diff options
author | R. Belmont <rb6502@users.noreply.github.com> | 2013-02-03 21:26:37 +0000 |
---|---|---|
committer | R. Belmont <rb6502@users.noreply.github.com> | 2013-02-03 21:26:37 +0000 |
commit | 70a9d274aca683ae6a9a5522ac7162f931c76453 (patch) | |
tree | 28fa8c16db389ad17ad5f20731e6288b0e595227 /src/osd/portmedia/pmmidi.c | |
parent | 7731ec7923b1e365ccfc7c72b98aca4678757909 (diff) |
MIDI: preliminary SysEx reception support [R. Belmont]
Diffstat (limited to 'src/osd/portmedia/pmmidi.c')
-rw-r--r-- | src/osd/portmedia/pmmidi.c | 113 |
1 files changed, 78 insertions, 35 deletions
diff --git a/src/osd/portmedia/pmmidi.c b/src/osd/portmedia/pmmidi.c index 4321652dfaa..222941509d5 100644 --- a/src/osd/portmedia/pmmidi.c +++ b/src/osd/portmedia/pmmidi.c @@ -24,6 +24,7 @@ struct osd_midi_device UINT8 xmit_in[4]; // Pm_Messages mean we can at most have 3 residue bytes int xmit_cnt; UINT8 last_status; + bool rx_sysex; }; void osd_list_midi_devices(void) @@ -192,46 +193,88 @@ int osd_read_midi_channel(osd_midi_device *dev, UINT8 *pOut) for (int msg = 0; msg < msgsRead; msg++) { UINT8 status = Pm_MessageStatus(dev->rx_evBuf[msg].message); - switch ((status>>4) & 0xf) - { - case 0xc: // 2-byte messages - case 0xd: - *pOut++ = status; - *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); - bytesOut += 2; - break; - case 0xf: // system common - switch (status & 0xf) + if (dev->rx_sysex) + { + if (status & 0x80) // sys real-time imposing on us? + { + if ((status == 0xf2) || (status == 0xf3)) { - case 0: // System Exclusive - printf("No SEx please!\n"); - break; - - case 7: // End of System Exclusive - *pOut++ = status; - bytesOut += 1; - break; - - case 2: // song pos - case 3: // song select - *pOut++ = status; - *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); - *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message); - bytesOut += 3; - break; - - default: // all other defined Fx messages are 1 byte + *pOut++ = status; + *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); + *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message); + bytesOut += 3; + } + else + { + *pOut++ = status; + bytesOut++; + } + } + else // shift out the sysex bytes + { + for (int i = 0; i < 4; i++) + { + UINT8 byte = dev->rx_evBuf[msg].message & 0xff; + *pOut++ = byte; + bytesOut++; + if (byte == MIDI_EOX) + { + dev->rx_sysex = false; break; + } + dev->rx_evBuf[msg].message >>= 8; } - break; + } + } + else + { + switch ((status>>4) & 0xf) + { + case 0xc: // 2-byte messages + case 0xd: + *pOut++ = status; + *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); + bytesOut += 2; + break; - default: - *pOut++ = status; - *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); - *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message); - bytesOut += 3; - break; + case 0xf: // system common + switch (status & 0xf) + { + case 0: // System Exclusive + *pOut++ = status; // this should be OK: the shortest legal sysex is F0 tt dd F7, I believe + *pOut++ = (dev->rx_evBuf[msg].message>>8) & 0xff; + *pOut++ = (dev->rx_evBuf[msg].message>>16) & 0xff; + *pOut++ = (dev->rx_evBuf[msg].message>>24) & 0xff; + bytesOut += 4; + dev->rx_sysex = true; + break; + + case 7: // End of System Exclusive + *pOut++ = status; + bytesOut += 1; + break; + + case 2: // song pos + case 3: // song select + *pOut++ = status; + *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); + *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message); + bytesOut += 3; + break; + + default: // all other defined Fx messages are 1 byte + break; + } + break; + + default: + *pOut++ = status; + *pOut++ = Pm_MessageData1(dev->rx_evBuf[msg].message); + *pOut++ = Pm_MessageData2(dev->rx_evBuf[msg].message); + bytesOut += 3; + break; + } } } |