/* musicserial.c */ /* Copyright 1990 Thomas E. Janzen All Rights Reserved */ /* ** FACILITY: ** ** AlgoRhythms music improviser on Commodore (TM) Amiga (TM) ** compiled with Lattice (TM) C 5.05 ** ** ABSTRACT: ** ** Algorhythms improvises music over the MIDI serial port. ** ** AUTHORS: Thomas E. Janzen ** ** CREATION DATE: 26-MAR-1990 ** ** MODIFICATION HISTORY: ** DATE NAME DESCRIPTION **-- */ #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 #include #include #include #include #define NOTEON (0x90) #define NOTEOFF (0x80) #define MIDIADDRESS (0x00) #define NOTEONCMD (0x90) #define NOTEOFFCMD (0x80) #define STARTFUNCT (0) #define STOPFUNCT (1) #define CLOCKFUNCT (2) #define CONTFUNCT (3) #define START 0xFA #define STOP 0xFC #define CONTINUE 0xFB #define TIMINGCLOCK 0xF8 extern struct Window *w; extern int fubar; int midi_addr=0; extern int quit; int Response; #include "AlgoRhythms.h" extern struct GfxBase *GfxBase; extern struct IntuitionBase *IntuitionBase; extern struct DOSBase *DOSBase; extern struct MathBase *MathBase; struct IOExtSer *IORser; struct MsgPort *port; extern struct IORequest *CreateExtIO(); /* Devices prototypes */ extern void DeletePort(struct MsgPort *); const char QuitStr[]="Quit"; const char SerErrStr[]="Serial Device Error"; const char PrtErrStr[]="Port Error"; const char IOErrStr[]="Create ExtIO Error"; const char DevErrStr[]="Serial Device Error"; const char PrmErrStr[]="Set Parm Error"; const char WrtErrStr[]="Serial.device write error"; struct IntuiText QuitTxt={2,1,JAM1,5,4,NULL,QuitStr,NULL}; void SendFunction(int Function); char playbuffer[4]; /* MIDI note message buffer */ 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) { struct IntuiText SerErrTxt={2,1,JAM1,5,15,NULL,SerErrStr,NULL}; 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<IOSer.io_Command=SDCMD_SETPARAMS; io->io_TermArray.TermArray0=ta0; io->io_TermArray.TermArray1=ta1; if((error=DoIO(io)) !=0) { quit=TRUE; fubar=TRUE; Response=AutoRequest(w,&SerErrTxt, &QuitTxt,&QuitTxt,0L,0L,300L,60L); } return(error); } void Open_MIDI_Port(void) { struct IntuiText PrtErrTxt={2,1,JAM1,5,15,NULL,PrtErrStr,NULL}; struct IntuiText IOErrTxt={2,1,JAM1,5,15,NULL,IOErrStr,NULL}; struct IntuiText DevErrTxt={2,1,JAM1,5,15,NULL,DevErrStr,NULL}; struct IntuiText PrmErrTxt={2,1,JAM1,5,15,NULL,PrmErrStr,NULL}; int error; unsigned long rbl = 512; /*read buffer length*/ unsigned long brk = 750000; /* length of break in usec, usu. 750000 */ unsigned long baud= 31250; /*baud rate 31.25k*/ unsigned long t0 = 0x51040303; /*termination characters*/ unsigned long t1 = 0x03030303; unsigned char rwl = 0x08; /*bits per read char */ unsigned char wwl = 0x08;/*bits per write char */ unsigned 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; Response=AutoRequest(w,&PrtErrTxt, &QuitTxt,&QuitTxt,0L,0L,300L,60L); } IORser= (struct IOExtSer *)CreateExtIO(port,sizeof(struct IOExtSer)); if(IORser == NULL) { quit=TRUE; fubar=TRUE; Response=AutoRequest(w,&IOErrTxt, &QuitTxt,&QuitTxt,0L,0L,300L,60L); } open: if ((error = OpenDevice(SERIALNAME,0,IORser,0))!=0) { quit=TRUE; fubar=TRUE; Response=AutoRequest(w,&DevErrTxt, &QuitTxt,&QuitTxt,0L,0L,300L,60L); } if((error=SetParams(IORser,rbl,rwl,wwl,brk,baud,sf,t0,t1))!=0){ fubar=TRUE; quit=TRUE; Response=AutoRequest(w,&PrmErrTxt, &QuitTxt,&QuitTxt,0L,0L,300L,60L); } /* The serial device is open, so go ahead and play music.*/ } int WriteSer(struct IOExtSer *io,char *data,int length) { int error; struct IntuiText WrtErrTxt={2,1,JAM1,5,15,NULL,WrtErrStr,NULL}; io->IOSer.io_Data=(APTR)data; io->IOSer.io_Length=length; io->IOSer.io_Command=CMD_WRITE; if((error=DoIO(io))!=0){ quit=TRUE; fubar=TRUE; Response=AutoRequest(w,&WrtErrTxt, &QuitTxt,&QuitTxt,0L,0L,300L,60L); } return(error); } void PlayNoteOn(const struct NoteEvent *PlayEvent) { extern int scale[]; /* Play a note; give note, dynamic*/ playbuffer[0]=(unsigned char)(PlayEvent->Channel | NOTEONCMD); playbuffer[1]=(unsigned char)(scale[PlayEvent->Pitch]); playbuffer[2]=(unsigned char)(PlayEvent->Dynamic); WriteSer(IORser,playbuffer,3); /* send it out MIDI */ } void PlayNoteOff(const struct NoteEvent *StopEvent) { /* MIDI note off routine ; input is number of note */ extern int scale[]; playbuffer[0]=(unsigned char)(StopEvent->Channel | NOTEOFFCMD); playbuffer[1]=(unsigned char)(StopEvent->CurPitch); /* note number */ playbuffer[2]=0; /* zero dynamic */ WriteSer(IORser,playbuffer,3); /*send it out MIDI */ } 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; } WriteSer(IORser,playbuffer,1); /* send it out MIDI */ } void StopAllNotes(const struct NoteEvent NotestoStop[]) { int i; for(i=0;i<16;i++) { PlayNoteOff(&NotestoStop[i]); if(fubar == TRUE) break; } SendFunction(STOPFUNCT); } void StopMIDI(void){ if (port) DeletePort(port); if (IORser) CloseDevice(IORser); }