'**************************************************************************** ' INITMIDI.BAS ' MPU-401 Hardware Handshaking routines based on routines by Michel Poirier, ' MIDICOM Montreal Fido 167/111, (514) 744-7354 ' Posted to comp.lang.basic.misc by Wayne Freno, wfreno@vcn.bc.ca June 7/97 ' Please send any bug fixes or any interesting algorithms to wfreno@vcn.bc.ca '**************************************************************************** ' First call InitMidi to initialize the MPU ' ReadData is used to read bytes from the computer's MIDI in. Use PRINT to ' see what they are. ' Play1note is there to demonstrate output. ' AllNotesOff should be called at the end, just before ResetMidi. ' DECLARE SUB ResetMidi (dataport, Rst, DRR) DECLARE SUB AllNotesOff (dataport) DECLARE SUB InitMidi (dataport, comport, Rst, DRR, Uart) DECLARE SUB ReadData (dataport, comport, DSR) DECLARE SUB Play1note (dataport, comport, DRR, ch0, notes, rests, velo, dur) dataport = &H330 ' Port where MIDI bytes are sent comport = &H331 ' Port where commands are sent DSR = &H80 ' Data Set Ready. Used for incoming bytes DRR = &H40 ' Data Read Ready. Used for outgoing bytes Uart = &H3F ' Used to put MPU into dumb mode Ack = &HFE ' Acknowledge byte sent to data port Rst = &HFF ' Reset MPU CALL InitMidi(dataport, comport, Rst, DRR, Uart) CLS ' sample output DO notes = INT(RND * 30) + 50 ' notes to send rests = INT(RND * 2) - 1 CALL Play1note(dataport, comport, DRR, 0, notes, rests, 99, 1600) LOOP WHILE INKEY$ = "" CALL AllNotesOff(dataport) CALL ResetMidi(dataport, Rst, DRR) END SUB AllNotesOff (dataport) FOR c = 0 TO 15 ' step through the MIDI channels WHILE (INP(comport) AND DRR = DRR) ' make sure its ok to send data purge = INP(dataport) WEND OUT dataport, &HB0 + c ' Control change status byte, plus channel purge = INP(dataport) ' Read Acknowledge WHILE (INP(comport) AND DRR = DRR) purge = INP(dataport) ' Read Acknowledge byte to clear the port WEND OUT dataport, 123 ' Controller #123 All Notes Off purge = INP(dataport) WHILE (INP(comport) AND DRR = DRR) purge = INP(dataport) WEND OUT dataport, 127 ' 0 to 63 = off, 64 to 127 = on purge = INP(dataport) NEXT c END SUB SUB InitMidi (dataport, comport, Rst, DRR, Uart) WHILE (INP(comport) AND DRR) = DRR purge = INP(dataport) WEND OUT comport, Rst ' Reset sent to command port purge = INP(dataport) WHILE (INP(comport) AND DRR) = DRR purge = INP(dataport) WEND OUT comport, Uart ' Put the MPU in Uart (dumb) mode purge = INP(dataport) END SUB SUB Play1note (dataport, comport, DRR, ch0, notes, rests, velo, dur) IF rests = 0 THEN velo = 0 ELSE velo = velo END IF WHILE (INP(comport) AND DRR) = DRR purge = INP(dataport) WEND OUT dataport, &H90 + ch0 ' NOTE ON channel 0 purge = INP(dataport) WHILE (INP(comport) AND DRR) = DRR purge = INP(dataport) WEND OUT dataport, notes ' notes to play purge = INP(dataport) WHILE (INP(comport) AND DRR) = DRR purge = INP(dataport) WEND OUT dataport, velo ' note velocity purge = INP(dataport) WHILE (INP(comport) AND DRR) = DRR purge = INP(dataport) WEND OUT dataport, &H90 + ch0 ' NOTE OFF Channel 0 purge = INP(dataport) WHILE (INP(comport) AND DRR) = DRR purge = INP(dataport) WEND OUT dataport, notes ' notes to turn off purge = INP(dataport) WHILE (INP(comport) AND DRR) = DRR purge = INP(dataport) WEND OUT dataport, 0 ' velocity 0, same as note off purge = INP(dataport) WHILE (INP(comport) AND DRR) = DRR purge = INP(dataport) WEND FOR d = 1 TO dur: NEXT d ' how long between notes END SUB SUB ReadData (dataport, comport, DSR) SHARED Byte WHILE (INP(comport) AND DSR) = DSR: WEND Byte = INP(dataport) END SUB SUB ResetMidi (dataport, Rst, DRR) ' put sub at end of program WHILE (INP(comport) AND DRR) = DRR purge = INP(dataport) WEND OUT comport, Rst ' Reset MPU to its default state purge = INP(dataport) END SUB