/* Copyright (C) 1986 by M. J. Shannon, Jr. ** Permission to distribute for non-commercial uses granted as long as this ** notice is retained. Violators will be prosecuted. */ #include "mpu.h" /* midi_lengths[]: ** lengths of the MIDI voice messages after reading the 2nd byte of the ** message. */ static short midi_lengths[8] = { 1, /* 80: Note Off */ 1, /* 90: Note On */ 1, /* A0: Note After Touch */ 1, /* B0: Control Change */ 0, /* C0: Program Change */ 0, /* D0: Channel After Touch */ 1, /* E0: Pitch Wheel */ 0 /* F0: "Can't Happen" */ }; /* mpu_read(char *): ** read a response from a midi device. The response is stored in the ** passed character buffer, and the length of the response is returned. ** The buffer must be large enough to hold the response. */ int mpu_read(bp) register unsigned char *bp; { register int length = 0; register unsigned char data; if (mpu_dsr() && mpu_dsr()) /* timed out waiting for a response? */ return (length); bp[length++] = data = mpu_dget(); /* store the input */ if (data < 0xF0) /* time followed by midi data */ { static unsigned char midi_rs = 0; /* last rec'd running stat */ static int mmlen; /* and # of following bytes */ register int i; unsigned char vm; vm = mpu_dget(); /* get midi voice message */ if (vm < 0x80) /* midi running status? */ bp[length++] = midi_rs; /* yes, store the old status */ bp[length++] = vm; /* store the data */ if (vm <= 0xEF) /* midi, not MPU mark */ { if (vm >= 0x80) /* new running status? */ { midi_rs = vm; /* yes, set the new status */ mmlen = midi_lengths[(midi_rs >> 4) & 0x07]; bp[length++] = mpu_dget(); /* get next byte */ } for (i = 0; i < mmlen; ++i) bp[length++] = mpu_dget(); } } else /* These are all MPU msgs */ switch (data) { case 0xF0: /* track 1 request */ case 0xF1: /* track 2 request */ case 0xF2: /* track 3 request */ case 0xF3: /* track 4 request */ case 0xF4: /* track 5 request */ case 0xF5: /* track 6 request */ case 0xF6: /* track 7 request */ case 0xF7: /* track 8 request */ case 0xF8: /* timing overflow */ case 0xF9: /* conductor request */ case 0xFC: /* all end */ case 0xFD: /* clock to host */ break; case 0xFF: /* midi system message */ { data = mpu_dget(); bp[length++] = data; switch (data) { case 0xF0: /* system exclusive */ do { data = mpu_dget(); bp[length++] = data; } while (data != MIDI_EOX); break; case 0xF2: /* song position pointer */ bp[length++] = mpu_dget(); /* FALL THRU */ case 0xF3: /* song select */ bp[length++] = mpu_dget(); /* FALL THRU */ case 0xF6: /* tune request */ case 0xFA: /* start */ case 0xFB: /* stop */ case 0xFC: /* continue */ break; default: printf("Bogus sys msg: %.2x\n", data); } break; } case CMD_ACK: /* we're confused.... */ printf("Spurious ACK!\n"); break; default: /* we're REALLY confused.... */ printf("Bogus message: %.2x\n", data); break; } return (length); }