MIDI message reassemby; we can play notes over rtpMIDI again!

md-perf
probonopd 1 week ago
parent 69b2e7d569
commit a8b6c0e12f
  1. 4
      src/mididevice.cpp
  2. 19
      src/serialmididevice.cpp
  3. 67
      src/udpmididevice.cpp
  4. 4
      src/udpmididevice.h

@ -238,12 +238,8 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
// Handle MiniDexed performance SysEx messages // Handle MiniDexed performance SysEx messages
if (pMessage[0] == MIDI_SYSTEM_EXCLUSIVE_BEGIN && pMessage[1] == 0x7D ) { if (pMessage[0] == MIDI_SYSTEM_EXCLUSIVE_BEGIN && pMessage[1] == 0x7D ) {
LOGNOTE("MiniDexed SysEx handler entered, nLength=%u", nLength);
// Update: Pass m_pSynthesizer to handle_performance_sysex for synth/GUI update
handle_performance_sysex(pMessage, this, m_pSynthesizer, nCable); handle_performance_sysex(pMessage, this, m_pSynthesizer, nCable);
return; return;
} else {
LOGNOTE("MiniDexed SysEx handler NOT entered, nLength=%u", nLength);
} }
// Master Volume is set using a MIDI SysEx message as follows: // Master Volume is set using a MIDI SysEx message as follows:

@ -85,15 +85,22 @@ void CSerialMIDIDevice::Process (void)
m_SysExLen = 0; m_SysExLen = 0;
} }
if (m_SysExActive) { if (m_SysExActive) {
if (m_SysExLen < MAX_MIDI_MESSAGE) { if ((uchData & 0x80) && uchData != 0xF0 && uchData != 0xF7) {
m_SysExBuffer[m_SysExLen++] = uchData; // Abort SysEx on new status byte (except 0xF0/0xF7)
}
if (uchData == 0xF7 || m_SysExLen >= MAX_MIDI_MESSAGE) {
MIDIMessageHandler(m_SysExBuffer, m_SysExLen, 0);
m_SysExActive = false; m_SysExActive = false;
m_SysExLen = 0; m_SysExLen = 0;
// Process this byte as normal MIDI below
} else {
if (m_SysExLen < MAX_MIDI_MESSAGE) {
m_SysExBuffer[m_SysExLen++] = uchData;
}
if (uchData == 0xF7 || m_SysExLen >= MAX_MIDI_MESSAGE) {
MIDIMessageHandler(m_SysExBuffer, m_SysExLen, 0);
m_SysExActive = false;
m_SysExLen = 0;
}
if (m_SysExActive) continue;
} }
continue;
} }
// System Real Time messages may appear anywhere in the byte stream, so handle them specially // System Real Time messages may appear anywhere in the byte stream, so handle them specially

@ -76,6 +76,35 @@ boolean CUDPMIDIDevice::Initialize (void)
return true; return true;
} }
void CUDPMIDIDevice::UdpMidiReassembly(uint8_t byte, unsigned cable) {
// System Real Time messages (single byte)
if (byte == 0xF8 || byte == 0xFA || byte == 0xFB || byte == 0xFC || byte == 0xFE || byte == 0xFF) {
MIDIMessageHandler(&byte, 1, cable);
return;
}
// Status byte
if ((byte & 0x80) == 0x80 && (byte & 0xF0) != 0xF0) {
m_udpMidiMsg[0] = byte;
m_udpMidiState = 1;
return;
}
// Data byte
if (m_udpMidiState > 0) {
m_udpMidiMsg[m_udpMidiState++] = byte;
if ((m_udpMidiMsg[0] & 0xE0) == 0xC0 || (m_udpMidiMsg[0] & 0xF0) == 0xD0) {
// Program Change or Channel Pressure (2 bytes)
if (m_udpMidiState == 2) {
MIDIMessageHandler(m_udpMidiMsg, 2, cable);
m_udpMidiState = 0;
}
} else if (m_udpMidiState == 3) {
// All other channel messages (3 bytes)
MIDIMessageHandler(m_udpMidiMsg, 3, cable);
m_udpMidiState = 0;
}
}
}
// Methods to handle MIDI events // Methods to handle MIDI events
void CUDPMIDIDevice::OnAppleMIDIDataReceived(const u8* pData, size_t nSize) void CUDPMIDIDevice::OnAppleMIDIDataReceived(const u8* pData, size_t nSize)
@ -87,17 +116,22 @@ void CUDPMIDIDevice::OnAppleMIDIDataReceived(const u8* pData, size_t nSize)
m_SysExLen = 0; m_SysExLen = 0;
} }
if (m_SysExActive) { if (m_SysExActive) {
if (m_SysExLen < MAX_MIDI_MESSAGE) { if ((byte & 0x80) && byte != 0xF0 && byte != 0xF7) {
m_SysExBuffer[m_SysExLen++] = byte;
}
if (byte == 0xF7 || m_SysExLen >= MAX_MIDI_MESSAGE) {
MIDIMessageHandler(m_SysExBuffer, m_SysExLen, VIRTUALCABLE);
m_SysExActive = false; m_SysExActive = false;
m_SysExLen = 0; m_SysExLen = 0;
} else {
if (m_SysExLen < MAX_MIDI_MESSAGE) {
m_SysExBuffer[m_SysExLen++] = byte;
}
if (byte == 0xF7 || m_SysExLen >= MAX_MIDI_MESSAGE) {
MIDIMessageHandler(m_SysExBuffer, m_SysExLen, VIRTUALCABLE);
m_SysExActive = false;
m_SysExLen = 0;
}
if (m_SysExActive) continue;
} }
continue;
} }
MIDIMessageHandler(&byte, 1, VIRTUALCABLE); UdpMidiReassembly(byte, VIRTUALCABLE);
} }
} }
@ -120,17 +154,22 @@ void CUDPMIDIDevice::OnUDPMIDIDataReceived(const u8* pData, size_t nSize)
m_SysExLen = 0; m_SysExLen = 0;
} }
if (m_SysExActive) { if (m_SysExActive) {
if (m_SysExLen < MAX_MIDI_MESSAGE) { if ((byte & 0x80) && byte != 0xF0 && byte != 0xF7) {
m_SysExBuffer[m_SysExLen++] = byte;
}
if (byte == 0xF7 || m_SysExLen >= MAX_MIDI_MESSAGE) {
MIDIMessageHandler(m_SysExBuffer, m_SysExLen, VIRTUALCABLE);
m_SysExActive = false; m_SysExActive = false;
m_SysExLen = 0; m_SysExLen = 0;
} else {
if (m_SysExLen < MAX_MIDI_MESSAGE) {
m_SysExBuffer[m_SysExLen++] = byte;
}
if (byte == 0xF7 || m_SysExLen >= MAX_MIDI_MESSAGE) {
MIDIMessageHandler(m_SysExBuffer, m_SysExLen, VIRTUALCABLE);
m_SysExActive = false;
m_SysExLen = 0;
}
if (m_SysExActive) continue;
} }
continue;
} }
MIDIMessageHandler(&byte, 1, VIRTUALCABLE); UdpMidiReassembly(byte, VIRTUALCABLE);
} }
} }

@ -62,6 +62,10 @@ private:
uint8_t m_SysExBuffer[MAX_MIDI_MESSAGE]; uint8_t m_SysExBuffer[MAX_MIDI_MESSAGE];
size_t m_SysExLen = 0; size_t m_SysExLen = 0;
bool m_SysExActive = false; bool m_SysExActive = false;
void UdpMidiReassembly(uint8_t byte, unsigned cable);
uint8_t m_udpMidiMsg[4] = {0};
uint8_t m_udpMidiState = 0;
}; };
#endif #endif

Loading…
Cancel
Save