home *** CD-ROM | disk | FTP | other *** search
- /* MusicSerial.c
- Copyright (c) 1990,1991,1992 by Thomas E. Janzen
- All Rights Reserved
-
- THIS SOFTWARE IS FURNISHED FREE OF CHARGE FOR STUDY AND USE AND MAY
- BE COPIED ONLY FOR PERSONAL USE OR COMPLETELY AS OFFERED WITH NO
- CHANGES FOR FREE DISTRIBUTION. NO TITLE TO AND OWNERSHIP OF THE
- SOFTWARE IS HEREBY TRANSFERRED. THOMAS E. JANZEN ASSUMES NO
- RESPONSBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWARE.
-
- Thomas E. Janzen
- 58A School St. Apt. 2-L
- Hudson, MA 01749
- (508)562-1295
- */
- /*
- ** FACILITY:
- **
- ** AlgoRhythms music improviser on Commodore (TM) Amiga (TM)
- ** compiled with SAS/C V5.10b
- **
- ** ABSTRACT:
- **
- ** MusicSerial.c manages the serial device at the MIDI bit rate.
- ** All sends to MIDI occur here.
- **
- ** AUTHORS: Thomas E. Janzen
- **
- ** CREATION DATE: 26-MAR-1990
- **
- ** MODIFICATION HISTORY:
- ** DATE NAME DESCRIPTION
- ** 7 Dec 90 T. Janzen Used SendIO rather than DoIO - didn't up performance
- ** 4 Nov 91 T. Janzen incorporate MIDI running status; delete SendNoteOff
- ** 8 DEC 91 T. Janzen conform to SAS/C 5.10b remove extern from functs
- ** 4 Jan 92 TEJ last changes for 2.0
- **--
- */
-
- #include "exec/types.h"
- #include "exec/nodes.h"
- #include "exec/lists.h"
- #include "exec/ports.h"
- #include "exec/libraries.h"
- #include "exec/devices.h"
- #include "devices/serial.h"
- #include "exec/io.h"
- #include "intuition/intuition.h"
- #include <proto/dos.h>
- #include <proto/graphics.h>
- #include <proto/exec.h>
- #include <proto/mathffp.h>
- #include <proto/intuition.h>
- #ifdef CLI
- #include <stdio.h>
- #endif
- #include "Window.h"
- #include "AlgoRhythms.h"
- #include "MusicSerial.h"
- #include "Record.h"
-
- #define NOTEON (0x90) /* MIDI Spec note on flag */
- #define NOTEOFF (0x80) /* MIDI Spec note off flag */
- #define NOTEONCMD (0x90) /* MIDI Note on byte */
- #define NOTEOFFCMD (0x80) /* MIDI Note off byte */
- #define START (0xFA) /* MIDI Start play byte */
- #define STOP (0xFC) /* MIDI Stop play byte */
- #define CONTINUE (0xFB) /* MIDI Continue play byte */
- #define TIMINGCLOCK (0xF8) /* MIDI Timing clock byte */
-
- int Response;
-
- static struct IOExtSer *IORser; /* Amiga Devices structures for serial */
- static struct MsgPort *port;
-
- extern struct IORequest *CreateExtIO();
- extern void DeletePort(struct MsgPort *);
-
- /* strings for error alerts */
- static char QuitStr[] = "Quit",
- SerErrStr[] = "Serial Device Error",
- PrtErrStr[] = "Port Error",
- IOErrStr[] = "Create ExtIO Error",
- DevErrStr[] = "Serial Device Error",
- PrmErrStr[] = "Set Parm Error",
- WrtErrStr[] = "Serial.device write error";
- #ifndef CLI
- struct IntuiText QuitTxt = {2, 1, JAM1, 5, 4, &font_choice, QuitStr, NULL};
- #endif
- static char playbuffer[4]; /* MIDI note message buffer */
-
-
- #ifdef MEASURE
- extern unsigned int NotesTotalMeasure = 0;
- #endif
-
- int SetParams (struct IOExtSer *io, unsigned long rbuf_len,
- unsigned char rlen, unsigned char wlen, unsigned long brk,
- unsigned long baud, unsigned char sf,
- unsigned long ta0, unsigned long ta1)
- {
- /* set parameters of serial device */
- #ifndef CLI
- struct IntuiText SerErrTxt = {2, 1, JAM1, 5, 15, &font_choice,SerErrStr,
- NULL};
- #endif
- int error;
-
- io->io_ReadLen = rlen;
- io->io_BrkTime = brk; /*length of break timej (irrelevant)*/
- io->io_Baud = baud;
- io->io_WriteLen = wlen;
- io->io_StopBits = 0x01;
- io->io_RBufLen = rbuf_len;
- io->io_SerFlags = (1 << SERB_RAD_BOOGIE);
- io->IOSer.io_Command = SDCMD_SETPARAMS;
- io->io_TermArray.TermArray0 = ta0;
- io->io_TermArray.TermArray1 = ta1;
- if ((error = DoIO (io)) != 0)
- {
- quit = TRUE;
- fubar = TRUE;
- #ifdef CLI
- puts (SerErrStr);
- #else
- Response = AutoRequest ( w, &SerErrTxt, &QuitTxt, &QuitTxt,
- 0L, 0L, 300L, 60L);
- #endif
- }
- return error;
- }
-
- void Open_MIDI_Port (void)
- {
- #ifndef CLI
- struct IntuiText PrtErrTxt = {2, 1, JAM1, 5, 15,
- &font_choice, PrtErrStr, NULL},
- IOErrTxt = {2, 1, JAM1, 5, 15,
- &font_choice, IOErrStr, NULL},
- DevErrTxt = {2, 1, JAM1, 5, 15,
- &font_choice, DevErrStr, NULL},
- PrmErrTxt = {2, 1, JAM1, 5, 15,
- &font_choice, PrmErrStr, NULL};
- #endif
- int error;
- unsigned long rbl = 512, /*read buffer length*/
- brk = 750000,
- /* length of break in usec, usu. 750000 */
- baud = 31250, /* MIDI baud rate 31.25k bits/sec*/
- t0 = 0x51040303, /*termination characters*/
- t1 = 0x03030303;
- unsigned char rwl = 0x08, /*bits per read char */
- wwl = 0x08, /*bits per write char */
- sf = 0x00; /*serial flags cf D-124 in libs devices*/
- /* Try to get to the serial device. */
- /* page 396 of Libraries and Devices
- was the example*/
- port = CreatePort (SERIALNAME, 0);
- if (port == NULL)
- {
- quit = TRUE;
- fubar = TRUE;
- #ifdef CLI
- puts (PrtErrStr);
- #else
- Response = AutoRequest (w, &PrtErrTxt, &QuitTxt, &QuitTxt,
- 0L, 0L, 300L, 60L);
- #endif
- }
- IORser =
- (struct IOExtSer *)CreateExtIO(port, sizeof(struct IOExtSer));
- if (IORser == NULL)
- {
- quit = TRUE;
- fubar = TRUE;
- #ifdef CLI
- puts (IOErrStr);
- #else
- Response = AutoRequest (w, &IOErrTxt,
- &QuitTxt, &QuitTxt, 0L, 0L, 300L, 60L);
- #endif
- }
- open:
- if ((error = OpenDevice(SERIALNAME, 0, IORser, 0)) != 0)
- {
- quit = TRUE;
- fubar = TRUE;
- #ifdef CLI
- puts (DevErrStr);
- #else
- Response = AutoRequest (w, &DevErrTxt,
- &QuitTxt, &QuitTxt, 0L, 0L, 300L, 60L);
- #endif
- }
-
- if ((error
- = SetParams (IORser, rbl, rwl, wwl, brk, baud, sf, t0, t1)) != 0)
- {
- fubar = TRUE;
- quit = TRUE;
- #ifdef CLI
- puts (PrmErrStr);
- #else
- Response = AutoRequest (w, &PrmErrTxt,
- &QuitTxt, &QuitTxt, 0L, 0L, 300L, 60L);
- #endif
- }
- return;
- /* The serial device is open, so go ahead and play music.*/
- }
-
- int WriteSer (struct IOExtSer *io, char *data, int length)
- {
- int error;
- #ifndef CLI
- struct IntuiText WrtErrTxt = {2, 1, JAM1, 5, 15, &font_choice,
- WrtErrStr, NULL};
- #endif
- io->IOSer.io_Data = (APTR)data;
- io->IOSer.io_Length = length;
- io->IOSer.io_Command = CMD_WRITE;
-
- if((error = WaitIO(io)) != 0)
- {
- quit = TRUE; /* flag to get out of program */
- fubar = TRUE; /* flag to dump out of program with error*/
- #ifdef CLI
- puts (WrtErrStr);
- #else
- Response = AutoRequest (w, &WrtErrTxt,
- &QuitTxt, &QuitTxt, 0L, 0L, 300L, 60L);
- #endif
- }
- SendIO (io);
- return error;
- }
-
- void PlayNoteOn (const NOTEEVENT *PlayEvent)
- {
- static unsigned char Running_Status = 0X00;
-
- if (PlayEvent->Channel < 0)
- {
- Running_Status = 0;
- return;
- }
- playbuffer[0] = (unsigned char)(PlayEvent->Channel | NOTEONCMD);
- playbuffer[2] = (unsigned char)(PlayEvent->Dynamic);
-
- if (playbuffer[2])
- {
- playbuffer[1] = (unsigned char)(scale[PlayEvent->Pitch]);
- #ifdef MEASURE
- NotesTotalMeasure++;
- #endif
- }
- else
- {
- playbuffer[1] = (unsigned char)(PlayEvent->CurPitch);
- }
-
- if (playbuffer[0] == Running_Status)
- {
- WriteSer (IORser, &playbuffer[1], 2); /* send it out MIDI */
- }
- else
- {
- WriteSer (IORser, playbuffer, 3); /* send it out MIDI */
- Running_Status = playbuffer[0];
- }
- return;
- }
-
- void SendFunction (int Function)
- {
- playbuffer[1] = 0;
- switch (Function)
- {
- case STARTFUNCT:
- playbuffer[0] = (unsigned char)START;
- break;
- case STOPFUNCT:
- playbuffer[0] = (unsigned char)STOP;
- break;
- case CLOCKFUNCT:
- playbuffer[0] = (unsigned char)TIMINGCLOCK;
- break;
- case CONTFUNCT:
- playbuffer[0] = (unsigned char)CONTINUE;
- break;
- default:
- break;
- }
- WriteSer (IORser, playbuffer, 1); /* send it out MIDI */
- return;
- }
-
- void StopAllNotes (NOTEEVENT NotestoStop[])
- {
- int i;
-
- for (i = 0; i < 16; i++)
- {
- if (NotestoStop[i].Playing)
- {
- NotestoStop[i].Dynamic = 0;
- PlayNoteOn (&NotestoStop[i]);
- if (Recording)
- {
- Record_Note_Event (&NotestoStop[i]);
- }
- NotestoStop[i].Playing = 0;
- Delay (1);
- if (fubar == TRUE)
- {
- break;
- }
- }
- }
- SendFunction (STOPFUNCT);
- return;
- }
-
- void StopMIDI (void)
- {
- /* close up shop */
- if (port) DeletePort (port);
- if (IORser) CloseDevice (IORser);
- return;
- }
-
-