From 0be1d998bc16497df15f3b6f688159d104048444 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Tue, 17 May 2022 17:02:53 +0200 Subject: [PATCH 01/14] Fix for using the right MIDI channel for SYSEX. Fix for SYSEX MIDI dump output. --- src/mididevice.cpp | 11 +++++------ src/serialmididevice.cpp | 9 +++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/mididevice.cpp b/src/mididevice.cpp index 5daacc1..ce68339 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -115,15 +115,14 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign { case MIDI_SYSTEM_EXCLUSIVE_BEGIN: printf("SysEx data length: [%d]\n",uint16_t(nLength)); - printf("SysEx data:\n"); + printf("SysEx data:"); for (uint16_t i = 0; i < nLength; i++) { if((i % 8) == 0) - printf("%04d:",i); + printf("\n%04d:",i); printf(" 0x%02x",pMessage[i]); - if((i % 8) == 0) - printf("\n"); } + printf("\n"); break; default: printf("Unhandled MIDI event type %0x02x\n",pMessage[0]); @@ -166,7 +165,7 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++) { // MIDI SYSEX per MIDI channel - if (ucStatus == MIDI_SYSTEM_EXCLUSIVE_BEGIN && m_ChannelMap[nTG] == pMessage[2] & 0x07) + if (ucStatus == MIDI_SYSTEM_EXCLUSIVE_BEGIN && (m_ChannelMap[nTG] == ((pMessage[2] & 0x07) + 1) || (m_ChannelMap[nTG] > 16 ))) HandleSystemExclusive(pMessage, nLength, nTG); else { @@ -415,7 +414,7 @@ void CMIDIDevice::HandleSystemExclusive(const uint8_t* pMessage, const size_t nL LOGNOTE("Currently code for storing a bulk bank upload is missing!"); break; default: - LOGDBG("SysEx voice parameter change: %d value: %d",pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5]); + LOGDBG("SysEx voice parameter change: Parameter %d value: %d",pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5]); m_pSynthesizer->setVoiceDataElement(pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5],nTG); break; } diff --git a/src/serialmididevice.cpp b/src/serialmididevice.cpp index ec819d0..157c6be 100644 --- a/src/serialmididevice.cpp +++ b/src/serialmididevice.cpp @@ -64,17 +64,14 @@ void CSerialMIDIDevice::Process (void) if (m_pConfig->GetMIDIDumpEnabled ()) { - printf("Incoming MIDI data:\n"); + printf("Incoming MIDI data:"); for (uint16_t i = 0; i < nResult; i++) { if((i % 8) == 0) - printf("%04d:",i); + printf("\n%04d:",i); printf(" 0x%02x",Buffer[i]); - if((i > 1 ) && (i % 8) == 0) - printf("\n"); } - if((nResult % 8) != 0) - printf("\n"); + printf("\n"); } // Process MIDI messages From 8a143af07849e26bf2c76cf9a57134b64e57828d Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Tue, 17 May 2022 18:11:45 +0200 Subject: [PATCH 02/14] Small fixes for recognizing MIDI channel in SYSEX. Disabled printing of MIDI data in incoming serial data. Added some mor debug output. --- src/mididevice.cpp | 14 ++++++++++---- src/serialmididevice.cpp | 8 +++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/mididevice.cpp b/src/mididevice.cpp index ce68339..de22a71 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -114,8 +114,7 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign switch(pMessage[0]) { case MIDI_SYSTEM_EXCLUSIVE_BEGIN: - printf("SysEx data length: [%d]\n",uint16_t(nLength)); - printf("SysEx data:"); + printf("MIDI%u: SysEx data length: [%d]:",nCable, uint16_t(nLength)); for (uint16_t i = 0; i < nLength; i++) { if((i % 8) == 0) @@ -125,7 +124,7 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign printf("\n"); break; default: - printf("Unhandled MIDI event type %0x02x\n",pMessage[0]); + printf("MIDI%u: Unhandled MIDI event type %0x02x\n",nCable,pMessage[0]); } break; } @@ -165,8 +164,15 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++) { // MIDI SYSEX per MIDI channel - if (ucStatus == MIDI_SYSTEM_EXCLUSIVE_BEGIN && (m_ChannelMap[nTG] == ((pMessage[2] & 0x07) + 1) || (m_ChannelMap[nTG] > 16 ))) + uint8_t ucSysExChannel = (pMessage[2] & 0x07) + 1; + if (ucStatus == MIDI_SYSTEM_EXCLUSIVE_BEGIN && + (ucSysExChannel == m_ChannelMap[nTG] || + ucSysExChannel == OmniMode) + ) + { + LOGNOTE("MIDI-SYSEX: channel: %u, len: %u, TG: %u",m_ChannelMap[nTG],nTG); HandleSystemExclusive(pMessage, nLength, nTG); + } else { if ( m_ChannelMap[nTG] == ucChannel diff --git a/src/serialmididevice.cpp b/src/serialmididevice.cpp index 157c6be..fd25a28 100644 --- a/src/serialmididevice.cpp +++ b/src/serialmididevice.cpp @@ -20,10 +20,14 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . // + +#include #include #include "serialmididevice.h" #include +LOGMODULE("serialmididevice"); + CSerialMIDIDevice::CSerialMIDIDevice (CMiniDexed *pSynthesizer, CInterruptSystem *pInterrupt, CConfig *pConfig) : CMIDIDevice (pSynthesizer, pConfig), @@ -58,10 +62,11 @@ void CSerialMIDIDevice::Process (void) if (nResult <= 0) { if(nResult!=0) - printf("Serial-Read: %d\n",nResult); + LOGERR("Serial.Read() error: %d\n",nResult); return; } + /* if (m_pConfig->GetMIDIDumpEnabled ()) { printf("Incoming MIDI data:"); @@ -73,6 +78,7 @@ void CSerialMIDIDevice::Process (void) } printf("\n"); } + */ // Process MIDI messages // See: https://www.midi.org/specifications/item/table-1-summary-of-midi-message From 7e4e650649619db314f522c659c0d57b57e6fb43 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Fri, 20 May 2022 08:49:19 +0200 Subject: [PATCH 03/14] Reenabled showing incomfing MIDI data when MIDI-DUmp is enabled. Fix for using MIDI channel for SYSEX. --- src/mididevice.cpp | 4 ++-- src/serialmididevice.cpp | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mididevice.cpp b/src/mididevice.cpp index de22a71..c7ec76b 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -166,8 +166,8 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign // MIDI SYSEX per MIDI channel uint8_t ucSysExChannel = (pMessage[2] & 0x07) + 1; if (ucStatus == MIDI_SYSTEM_EXCLUSIVE_BEGIN && - (ucSysExChannel == m_ChannelMap[nTG] || - ucSysExChannel == OmniMode) + (m_ChannelMap[nTG] == ucSysExChannel || + m_ChannelMap[nTG] == OmniMode) ) { LOGNOTE("MIDI-SYSEX: channel: %u, len: %u, TG: %u",m_ChannelMap[nTG],nTG); diff --git a/src/serialmididevice.cpp b/src/serialmididevice.cpp index fd25a28..c3f2788 100644 --- a/src/serialmididevice.cpp +++ b/src/serialmididevice.cpp @@ -66,7 +66,6 @@ void CSerialMIDIDevice::Process (void) return; } - /* if (m_pConfig->GetMIDIDumpEnabled ()) { printf("Incoming MIDI data:"); @@ -78,7 +77,6 @@ void CSerialMIDIDevice::Process (void) } printf("\n"); } - */ // Process MIDI messages // See: https://www.midi.org/specifications/item/table-1-summary-of-midi-message From 2cb0631efc548064502844949ab30502ca221c21 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Sat, 21 May 2022 11:25:59 +0200 Subject: [PATCH 04/14] Several fixes for SYSEX handling. --- src/mididevice.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mididevice.cpp b/src/mididevice.cpp index c7ec76b..6a1a400 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -163,15 +163,15 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign { for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++) { - // MIDI SYSEX per MIDI channel - uint8_t ucSysExChannel = (pMessage[2] & 0x07) + 1; - if (ucStatus == MIDI_SYSTEM_EXCLUSIVE_BEGIN && - (m_ChannelMap[nTG] == ucSysExChannel || - m_ChannelMap[nTG] == OmniMode) - ) + if (ucStatus == MIDI_SYSTEM_EXCLUSIVE_BEGIN) { - LOGNOTE("MIDI-SYSEX: channel: %u, len: %u, TG: %u",m_ChannelMap[nTG],nTG); - HandleSystemExclusive(pMessage, nLength, nTG); + // MIDI SYSEX per MIDI channel + uint8_t ucSysExChannel = (pMessage[2] & 0x07); + if (m_ChannelMap[nTG] == ucSysExChannel || m_ChannelMap[nTG] == OmniMode) + { + LOGNOTE("MIDI-SYSEX: channel: %u, len: %u, TG: %u",m_ChannelMap[nTG],nLength,nTG); + HandleSystemExclusive(pMessage, nLength, nTG); + } } else { From 55e90c6aa1903e46102bcd66318eca4f5b2fcb5e Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Sat, 21 May 2022 17:41:20 +0200 Subject: [PATCH 05/14] Code for sending a voice dump via MIDI started. --- src/mididevice.cpp | 73 +++++++++++++++++++++++++++++++--------- src/mididevice.h | 6 ++-- src/minidexed.cpp | 28 +++++++++++++++ src/minidexed.h | 1 + src/serialmididevice.cpp | 1 + 5 files changed, 90 insertions(+), 19 deletions(-) diff --git a/src/mididevice.cpp b/src/mididevice.cpp index 6a1a400..935570d 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -117,7 +117,7 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign printf("MIDI%u: SysEx data length: [%d]:",nCable, uint16_t(nLength)); for (uint16_t i = 0; i < nLength; i++) { - if((i % 8) == 0) + if((i % 16) == 0) printf("\n%04d:",i); printf(" 0x%02x",pMessage[i]); } @@ -130,6 +130,21 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign } } + // Only for debugging: +/* + if(pMessage[0]==MIDI_SYSTEM_EXCLUSIVE_BEGIN) + { + printf("MIDI%u: SysEx data length: [%d]:",nCable, uint16_t(nLength)); + for (uint16_t i = 0; i < nLength; i++) + { + if((i % 16) == 0) + printf("\n%04d:",i); + printf(" 0x%02x",pMessage[i]); + } + printf("\n"); + } +*/ + // Handle MIDI Thru if (m_DeviceName.compare (m_pConfig->GetMIDIThruIn ()) == 0) { @@ -170,7 +185,7 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign if (m_ChannelMap[nTG] == ucSysExChannel || m_ChannelMap[nTG] == OmniMode) { LOGNOTE("MIDI-SYSEX: channel: %u, len: %u, TG: %u",m_ChannelMap[nTG],nLength,nTG); - HandleSystemExclusive(pMessage, nLength, nTG); + HandleSystemExclusive(pMessage, nLength, nCable, nTG); } } else @@ -311,7 +326,7 @@ void CMIDIDevice::AddDevice (const char *pDeviceName) s_DeviceMap.insert (std::pair (pDeviceName, this)); } -void CMIDIDevice::HandleSystemExclusive(const uint8_t* pMessage, const size_t nLength, const uint8_t nTG) +void CMIDIDevice::HandleSystemExclusive(const uint8_t* pMessage, const size_t nLength, const unsigned nCable, const uint8_t nTG) { int16_t sysex_return; @@ -324,33 +339,33 @@ void CMIDIDevice::HandleSystemExclusive(const uint8_t* pMessage, const size_t nL LOGERR("SysEx end status byte not detected."); break; case -2: - LOGERR("E: SysEx vendor not Yamaha."); + LOGERR("SysEx vendor not Yamaha."); break; case -3: - LOGERR("E: Unknown SysEx parameter change."); + LOGERR("Unknown SysEx parameter change."); break; case -4: - LOGERR(" Unknown SysEx voice or function."); + LOGERR("Unknown SysEx voice or function."); break; case -5: - LOGERR("E: Not a SysEx voice bulk upload."); + LOGERR("Not a SysEx voice bulk upload."); break; case -6: - LOGERR("E: Wrong length for SysEx voice bulk upload (not 155)."); + LOGERR("Wrong length for SysEx voice bulk upload (not 155)."); break; case -7: - LOGERR("E: Checksum error for one voice."); + LOGERR("Checksum error for one voice."); break; case -8: - LOGERR("E: Not a SysEx bank bulk upload."); + LOGERR("Not a SysEx bank bulk upload."); break; case -9: - LOGERR("E: Wrong length for SysEx bank bulk upload (not 4096)."); + LOGERR("Wrong length for SysEx bank bulk upload (not 4096)."); case -10: - LOGERR("E: Checksum error for bank."); + LOGERR("Checksum error for bank."); break; case -11: - LOGERR("E: Unknown SysEx message."); + LOGERR("Unknown SysEx message."); break; case 64: LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); @@ -420,9 +435,37 @@ void CMIDIDevice::HandleSystemExclusive(const uint8_t* pMessage, const size_t nL LOGNOTE("Currently code for storing a bulk bank upload is missing!"); break; default: - LOGDBG("SysEx voice parameter change: Parameter %d value: %d",pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5]); - m_pSynthesizer->setVoiceDataElement(pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5],nTG); + if(sysex_return >= 300 && sysex_return < 500) + { + LOGDBG("SysEx voice parameter change: Parameter %d value: %d",pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5]); + m_pSynthesizer->setVoiceDataElement(pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5],nTG); + } + else if(sysex_return >= 500 && sysex_return < 600) + { + LOGDBG("SysEx send voice %u request",sysex_return-500); + SendSystemExclusiveVoice(sysex_return-500, nCable, nTG); + } break; } } +void CMIDIDevice::SendSystemExclusiveVoice(uint8_t nVoice, const unsigned nCable, uint8_t nTG) +{ + uint8_t voicedump[163]; + + LOGDBG("Sending SysEx voice %u ",nVoice); + + // Get voice sysex dump from TG + m_pSynthesizer->getSysExVoiceDump(voicedump, nTG); + + if (m_DeviceName.compare (m_pConfig->GetMIDIThruIn ()) == 0) + { + TDeviceMap::const_iterator Iterator; + + Iterator = s_DeviceMap.find (m_pConfig->GetMIDIThruOut ()); + if (Iterator != s_DeviceMap.end ()) + { + Iterator->second->Send (voicedump, sizeof(voicedump)*sizeof(uint8_t), nCable); + } + } +} diff --git a/src/mididevice.h b/src/mididevice.h index 0b116d1..556306e 100644 --- a/src/mididevice.h +++ b/src/mididevice.h @@ -52,11 +52,9 @@ public: protected: void MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsigned nCable = 0); - void AddDevice (const char *pDeviceName); - - void HandleSystemExclusive(const uint8_t* pMessage, const size_t nLength, const uint8_t nTG); - + void HandleSystemExclusive(const uint8_t* pMessage, const size_t nLength, const unsigned nCable, const uint8_t nTG); + void SendSystemExclusiveVoice(uint8_t nVoice, const unsigned nCable, uint8_t nTG); private: CMiniDexed *m_pSynthesizer; CConfig *m_pConfig; diff --git a/src/minidexed.cpp b/src/minidexed.cpp index 21e79f1..1e1c173 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -1153,5 +1153,33 @@ void CMiniDexed::setVoiceDataElement(uint8_t data, uint8_t number, uint8_t nTG) int16_t CMiniDexed::checkSystemExclusive(const uint8_t* pMessage,const uint16_t nLength, uint8_t nTG) { + assert (nTG < CConfig::ToneGenerators); + assert (m_pTG[nTG]); + return(m_pTG[nTG]->checkSystemExclusive(pMessage, nLength)); } + +void CMiniDexed::getSysExVoiceDump(uint8_t* dest, uint8_t nTG) +{ + uint8_t checksum = 0; + uint8_t data[155]; + + assert (nTG < CConfig::ToneGenerators); + assert (m_pTG[nTG]); + + m_pTG[nTG]->getVoiceData(data); + + dest[0] = 0xF0; // SysEx start + dest[1] = 0x43; // ID=Yamaha + dest[2] = GetTGParameter(TGParameterMIDIChannel, nTG); // Sub-status and MIDI channel + dest[3] = 0x00; // Format number (0=1 voice) + dest[4] = 0x01; // Byte count MSB + dest[5] = 0x1B; // Byte count LSB + for (uint8_t n = 0; n < 155; n++) + { + checksum -= data[n]; + dest[6 + n] = data[n]; + } + dest[161] = checksum & 0x7f; // Checksum + dest[162] = 0xF7; // SysEx end +} diff --git a/src/minidexed.h b/src/minidexed.h index 66beb35..6eccf3e 100644 --- a/src/minidexed.h +++ b/src/minidexed.h @@ -100,6 +100,7 @@ public: void setAftertouchTarget(uint8_t target, uint8_t nTG); void loadVoiceParameters(const uint8_t* data, uint8_t nTG); void setVoiceDataElement(uint8_t data, uint8_t number, uint8_t nTG); + void getSysExVoiceDump(uint8_t* dest, uint8_t nTG); int16_t checkSystemExclusive(const uint8_t* pMessage, const uint16_t nLength, uint8_t nTG); diff --git a/src/serialmididevice.cpp b/src/serialmididevice.cpp index c3f2788..aed64a6 100644 --- a/src/serialmididevice.cpp +++ b/src/serialmididevice.cpp @@ -158,6 +158,7 @@ void CSerialMIDIDevice::Process (void) } } } + void CSerialMIDIDevice::Send (const u8 *pMessage, size_t nLength, unsigned nCable) { m_SendBuffer.Write (pMessage, nLength); From 0b75186c5aba0c627fe3395e9c06e4565c590798 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Sun, 22 May 2022 08:29:47 +0200 Subject: [PATCH 06/14] Fix for sending SYSEX voice dump to all interfaces. --- src/.mididevice.cpp.swp | Bin 0 -> 24576 bytes src/mididevice.cpp | 14 ++++++-------- 2 files changed, 6 insertions(+), 8 deletions(-) create mode 100644 src/.mididevice.cpp.swp diff --git a/src/.mididevice.cpp.swp b/src/.mididevice.cpp.swp new file mode 100644 index 0000000000000000000000000000000000000000..2e5140579eb329cf52896835cd85cac9db380542 GIT binary patch literal 24576 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 literal 0 HcmV?d00001 diff --git a/src/mididevice.cpp b/src/mididevice.cpp index 935570d..712adfa 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -458,14 +458,12 @@ void CMIDIDevice::SendSystemExclusiveVoice(uint8_t nVoice, const unsigned nCable // Get voice sysex dump from TG m_pSynthesizer->getSysExVoiceDump(voicedump, nTG); - if (m_DeviceName.compare (m_pConfig->GetMIDIThruIn ()) == 0) - { - TDeviceMap::const_iterator Iterator; + TDeviceMap::const_iterator Iterator; - Iterator = s_DeviceMap.find (m_pConfig->GetMIDIThruOut ()); - if (Iterator != s_DeviceMap.end ()) - { - Iterator->second->Send (voicedump, sizeof(voicedump)*sizeof(uint8_t), nCable); - } + // send voice dump to all MIDI interfaces + for(Iterator = s_DeviceMap.begin(); Iterator != s_DeviceMap.end(); ++Iterator) + { + Iterator->second->Send (voicedump, sizeof(voicedump)*sizeof(uint8_t), nCable); + LOGNOTE("Send SYSEX voice dump to \"%s\"\n",Iterator->first); } } From 7666793cc5431fefeb4caec8123a2d21f520138c Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Sun, 22 May 2022 12:42:30 +0200 Subject: [PATCH 07/14] Sending voice data via SYSEX when voice is changed. Adding master volume and changing master volume when SYSEX master volume is triggered. --- src/.mididevice.cpp.swp | Bin 24576 -> 0 bytes src/mididevice.cpp | 5 +- src/mididevice.h | 2 +- src/minidexed.cpp | 114 ++++++++++++++++++++++++---------------- src/minidexed.h | 3 ++ 5 files changed, 76 insertions(+), 48 deletions(-) delete mode 100644 src/.mididevice.cpp.swp diff --git a/src/.mididevice.cpp.swp b/src/.mididevice.cpp.swp deleted file mode 100644 index 2e5140579eb329cf52896835cd85cac9db380542..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24576 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 diff --git a/src/mididevice.cpp b/src/mididevice.cpp index 712adfa..9762e49 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -170,9 +170,9 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign // GLOBAL MIDI SYSEX if (pMessage[0] == MIDI_SYSTEM_EXCLUSIVE_BEGIN && pMessage[3] == 0x04 && pMessage[4] == 0x01 && pMessage[nLength-1] == MIDI_SYSTEM_EXCLUSIVE_END) // MASTER VOLUME { - float32_t nMasterVolume=(pMessage[5] & (pMessage[6]<<7))/(1<<14); + float32_t nMasterVolume=((pMessage[5] & 0x7c) & ((pMessage[6] & 0x7c) <<7))/(1<<14); LOGNOTE("Master volume: %f",nMasterVolume); - // TODO: Handle global master volume + m_pSynthesizer->setMasterVolume(nMasterVolume); } else { @@ -427,7 +427,6 @@ void CMIDIDevice::HandleSystemExclusive(const uint8_t* pMessage, const size_t nL // load sysex-data into voice memory LOGDBG("One Voice bulk upload"); m_pSynthesizer->loadVoiceParameters(pMessage,nTG); - break; case 200: LOGDBG("Bank bulk upload."); diff --git a/src/mididevice.h b/src/mididevice.h index 556306e..196a61b 100644 --- a/src/mididevice.h +++ b/src/mididevice.h @@ -49,12 +49,12 @@ public: u8 GetChannel (unsigned nTG) const; virtual void Send (const u8 *pMessage, size_t nLength, unsigned nCable = 0) {} + virtual void SendSystemExclusiveVoice(uint8_t nVoice, const unsigned nCable, uint8_t nTG); protected: void MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsigned nCable = 0); void AddDevice (const char *pDeviceName); void HandleSystemExclusive(const uint8_t* pMessage, const size_t nLength, const unsigned nCable, const uint8_t nTG); - void SendSystemExclusiveVoice(uint8_t nVoice, const unsigned nCable, uint8_t nTG); private: CMiniDexed *m_pSynthesizer; CConfig *m_pConfig; diff --git a/src/minidexed.cpp b/src/minidexed.cpp index 1e1c173..c434c0a 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -363,6 +363,7 @@ void CMiniDexed::ProgramChange (unsigned nProgram, unsigned nTG) assert (m_pTG[nTG]); m_pTG[nTG]->loadVoiceParameters (Buffer); + m_SerialMIDI.SendSystemExclusiveVoice(nProgram,0,nTG); m_UI.ParameterChanged (); } @@ -867,56 +868,70 @@ void CMiniDexed::ProcessSound (void) } // BEGIN TG mixing - for (uint8_t i = 0; i < CConfig::ToneGenerators; i++) - { - tg_mixer->doAddMix(i,m_OutputLevel[i]); - reverb_send_mixer->doAddMix(i,m_OutputLevel[i]); - } - // END TG mixing - - // BEGIN create SampleBuffer for holding audio data - float32_t SampleBuffer[2][nFrames]; - // END create SampleBuffer for holding audio data - - // get the mix of all TGs - tg_mixer->getMix(SampleBuffer[indexL], SampleBuffer[indexR]); + float32_t tmp_float[nFrames*2]; + int16_t tmp_int[nFrames*2]; - // BEGIN adding reverb - if (m_nParameter[ParameterReverbEnable]) + if(nMasterVolume > 0.0) { - float32_t ReverbBuffer[2][nFrames]; - float32_t ReverbSendBuffer[2][nFrames]; - - arm_fill_f32(0.0f, ReverbBuffer[indexL], nFrames); - arm_fill_f32(0.0f, ReverbBuffer[indexR], nFrames); - arm_fill_f32(0.0f, ReverbSendBuffer[indexR], nFrames); - arm_fill_f32(0.0f, ReverbSendBuffer[indexL], nFrames); - - m_ReverbSpinLock.Acquire (); - - reverb_send_mixer->getMix(ReverbSendBuffer[indexL], ReverbSendBuffer[indexR]); - reverb->doReverb(ReverbSendBuffer[indexL],ReverbSendBuffer[indexR],ReverbBuffer[indexL], ReverbBuffer[indexR],nFrames); + for (uint8_t i = 0; i < CConfig::ToneGenerators; i++) + { + tg_mixer->doAddMix(i,m_OutputLevel[i]); + reverb_send_mixer->doAddMix(i,m_OutputLevel[i]); + } + // END TG mixing + + // BEGIN create SampleBuffer for holding audio data + float32_t SampleBuffer[2][nFrames]; + // END create SampleBuffer for holding audio data - // scale down and add left reverb buffer by reverb level - arm_scale_f32(ReverbBuffer[indexL], reverb->get_level(), ReverbBuffer[indexL], nFrames); - arm_add_f32(SampleBuffer[indexL], ReverbBuffer[indexL], SampleBuffer[indexL], nFrames); - // scale down and add right reverb buffer by reverb level - arm_scale_f32(ReverbBuffer[indexR], reverb->get_level(), ReverbBuffer[indexR], nFrames); - arm_add_f32(SampleBuffer[indexR], ReverbBuffer[indexR], SampleBuffer[indexR], nFrames); + // get the mix of all TGs + tg_mixer->getMix(SampleBuffer[indexL], SampleBuffer[indexR]); - m_ReverbSpinLock.Release (); - } - // END adding reverb + // BEGIN adding reverb + if (m_nParameter[ParameterReverbEnable]) + { + float32_t ReverbBuffer[2][nFrames]; + float32_t ReverbSendBuffer[2][nFrames]; - // Convert dual float array (left, right) to single int16 array (left/right) - float32_t tmp_float[nFrames*2]; - int16_t tmp_int[nFrames*2]; - for(uint16_t i=0; igetMix(ReverbSendBuffer[indexL], ReverbSendBuffer[indexR]); + reverb->doReverb(ReverbSendBuffer[indexL],ReverbSendBuffer[indexR],ReverbBuffer[indexL], ReverbBuffer[indexR],nFrames); + + // scale down and add left reverb buffer by reverb level + arm_scale_f32(ReverbBuffer[indexL], reverb->get_level(), ReverbBuffer[indexL], nFrames); + arm_add_f32(SampleBuffer[indexL], ReverbBuffer[indexL], SampleBuffer[indexL], nFrames); + // scale down and add right reverb buffer by reverb level + arm_scale_f32(ReverbBuffer[indexR], reverb->get_level(), ReverbBuffer[indexR], nFrames); + arm_add_f32(SampleBuffer[indexR], ReverbBuffer[indexR], SampleBuffer[indexR], nFrames); + + m_ReverbSpinLock.Release (); + } + // END adding reverb + + // Convert dual float array (left, right) to single int16 array (left/right) + for(uint16_t i=0; i0.0 && nMasterVolume <1.0) + { + tmp_float[i*2]=SampleBuffer[indexL][i] * nMasterVolume; + tmp_float[(i*2)+1]=SampleBuffer[indexR][i] * nMasterVolume; + } + else if(nMasterVolume == 1.0) + { + tmp_float[i*2]=SampleBuffer[indexL][i]; + tmp_float[(i*2)+1]=SampleBuffer[indexR][i]; + } + } + arm_float_to_q15(tmp_float,tmp_int,nFrames*2); } - arm_float_to_q15(tmp_float,tmp_int,nFrames*2); + else + arm_fill_q15(0, tmp_int, nFrames * 2); if (m_pSoundDevice->Write (tmp_int, sizeof(tmp_int)) != (int) sizeof(tmp_int)) { @@ -1183,3 +1198,14 @@ void CMiniDexed::getSysExVoiceDump(uint8_t* dest, uint8_t nTG) dest[161] = checksum & 0x7f; // Checksum dest[162] = 0xF7; // SysEx end } + +void CMiniDexed::setMasterVolume (float32_t vol) +{ + if(vol < 0.0) + vol = 0.0; + else if(vol > 1.0) + vol = 1.0; + + nMasterVolume=vol; +} + diff --git a/src/minidexed.h b/src/minidexed.h index 6eccf3e..14a1023 100644 --- a/src/minidexed.h +++ b/src/minidexed.h @@ -150,6 +150,7 @@ public: std::string GetVoiceName (unsigned nTG); bool SavePerformance (void); + void setMasterVolume (float32_t vol); private: int16_t ApplyNoteLimits (int16_t pitch, unsigned nTG); // returns < 0 to ignore note @@ -195,6 +196,8 @@ private: unsigned m_nReverbSend[CConfig::ToneGenerators]; + float32_t nMasterVolume; + CUserInterface m_UI; CSysExFileLoader m_SysExFileLoader; CPerformanceConfig m_PerformanceConfig; From 01f99031c541142d8d0da2ea33dc62f062e27353 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Sun, 22 May 2022 13:11:14 +0200 Subject: [PATCH 08/14] Forgot to initialize nMasterVolume - just added it. --- src/minidexed.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/minidexed.cpp b/src/minidexed.cpp index c434c0a..d331792 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -124,6 +124,8 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt, } #endif + setMasterVolume(1.0); + // BEGIN setup tg_mixer tg_mixer = new AudioStereoMixer(pConfig->GetChunkSize()/2); // END setup tgmixer From c30a9c0dc65290bbda4eb68a641e6c232d452299 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Sun, 22 May 2022 14:11:01 +0200 Subject: [PATCH 09/14] Merge. --- src/minidexed.cpp | 17 ++++++++++++++++- src/minidexed.h | 3 +++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/minidexed.cpp b/src/minidexed.cpp index d331792..5e685e2 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -49,7 +49,8 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt, #endif m_GetChunkTimer ("GetChunk", 1000000U * pConfig->GetChunkSize ()/2 / pConfig->GetSampleRate ()), - m_bProfileEnabled (m_pConfig->GetProfileEnabled ()) + m_bProfileEnabled (m_pConfig->GetProfileEnabled ()), + m_bSavePerformance (false) { assert (m_pConfig); @@ -272,6 +273,13 @@ void CMiniDexed::Process (bool bPlugAndPlayUpdated) m_UI.Process (); + if (m_bSavePerformance) + { + DoSavePerformance (); + + m_bSavePerformance = false; + } + if (m_bProfileEnabled) { m_GetChunkTimer.Dump (); @@ -950,6 +958,13 @@ void CMiniDexed::ProcessSound (void) #endif bool CMiniDexed::SavePerformance (void) +{ + m_bSavePerformance = true; + + return true; +} + +bool CMiniDexed::DoSavePerformance (void) { for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++) { diff --git a/src/minidexed.h b/src/minidexed.h index 14a1023..6223e5f 100644 --- a/src/minidexed.h +++ b/src/minidexed.h @@ -151,6 +151,7 @@ public: bool SavePerformance (void); void setMasterVolume (float32_t vol); + bool DoSavePerformance (void); private: int16_t ApplyNoteLimits (int16_t pitch, unsigned nTG); // returns < 0 to ignore note @@ -226,6 +227,8 @@ private: AudioStereoMixer* reverb_send_mixer; CSpinLock m_ReverbSpinLock; + + bool m_bSavePerformance; }; #endif From 7afc844d7432a56b1a3fbc4f338f3f3806cf2471 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Tue, 24 May 2022 08:14:11 +0200 Subject: [PATCH 10/14] Added a SpinLock around MIDI message processing. --- src/mididevice.cpp | 3 +++ src/mididevice.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/mididevice.cpp b/src/mididevice.cpp index 9762e49..6959b41 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -163,6 +163,8 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign return; } + m_MIDISpinLock.Acquire (); + u8 ucStatus = pMessage[0]; u8 ucChannel = ucStatus & 0x0F; u8 ucType = ucStatus >> 4; @@ -313,6 +315,7 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign } } } + m_MIDISpinLock.Release (); } void CMIDIDevice::AddDevice (const char *pDeviceName) diff --git a/src/mididevice.h b/src/mididevice.h index 196a61b..1bd5396 100644 --- a/src/mididevice.h +++ b/src/mididevice.h @@ -27,6 +27,7 @@ #include #include #include +#include class CMiniDexed; @@ -65,6 +66,8 @@ private: typedef std::unordered_map TDeviceMap; static TDeviceMap s_DeviceMap; + + CSpinLock m_MIDISpinLock; }; #endif From 821390436a90cac69169242c7faf34dc9c6b2105 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Tue, 24 May 2022 08:49:36 +0200 Subject: [PATCH 11/14] Added notesOff() when changing algorithm parameter (can be extended later for other parameters). --- src/mididevice.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mididevice.cpp b/src/mididevice.cpp index 6959b41..d96d089 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -441,6 +441,12 @@ void CMIDIDevice::HandleSystemExclusive(const uint8_t* pMessage, const size_t nL { LOGDBG("SysEx voice parameter change: Parameter %d value: %d",pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5]); m_pSynthesizer->setVoiceDataElement(pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5],nTG); + switch(pMessage[4] + ((pMessage[3] & 0x03) * 128)) + { + case 134: + m_pSynthesizer->notesOff(0,nTG); + break; + } } else if(sysex_return >= 500 && sysex_return < 600) { From 04afcee58f372868fe1ee10e32f1619e84e2dc63 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Tue, 31 May 2022 09:54:01 +0200 Subject: [PATCH 12/14] Fix for garbage when showing device name. --- src/mididevice.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mididevice.cpp b/src/mididevice.cpp index d96d089..4e15cf1 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -461,8 +461,6 @@ void CMIDIDevice::SendSystemExclusiveVoice(uint8_t nVoice, const unsigned nCable { uint8_t voicedump[163]; - LOGDBG("Sending SysEx voice %u ",nVoice); - // Get voice sysex dump from TG m_pSynthesizer->getSysExVoiceDump(voicedump, nTG); @@ -471,7 +469,7 @@ void CMIDIDevice::SendSystemExclusiveVoice(uint8_t nVoice, const unsigned nCable // send voice dump to all MIDI interfaces for(Iterator = s_DeviceMap.begin(); Iterator != s_DeviceMap.end(); ++Iterator) { - Iterator->second->Send (voicedump, sizeof(voicedump)*sizeof(uint8_t), nCable); - LOGNOTE("Send SYSEX voice dump to \"%s\"\n",Iterator->first); + Iterator->second->Send (voicedump, sizeof(voicedump)*sizeof(uint8_t)); + LOGDBG("Send SYSEX voice dump %u to \"%s\"",nVoice,Iterator->first.c_str()); } } From d81b242095c6e3295cfb6d4945df00514f054acc Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Mon, 20 Nov 2023 09:56:58 +0100 Subject: [PATCH 13/14] Comments on some "m_pTG[nTG]->ControllersRefresh();" when changing the range or target of controllers, due to problems. --- src/minidexed.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/minidexed.cpp b/src/minidexed.cpp index 1ddf250..d587961 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -1312,7 +1312,7 @@ void CMiniDexed::setModWheelRange(uint8_t range, uint8_t nTG) m_pTG[nTG]->setMWController(range, m_pTG[nTG]->getModWheelTarget(), 0); // m_pTG[nTG]->setModWheelRange(constrain(range, 0, 99)); replaces with the above due to wrong constrain on dexed_synth module. - m_pTG[nTG]->ControllersRefresh(); + //m_pTG[nTG]->ControllersRefresh(); m_UI.ParameterChanged (); } @@ -1324,7 +1324,7 @@ void CMiniDexed::setModWheelTarget(uint8_t target, uint8_t nTG) m_nModulationWheelTarget[nTG] = target; m_pTG[nTG]->setModWheelTarget(constrain(target, 0, 7)); - m_pTG[nTG]->ControllersRefresh(); + //m_pTG[nTG]->ControllersRefresh(); m_UI.ParameterChanged (); } @@ -1337,7 +1337,7 @@ void CMiniDexed::setFootControllerRange(uint8_t range, uint8_t nTG) m_pTG[nTG]->setFCController(range, m_pTG[nTG]->getFootControllerTarget(), 0); // m_pTG[nTG]->setFootControllerRange(constrain(range, 0, 99)); replaces with the above due to wrong constrain on dexed_synth module. - m_pTG[nTG]->ControllersRefresh(); + //m_pTG[nTG]->ControllersRefresh(); m_UI.ParameterChanged (); } @@ -1349,7 +1349,7 @@ void CMiniDexed::setFootControllerTarget(uint8_t target, uint8_t nTG) m_nFootControlTarget[nTG] = target; m_pTG[nTG]->setFootControllerTarget(constrain(target, 0, 7)); - m_pTG[nTG]->ControllersRefresh(); + //m_pTG[nTG]->ControllersRefresh(); m_UI.ParameterChanged (); } @@ -1362,7 +1362,7 @@ void CMiniDexed::setBreathControllerRange(uint8_t range, uint8_t nTG) m_pTG[nTG]->setBCController(range, m_pTG[nTG]->getBreathControllerTarget(), 0); //m_pTG[nTG]->setBreathControllerRange(constrain(range, 0, 99)); - m_pTG[nTG]->ControllersRefresh(); + //m_pTG[nTG]->ControllersRefresh(); m_UI.ParameterChanged (); } @@ -1374,7 +1374,7 @@ void CMiniDexed::setBreathControllerTarget(uint8_t target, uint8_t nTG) m_nBreathControlTarget[nTG]=target; m_pTG[nTG]->setBreathControllerTarget(constrain(target, 0, 7)); - m_pTG[nTG]->ControllersRefresh(); + //m_pTG[nTG]->ControllersRefresh(); m_UI.ParameterChanged (); } @@ -1387,7 +1387,7 @@ void CMiniDexed::setAftertouchRange(uint8_t range, uint8_t nTG) m_pTG[nTG]->setATController(range, m_pTG[nTG]->getAftertouchTarget(), 0); // m_pTG[nTG]->setAftertouchRange(constrain(range, 0, 99)); - m_pTG[nTG]->ControllersRefresh(); + //m_pTG[nTG]->ControllersRefresh(); m_UI.ParameterChanged (); } @@ -1399,7 +1399,7 @@ void CMiniDexed::setAftertouchTarget(uint8_t target, uint8_t nTG) m_nAftertouchTarget[nTG]=target; m_pTG[nTG]->setAftertouchTarget(constrain(target, 0, 7)); - m_pTG[nTG]->ControllersRefresh(); + //m_pTG[nTG]->ControllersRefresh(); m_UI.ParameterChanged (); } From e05cb6c5c29bb4dd5ef241c4a196680032161002 Mon Sep 17 00:00:00 2001 From: probonopd Date: Mon, 20 Nov 2023 19:17:24 +0100 Subject: [PATCH 14/14] Synth_Dexed af3c7ce --- submod.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submod.sh b/submod.sh index dcdf2af..0a1afd9 100755 --- a/submod.sh +++ b/submod.sh @@ -11,5 +11,5 @@ cd circle-stdlib/libs/circle-newlib git checkout 48bf91d # needed for circle ec09d7e cd - cd Synth_Dexed/ -git checkout c9f5274 +git checkout af3c7ce cd -