Code for sending a voice dump via MIDI started.

pull/247/head
Holger Wirtz 3 years ago
parent 2cb0631efc
commit 55e90c6aa1
  1. 73
      src/mididevice.cpp
  2. 6
      src/mididevice.h
  3. 28
      src/minidexed.cpp
  4. 1
      src/minidexed.h
  5. 1
      src/serialmididevice.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)); printf("MIDI%u: SysEx data length: [%d]:",nCable, uint16_t(nLength));
for (uint16_t i = 0; i < nLength; i++) for (uint16_t i = 0; i < nLength; i++)
{ {
if((i % 8) == 0) if((i % 16) == 0)
printf("\n%04d:",i); printf("\n%04d:",i);
printf(" 0x%02x",pMessage[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 // Handle MIDI Thru
if (m_DeviceName.compare (m_pConfig->GetMIDIThruIn ()) == 0) 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) if (m_ChannelMap[nTG] == ucSysExChannel || m_ChannelMap[nTG] == OmniMode)
{ {
LOGNOTE("MIDI-SYSEX: channel: %u, len: %u, TG: %u",m_ChannelMap[nTG],nLength,nTG); LOGNOTE("MIDI-SYSEX: channel: %u, len: %u, TG: %u",m_ChannelMap[nTG],nLength,nTG);
HandleSystemExclusive(pMessage, nLength, nTG); HandleSystemExclusive(pMessage, nLength, nCable, nTG);
} }
} }
else else
@ -311,7 +326,7 @@ void CMIDIDevice::AddDevice (const char *pDeviceName)
s_DeviceMap.insert (std::pair<std::string, CMIDIDevice *> (pDeviceName, this)); s_DeviceMap.insert (std::pair<std::string, CMIDIDevice *> (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; 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."); LOGERR("SysEx end status byte not detected.");
break; break;
case -2: case -2:
LOGERR("E: SysEx vendor not Yamaha."); LOGERR("SysEx vendor not Yamaha.");
break; break;
case -3: case -3:
LOGERR("E: Unknown SysEx parameter change."); LOGERR("Unknown SysEx parameter change.");
break; break;
case -4: case -4:
LOGERR(" Unknown SysEx voice or function."); LOGERR("Unknown SysEx voice or function.");
break; break;
case -5: case -5:
LOGERR("E: Not a SysEx voice bulk upload."); LOGERR("Not a SysEx voice bulk upload.");
break; break;
case -6: case -6:
LOGERR("E: Wrong length for SysEx voice bulk upload (not 155)."); LOGERR("Wrong length for SysEx voice bulk upload (not 155).");
break; break;
case -7: case -7:
LOGERR("E: Checksum error for one voice."); LOGERR("Checksum error for one voice.");
break; break;
case -8: case -8:
LOGERR("E: Not a SysEx bank bulk upload."); LOGERR("Not a SysEx bank bulk upload.");
break; break;
case -9: 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: case -10:
LOGERR("E: Checksum error for bank."); LOGERR("Checksum error for bank.");
break; break;
case -11: case -11:
LOGERR("E: Unknown SysEx message."); LOGERR("Unknown SysEx message.");
break; break;
case 64: case 64:
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); 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!"); LOGNOTE("Currently code for storing a bulk bank upload is missing!");
break; break;
default: default:
LOGDBG("SysEx voice parameter change: Parameter %d value: %d",pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5]); if(sysex_return >= 300 && sysex_return < 500)
m_pSynthesizer->setVoiceDataElement(pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5],nTG); {
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; 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);
}
}
}

@ -52,11 +52,9 @@ public:
protected: protected:
void MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsigned nCable = 0); void MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsigned nCable = 0);
void AddDevice (const char *pDeviceName); void AddDevice (const char *pDeviceName);
void HandleSystemExclusive(const uint8_t* pMessage, const size_t nLength, const unsigned nCable, const uint8_t nTG);
void HandleSystemExclusive(const uint8_t* pMessage, const size_t nLength, const uint8_t nTG); void SendSystemExclusiveVoice(uint8_t nVoice, const unsigned nCable, uint8_t nTG);
private: private:
CMiniDexed *m_pSynthesizer; CMiniDexed *m_pSynthesizer;
CConfig *m_pConfig; CConfig *m_pConfig;

@ -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) 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)); 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
}

@ -100,6 +100,7 @@ public:
void setAftertouchTarget(uint8_t target, uint8_t nTG); void setAftertouchTarget(uint8_t target, uint8_t nTG);
void loadVoiceParameters(const uint8_t* data, uint8_t nTG); void loadVoiceParameters(const uint8_t* data, uint8_t nTG);
void setVoiceDataElement(uint8_t data, uint8_t number, 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); int16_t checkSystemExclusive(const uint8_t* pMessage, const uint16_t nLength, uint8_t nTG);

@ -158,6 +158,7 @@ void CSerialMIDIDevice::Process (void)
} }
} }
} }
void CSerialMIDIDevice::Send (const u8 *pMessage, size_t nLength, unsigned nCable) void CSerialMIDIDevice::Send (const u8 *pMessage, size_t nLength, unsigned nCable)
{ {
m_SendBuffer.Write (pMessage, nLength); m_SendBuffer.Write (pMessage, nLength);

Loading…
Cancel
Save