diff --git a/src/config.cpp b/src/config.cpp index 1143476..9ad98f0 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -70,6 +70,7 @@ void CConfig::Load (void) m_bMIDIRXProgramChange = m_Properties.GetNumber ("MIDIRXProgramChange", 1) != 0; m_bIgnoreAllNotesOff = m_Properties.GetNumber ("IgnoreAllNotesOff", 0) != 0; + m_bMIDIAutoVoiceDumpOnPC = m_Properties.GetNumber ("MIDIAutoVoiceDumpOnPC", 1) != 0; m_bLCDEnabled = m_Properties.GetNumber ("LCDEnabled", 0) != 0; m_nLCDPinEnable = m_Properties.GetNumber ("LCDPinEnable", 4); @@ -171,6 +172,11 @@ bool CConfig::GetIgnoreAllNotesOff (void) const return m_bIgnoreAllNotesOff; } +bool CConfig::GetMIDIAutoVoiceDumpOnPC (void) const +{ + return m_bMIDIAutoVoiceDumpOnPC; +} + bool CConfig::GetLCDEnabled (void) const { return m_bLCDEnabled; diff --git a/src/config.h b/src/config.h index be75100..2465507 100644 --- a/src/config.h +++ b/src/config.h @@ -76,6 +76,7 @@ public: const char *GetMIDIThruOut (void) const; // "" if not specified bool GetMIDIRXProgramChange (void) const; // true if not specified bool GetIgnoreAllNotesOff (void) const; + bool GetMIDIAutoVoiceDumpOnPC (void) const; // true if not specified // HD44780 LCD // GPIO pin numbers are chip numbers, not header positions @@ -153,6 +154,7 @@ private: std::string m_MIDIThruOut; bool m_bMIDIRXProgramChange; bool m_bIgnoreAllNotesOff; + bool m_bMIDIAutoVoiceDumpOnPC; bool m_bLCDEnabled; unsigned m_nLCDPinEnable; diff --git a/src/mididevice.cpp b/src/mididevice.cpp index 898c187..9b3deac 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -203,7 +203,7 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign if (ucStatus == MIDI_SYSTEM_EXCLUSIVE_BEGIN) { // MIDI SYSEX per MIDI channel - uint8_t ucSysExChannel = (pMessage[2] & 0x07); + uint8_t ucSysExChannel = (pMessage[2] & 0x0F); if (m_ChannelMap[nTG] == ucSysExChannel || m_ChannelMap[nTG] == OmniMode) { LOGNOTE("MIDI-SYSEX: channel: %u, len: %u, TG: %u",m_ChannelMap[nTG],nLength,nTG); diff --git a/src/minidexed.cpp b/src/minidexed.cpp index 328eab4..8df8d6d 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -377,6 +377,8 @@ void CMiniDexed::BankSelectLSB (unsigned nBankLSB, unsigned nTG) void CMiniDexed::ProgramChange (unsigned nProgram, unsigned nTG) { + assert (m_pConfig); + nProgram=constrain((int)nProgram,0,31); assert (nTG < CConfig::ToneGenerators); @@ -387,7 +389,16 @@ void CMiniDexed::ProgramChange (unsigned nProgram, unsigned nTG) assert (m_pTG[nTG]); m_pTG[nTG]->loadVoiceParameters (Buffer); - m_SerialMIDI.SendSystemExclusiveVoice(nProgram,0,nTG); + + if (m_pConfig->GetMIDIAutoVoiceDumpOnPC()) + { + // Only do the voice dump back out over MIDI if we have a specific + // MIDI channel configured for this TG + if (m_nMIDIChannel[nTG] < CMIDIDevice::Channels) + { + m_SerialMIDI.SendSystemExclusiveVoice(nProgram,0,nTG); + } + } m_UI.ParameterChanged (); } @@ -474,6 +485,8 @@ void CMiniDexed::SetResonance (int nResonance, unsigned nTG) void CMiniDexed::SetMIDIChannel (uint8_t uchChannel, unsigned nTG) { assert (nTG < CConfig::ToneGenerators); + assert (uchChannel < CMIDIDevice::ChannelUnknown); + m_nMIDIChannel[nTG] = uchChannel; for (unsigned i = 0; i < CConfig::MaxUSBMIDIDevices; i++) @@ -1321,7 +1334,7 @@ void CMiniDexed::getSysExVoiceDump(uint8_t* dest, uint8_t nTG) dest[0] = 0xF0; // SysEx start dest[1] = 0x43; // ID=Yamaha - dest[2] = GetTGParameter(TGParameterMIDIChannel, nTG); // Sub-status and MIDI channel + dest[2] = 0x00 | m_nMIDIChannel[nTG]; // 0x0c Sub-status 0 and MIDI channel dest[3] = 0x00; // Format number (0=1 voice) dest[4] = 0x01; // Byte count MSB dest[5] = 0x1B; // Byte count LSB diff --git a/src/minidexed.ini b/src/minidexed.ini index 7d73416..f2bfbf6 100644 --- a/src/minidexed.ini +++ b/src/minidexed.ini @@ -16,6 +16,7 @@ MIDIBaudRate=31250 #MIDIThru=umidi1,ttyS1 MIDIRXProgramChange=1 IgnoreAllNotesOff=0 +MIDIAutoVoiceDumpOnPC=1 # HD44780 LCD LCDEnabled=1