|
|
|
@ -29,30 +29,30 @@ |
|
|
|
|
#include <assert.h> |
|
|
|
|
#include "userinterface.h" |
|
|
|
|
|
|
|
|
|
LOGMODULE ("mididevice"); |
|
|
|
|
LOGMODULE("mididevice"); |
|
|
|
|
|
|
|
|
|
#define MIDI_NOTE_OFF 0b1000 |
|
|
|
|
#define MIDI_NOTE_ON 0b1001 |
|
|
|
|
#define MIDI_AFTERTOUCH 0b1010 // TODO
|
|
|
|
|
#define MIDI_CHANNEL_AFTERTOUCH 0b1101 // right now Synth_Dexed just manage Channel Aftertouch not Polyphonic AT -> 0b1010
|
|
|
|
|
#define MIDI_CONTROL_CHANGE 0b1011 |
|
|
|
|
#define MIDI_CC_BANK_SELECT_MSB 0 |
|
|
|
|
#define MIDI_CC_MODULATION 1 |
|
|
|
|
#define MIDI_CC_BREATH_CONTROLLER 2 |
|
|
|
|
#define MIDI_CC_FOOT_PEDAL 4 |
|
|
|
|
#define MIDI_CC_VOLUME 7 |
|
|
|
|
#define MIDI_CC_PAN_POSITION 10 |
|
|
|
|
#define MIDI_CC_BANK_SELECT_LSB 32 |
|
|
|
|
#define MIDI_CC_BANK_SUSTAIN 64 |
|
|
|
|
#define MIDI_CC_RESONANCE 71 |
|
|
|
|
#define MIDI_CC_FREQUENCY_CUTOFF 74 |
|
|
|
|
#define MIDI_CC_REVERB_LEVEL 91 |
|
|
|
|
#define MIDI_CC_ORBITONE_LEVEL 92 // added with mixing console
|
|
|
|
|
#define MIDI_CC_CHORUS_LEVEL 93 // added with mixing console
|
|
|
|
|
#define MIDI_CC_DETUNE_LEVEL 94 |
|
|
|
|
#define MIDI_CC_PHASER_LEVEL 95 // added with mixing console
|
|
|
|
|
#define MIDI_CC_ALL_SOUND_OFF 120 |
|
|
|
|
#define MIDI_CC_ALL_NOTES_OFF 123 |
|
|
|
|
#define MIDI_CC_BANK_SELECT_MSB 0 |
|
|
|
|
#define MIDI_CC_MODULATION 1 |
|
|
|
|
#define MIDI_CC_BREATH_CONTROLLER 2 |
|
|
|
|
#define MIDI_CC_FOOT_PEDAL 4 |
|
|
|
|
#define MIDI_CC_VOLUME 7 |
|
|
|
|
#define MIDI_CC_PAN_POSITION 10 |
|
|
|
|
#define MIDI_CC_BANK_SELECT_LSB 32 |
|
|
|
|
#define MIDI_CC_BANK_SUSTAIN 64 |
|
|
|
|
#define MIDI_CC_RESONANCE 71 |
|
|
|
|
#define MIDI_CC_FREQUENCY_CUTOFF 74 |
|
|
|
|
#define MIDI_CC_REVERB_LEVEL 91 |
|
|
|
|
#define MIDI_CC_ORBITONE_LEVEL 92 // added with mixing console
|
|
|
|
|
#define MIDI_CC_CHORUS_LEVEL 93 // added with mixing console
|
|
|
|
|
#define MIDI_CC_DETUNE_LEVEL 94 |
|
|
|
|
#define MIDI_CC_PHASER_LEVEL 95 // added with mixing console
|
|
|
|
|
#define MIDI_CC_ALL_SOUND_OFF 120 |
|
|
|
|
#define MIDI_CC_ALL_NOTES_OFF 123 |
|
|
|
|
#define MIDI_PROGRAM_CHANGE 0b1100 |
|
|
|
|
#define MIDI_PITCH_BEND 0b1110 |
|
|
|
|
|
|
|
|
@ -63,10 +63,10 @@ LOGMODULE ("mididevice"); |
|
|
|
|
|
|
|
|
|
CMIDIDevice::TDeviceMap CMIDIDevice::s_DeviceMap; |
|
|
|
|
|
|
|
|
|
CMIDIDevice::CMIDIDevice (CMiniDexed *pSynthesizer, CConfig *pConfig, CUserInterface *pUI) |
|
|
|
|
: m_pSynthesizer (pSynthesizer), |
|
|
|
|
m_pConfig (pConfig), |
|
|
|
|
m_pUI (pUI) |
|
|
|
|
CMIDIDevice::CMIDIDevice(CMiniDexed *pSynthesizer, CConfig *pConfig, CUserInterface *pUI) |
|
|
|
|
: m_pSynthesizer(pSynthesizer), |
|
|
|
|
m_pConfig(pConfig), |
|
|
|
|
m_pUI(pUI) |
|
|
|
|
{ |
|
|
|
|
for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++) |
|
|
|
|
{ |
|
|
|
@ -74,72 +74,71 @@ CMIDIDevice::CMIDIDevice (CMiniDexed *pSynthesizer, CConfig *pConfig, CUserInter |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
CMIDIDevice::~CMIDIDevice (void) |
|
|
|
|
CMIDIDevice::~CMIDIDevice(void) |
|
|
|
|
{ |
|
|
|
|
m_pSynthesizer = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CMIDIDevice::SetChannel (u8 ucChannel, unsigned nTG) |
|
|
|
|
void CMIDIDevice::SetChannel(u8 ucChannel, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert(nTG < CConfig::ToneGenerators); |
|
|
|
|
m_ChannelMap[nTG] = ucChannel; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
u8 CMIDIDevice::GetChannel (unsigned nTG) const |
|
|
|
|
u8 CMIDIDevice::GetChannel(unsigned nTG) const |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert(nTG < CConfig::ToneGenerators); |
|
|
|
|
return m_ChannelMap[nTG]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsigned nCable) |
|
|
|
|
void CMIDIDevice::MIDIMessageHandler(const u8 *pMessage, size_t nLength, unsigned nCable) |
|
|
|
|
{ |
|
|
|
|
// The packet contents are just normal MIDI data - see
|
|
|
|
|
// https://www.midi.org/specifications/item/table-1-summary-of-midi-message
|
|
|
|
|
|
|
|
|
|
if (m_pConfig->GetMIDIDumpEnabled ()) |
|
|
|
|
if (m_pConfig->GetMIDIDumpEnabled()) |
|
|
|
|
{ |
|
|
|
|
switch (nLength) |
|
|
|
|
{ |
|
|
|
|
case 1: |
|
|
|
|
if ( pMessage[0] != MIDI_TIMING_CLOCK |
|
|
|
|
&& pMessage[0] != MIDI_ACTIVE_SENSING) |
|
|
|
|
if (pMessage[0] != MIDI_TIMING_CLOCK && pMessage[0] != MIDI_ACTIVE_SENSING) |
|
|
|
|
{ |
|
|
|
|
printf ("MIDI%u: %02X\n", nCable, (unsigned) pMessage[0]); |
|
|
|
|
printf("MIDI%u: %02X\n", nCable, (unsigned)pMessage[0]); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 2: |
|
|
|
|
printf ("MIDI%u: %02X %02X\n", nCable, |
|
|
|
|
(unsigned) pMessage[0], (unsigned) pMessage[1]); |
|
|
|
|
printf("MIDI%u: %02X %02X\n", nCable, |
|
|
|
|
(unsigned)pMessage[0], (unsigned)pMessage[1]); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 3: |
|
|
|
|
printf ("MIDI%u: %02X %02X %02X\n", nCable, |
|
|
|
|
(unsigned) pMessage[0], (unsigned) pMessage[1], |
|
|
|
|
(unsigned) pMessage[2]); |
|
|
|
|
printf("MIDI%u: %02X %02X %02X\n", nCable, |
|
|
|
|
(unsigned)pMessage[0], (unsigned)pMessage[1], |
|
|
|
|
(unsigned)pMessage[2]); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
switch(pMessage[0]) |
|
|
|
|
switch (pMessage[0]) |
|
|
|
|
{ |
|
|
|
|
case MIDI_SYSTEM_EXCLUSIVE_BEGIN: |
|
|
|
|
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++) |
|
|
|
|
{ |
|
|
|
|
if((i % 16) == 0) |
|
|
|
|
printf("\n%04d:",i); |
|
|
|
|
printf(" 0x%02x",pMessage[i]); |
|
|
|
|
if ((i % 16) == 0) |
|
|
|
|
printf("\n%04d:", i); |
|
|
|
|
printf(" 0x%02x", pMessage[i]); |
|
|
|
|
} |
|
|
|
|
printf("\n"); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
printf("MIDI%u: Unhandled MIDI event type %0x02x\n",nCable,pMessage[0]); |
|
|
|
|
printf("MIDI%u: Unhandled MIDI event type %0x02x\n", nCable, pMessage[0]); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Only for debugging:
|
|
|
|
|
/*
|
|
|
|
|
/*
|
|
|
|
|
if(pMessage[0]==MIDI_SYSTEM_EXCLUSIVE_BEGIN) |
|
|
|
|
{ |
|
|
|
|
printf("MIDI%u: SysEx data length: [%d]:",nCable, uint16_t(nLength)); |
|
|
|
@ -151,17 +150,17 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign |
|
|
|
|
} |
|
|
|
|
printf("\n"); |
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
// Handle MIDI Thru
|
|
|
|
|
if (m_DeviceName.compare (m_pConfig->GetMIDIThruIn ()) == 0) |
|
|
|
|
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 = s_DeviceMap.find(m_pConfig->GetMIDIThruOut()); |
|
|
|
|
if (Iterator != s_DeviceMap.end()) |
|
|
|
|
{ |
|
|
|
|
Iterator->second->Send (pMessage, nLength, nCable); |
|
|
|
|
Iterator->second->Send(pMessage, nLength, nCable); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -171,17 +170,17 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
m_MIDISpinLock.Acquire (); |
|
|
|
|
m_MIDISpinLock.Acquire(); |
|
|
|
|
|
|
|
|
|
u8 ucStatus = pMessage[0]; |
|
|
|
|
u8 ucChannel = ucStatus & 0x0F; |
|
|
|
|
u8 ucType = ucStatus >> 4; |
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
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] & 0x7c) & ((pMessage[6] & 0x7c) <<7))/(1<<14); |
|
|
|
|
LOGNOTE("Master volume: %f",nMasterVolume); |
|
|
|
|
float32_t nMasterVolume = ((pMessage[5] & 0x7c) & ((pMessage[6] & 0x7c) << 7)) / (1 << 14); |
|
|
|
|
LOGNOTE("Master volume: %f", nMasterVolume); |
|
|
|
|
m_pSynthesizer->setMasterVolume(nMasterVolume); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
@ -196,7 +195,7 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign |
|
|
|
|
{ |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
m_pUI->UIMIDICmdHandler (ucChannel, ucStatus & 0xF0, pMessage[1], pMessage[2]); |
|
|
|
|
m_pUI->UIMIDICmdHandler(ucChannel, ucStatus & 0xF0, pMessage[1], pMessage[2]); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -209,14 +208,13 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign |
|
|
|
|
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); |
|
|
|
|
LOGNOTE("MIDI-SYSEX: channel: %u, len: %u, TG: %u", m_ChannelMap[nTG], nLength, nTG); |
|
|
|
|
HandleSystemExclusive(pMessage, nLength, nCable, nTG); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
if ( m_ChannelMap[nTG] == ucChannel |
|
|
|
|
|| m_ChannelMap[nTG] == OmniMode) |
|
|
|
|
if (m_ChannelMap[nTG] == ucChannel || m_ChannelMap[nTG] == OmniMode) |
|
|
|
|
{ |
|
|
|
|
switch (ucType) |
|
|
|
|
{ |
|
|
|
@ -230,13 +228,13 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign |
|
|
|
|
{ |
|
|
|
|
if (pMessage[2] <= 127) |
|
|
|
|
{ |
|
|
|
|
m_pSynthesizer->keydown (pMessage[1], |
|
|
|
|
m_pSynthesizer->keydown(pMessage[1], |
|
|
|
|
pMessage[2], nTG); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
m_pSynthesizer->keyup (pMessage[1], nTG); |
|
|
|
|
m_pSynthesizer->keyup(pMessage[1], nTG); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
@ -246,13 +244,13 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
m_pSynthesizer->keyup (pMessage[1], nTG); |
|
|
|
|
m_pSynthesizer->keyup(pMessage[1], nTG); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_CHANNEL_AFTERTOUCH: |
|
|
|
|
|
|
|
|
|
m_pSynthesizer->setAftertouch (pMessage[1], nTG); |
|
|
|
|
m_pSynthesizer->ControllersRefresh (nTG); |
|
|
|
|
m_pSynthesizer->setAftertouch(pMessage[1], nTG); |
|
|
|
|
m_pSynthesizer->ControllersRefresh(nTG); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_CONTROL_CHANGE: |
|
|
|
@ -264,53 +262,53 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign |
|
|
|
|
switch (pMessage[1]) |
|
|
|
|
{ |
|
|
|
|
case MIDI_CC_MODULATION: |
|
|
|
|
m_pSynthesizer->setModWheel (pMessage[2], nTG); |
|
|
|
|
m_pSynthesizer->ControllersRefresh (nTG); |
|
|
|
|
m_pSynthesizer->setModWheel(pMessage[2], nTG); |
|
|
|
|
m_pSynthesizer->ControllersRefresh(nTG); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_CC_FOOT_PEDAL: |
|
|
|
|
m_pSynthesizer->setFootController (pMessage[2], nTG); |
|
|
|
|
m_pSynthesizer->ControllersRefresh (nTG); |
|
|
|
|
m_pSynthesizer->setFootController(pMessage[2], nTG); |
|
|
|
|
m_pSynthesizer->ControllersRefresh(nTG); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_CC_BREATH_CONTROLLER: |
|
|
|
|
m_pSynthesizer->setBreathController (pMessage[2], nTG); |
|
|
|
|
m_pSynthesizer->ControllersRefresh (nTG); |
|
|
|
|
m_pSynthesizer->setBreathController(pMessage[2], nTG); |
|
|
|
|
m_pSynthesizer->ControllersRefresh(nTG); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_CC_VOLUME: |
|
|
|
|
m_pSynthesizer->SetVolume (pMessage[2], nTG); |
|
|
|
|
m_pSynthesizer->SetVolume(pMessage[2], nTG); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_CC_PAN_POSITION: |
|
|
|
|
m_pSynthesizer->SetPan (pMessage[2], nTG); |
|
|
|
|
m_pSynthesizer->SetPan(pMessage[2], nTG); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_CC_BANK_SELECT_MSB: |
|
|
|
|
m_pSynthesizer->BankSelectMSB (pMessage[2], nTG); |
|
|
|
|
m_pSynthesizer->BankSelectMSB(pMessage[2], nTG); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_CC_BANK_SELECT_LSB: |
|
|
|
|
m_pSynthesizer->BankSelectLSB (pMessage[2], nTG); |
|
|
|
|
m_pSynthesizer->BankSelectLSB(pMessage[2], nTG); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_CC_BANK_SUSTAIN: |
|
|
|
|
m_pSynthesizer->setSustain (pMessage[2] >= 64, nTG); |
|
|
|
|
m_pSynthesizer->setSustain(pMessage[2] >= 64, nTG); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_CC_RESONANCE: |
|
|
|
|
m_pSynthesizer->SetResonance (maplong (pMessage[2], 0, 127, 0, 99), nTG); |
|
|
|
|
m_pSynthesizer->SetResonance(maplong(pMessage[2], 0, 127, 0, 99), nTG); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_CC_FREQUENCY_CUTOFF: |
|
|
|
|
m_pSynthesizer->SetCutoff (maplong (pMessage[2], 0, 127, 0, 99), nTG); |
|
|
|
|
m_pSynthesizer->SetCutoff(maplong(pMessage[2], 0, 127, 0, 99), nTG); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_CC_REVERB_LEVEL: |
|
|
|
|
#ifdef MIXING_CONSOLE_ENABLE |
|
|
|
|
this->m_pSynthesizer->setMixingConsoleSendLevel(nTG, MixerOutput::FX_PlateReverb, maplong(pMessage[2], 0, 127, 0, 99)); |
|
|
|
|
#else |
|
|
|
|
m_pSynthesizer->SetReverbSend (maplong (pMessage[2], 0, 127, 0, 99), nTG); |
|
|
|
|
m_pSynthesizer->SetReverbSend(maplong(pMessage[2], 0, 127, 0, 99), nTG); |
|
|
|
|
#endif |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
@ -330,22 +328,25 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign |
|
|
|
|
if (pMessage[2] == 0) |
|
|
|
|
{ |
|
|
|
|
// "0 to 127, with 0 being no celeste (detune) effect applied at all."
|
|
|
|
|
m_pSynthesizer->SetMasterTune (0, nTG); |
|
|
|
|
m_pSynthesizer->SetMasterTune(0, nTG); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
m_pSynthesizer->SetMasterTune (maplong (pMessage[2], 1, 127, -99, 99), nTG); |
|
|
|
|
m_pSynthesizer->SetMasterTune(maplong(pMessage[2], 1, 127, -99, 99), nTG); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_CC_ALL_SOUND_OFF: |
|
|
|
|
m_pSynthesizer->panic (pMessage[2], nTG); |
|
|
|
|
m_pSynthesizer->panic(pMessage[2], nTG); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_CC_ALL_NOTES_OFF: |
|
|
|
|
if (!m_pConfig->GetIgnoreAllNotesOff ()) |
|
|
|
|
// As per "MIDI 1.0 Detailed Specification" v4.2
|
|
|
|
|
// From "ALL NOTES OFF" states:
|
|
|
|
|
// "Receivers should ignore an All Notes Off message while Omni is on (Modes 1 & 2)"
|
|
|
|
|
if (!m_pConfig->GetIgnoreAllNotesOff() && m_ChannelMap[nTG] != OmniMode) |
|
|
|
|
{ |
|
|
|
|
m_pSynthesizer->notesOff (pMessage[2], nTG); |
|
|
|
|
m_pSynthesizer->notesOff(pMessage[2], nTG); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
@ -353,22 +354,24 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign |
|
|
|
|
|
|
|
|
|
case MIDI_PROGRAM_CHANGE: |
|
|
|
|
// do program change only if enabled in config
|
|
|
|
|
if( m_pConfig->GetMIDIRXProgramChange() ) |
|
|
|
|
m_pSynthesizer->ProgramChange (pMessage[1], nTG); |
|
|
|
|
if (m_pConfig->GetMIDIRXProgramChange()) |
|
|
|
|
m_pSynthesizer->ProgramChange(pMessage[1], nTG); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case MIDI_PITCH_BEND: { |
|
|
|
|
case MIDI_PITCH_BEND: |
|
|
|
|
{ |
|
|
|
|
if (nLength < 3) |
|
|
|
|
{ |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
s16 nValue = pMessage[1]; |
|
|
|
|
nValue |= (s16) pMessage[2] << 7; |
|
|
|
|
nValue |= (s16)pMessage[2] << 7; |
|
|
|
|
nValue -= 0x2000; |
|
|
|
|
|
|
|
|
|
m_pSynthesizer->setPitchbend (nValue, nTG); |
|
|
|
|
} break; |
|
|
|
|
m_pSynthesizer->setPitchbend(nValue, nTG); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
break; |
|
|
|
@ -377,21 +380,21 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
m_MIDISpinLock.Release (); |
|
|
|
|
m_MIDISpinLock.Release(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CMIDIDevice::AddDevice (const char *pDeviceName) |
|
|
|
|
void CMIDIDevice::AddDevice(const char *pDeviceName) |
|
|
|
|
{ |
|
|
|
|
assert (pDeviceName); |
|
|
|
|
assert(pDeviceName); |
|
|
|
|
|
|
|
|
|
assert (m_DeviceName.empty ()); |
|
|
|
|
assert(m_DeviceName.empty()); |
|
|
|
|
m_DeviceName = pDeviceName; |
|
|
|
|
assert (!m_DeviceName.empty ()); |
|
|
|
|
assert(!m_DeviceName.empty()); |
|
|
|
|
|
|
|
|
|
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 unsigned nCable, 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; |
|
|
|
|
|
|
|
|
@ -433,87 +436,87 @@ void CMIDIDevice::HandleSystemExclusive(const uint8_t* pMessage, const size_t nL |
|
|
|
|
LOGERR("Unknown SysEx message."); |
|
|
|
|
break; |
|
|
|
|
case 64: |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); |
|
|
|
|
m_pSynthesizer->setMonoMode(pMessage[5],nTG); |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]); |
|
|
|
|
m_pSynthesizer->setMonoMode(pMessage[5], nTG); |
|
|
|
|
break; |
|
|
|
|
case 65: |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); |
|
|
|
|
m_pSynthesizer->setPitchbendRange(pMessage[5],nTG); |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]); |
|
|
|
|
m_pSynthesizer->setPitchbendRange(pMessage[5], nTG); |
|
|
|
|
break; |
|
|
|
|
case 66: |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); |
|
|
|
|
m_pSynthesizer->setPitchbendStep(pMessage[5],nTG); |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]); |
|
|
|
|
m_pSynthesizer->setPitchbendStep(pMessage[5], nTG); |
|
|
|
|
break; |
|
|
|
|
case 67: |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); |
|
|
|
|
m_pSynthesizer->setPortamentoMode(pMessage[5],nTG); |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]); |
|
|
|
|
m_pSynthesizer->setPortamentoMode(pMessage[5], nTG); |
|
|
|
|
break; |
|
|
|
|
case 68: |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); |
|
|
|
|
m_pSynthesizer->setPortamentoGlissando(pMessage[5],nTG); |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]); |
|
|
|
|
m_pSynthesizer->setPortamentoGlissando(pMessage[5], nTG); |
|
|
|
|
break; |
|
|
|
|
case 69: |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); |
|
|
|
|
m_pSynthesizer->setPortamentoTime(pMessage[5],nTG); |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]); |
|
|
|
|
m_pSynthesizer->setPortamentoTime(pMessage[5], nTG); |
|
|
|
|
break; |
|
|
|
|
case 70: |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); |
|
|
|
|
m_pSynthesizer->setModWheelRange(pMessage[5],nTG); |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]); |
|
|
|
|
m_pSynthesizer->setModWheelRange(pMessage[5], nTG); |
|
|
|
|
break; |
|
|
|
|
case 71: |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); |
|
|
|
|
m_pSynthesizer->setModWheelTarget(pMessage[5],nTG); |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]); |
|
|
|
|
m_pSynthesizer->setModWheelTarget(pMessage[5], nTG); |
|
|
|
|
break; |
|
|
|
|
case 72: |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); |
|
|
|
|
m_pSynthesizer->setFootControllerRange(pMessage[5],nTG); |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]); |
|
|
|
|
m_pSynthesizer->setFootControllerRange(pMessage[5], nTG); |
|
|
|
|
break; |
|
|
|
|
case 73: |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); |
|
|
|
|
m_pSynthesizer->setFootControllerTarget(pMessage[5],nTG); |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]); |
|
|
|
|
m_pSynthesizer->setFootControllerTarget(pMessage[5], nTG); |
|
|
|
|
break; |
|
|
|
|
case 74: |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); |
|
|
|
|
m_pSynthesizer->setBreathControllerRange(pMessage[5],nTG); |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]); |
|
|
|
|
m_pSynthesizer->setBreathControllerRange(pMessage[5], nTG); |
|
|
|
|
break; |
|
|
|
|
case 75: |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); |
|
|
|
|
m_pSynthesizer->setBreathControllerTarget(pMessage[5],nTG); |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]); |
|
|
|
|
m_pSynthesizer->setBreathControllerTarget(pMessage[5], nTG); |
|
|
|
|
break; |
|
|
|
|
case 76: |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); |
|
|
|
|
m_pSynthesizer->setAftertouchRange(pMessage[5],nTG); |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]); |
|
|
|
|
m_pSynthesizer->setAftertouchRange(pMessage[5], nTG); |
|
|
|
|
break; |
|
|
|
|
case 77: |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]); |
|
|
|
|
m_pSynthesizer->setAftertouchTarget(pMessage[5],nTG); |
|
|
|
|
LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]); |
|
|
|
|
m_pSynthesizer->setAftertouchTarget(pMessage[5], nTG); |
|
|
|
|
break; |
|
|
|
|
case 100: |
|
|
|
|
// load sysex-data into voice memory
|
|
|
|
|
LOGDBG("One Voice bulk upload"); |
|
|
|
|
m_pSynthesizer->loadVoiceParameters(pMessage,nTG); |
|
|
|
|
m_pSynthesizer->loadVoiceParameters(pMessage, nTG); |
|
|
|
|
break; |
|
|
|
|
case 200: |
|
|
|
|
LOGDBG("Bank bulk upload."); |
|
|
|
|
//TODO: add code for storing a bank bulk upload
|
|
|
|
|
// TODO: add code for storing a bank bulk upload
|
|
|
|
|
LOGNOTE("Currently code for storing a bulk bank upload is missing!"); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
if(sysex_return >= 300 && sysex_return < 500) |
|
|
|
|
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); |
|
|
|
|
switch(pMessage[4] + ((pMessage[3] & 0x03) * 128)) |
|
|
|
|
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); |
|
|
|
|
m_pSynthesizer->notesOff(0, nTG); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else if(sysex_return >= 500 && sysex_return < 600) |
|
|
|
|
else if (sysex_return >= 500 && sysex_return < 600) |
|
|
|
|
{ |
|
|
|
|
LOGDBG("SysEx send voice %u request",sysex_return-500); |
|
|
|
|
SendSystemExclusiveVoice(sysex_return-500, nCable, nTG); |
|
|
|
|
LOGDBG("SysEx send voice %u request", sysex_return - 500); |
|
|
|
|
SendSystemExclusiveVoice(sysex_return - 500, nCable, nTG); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
@ -529,10 +532,9 @@ void CMIDIDevice::SendSystemExclusiveVoice(uint8_t nVoice, const unsigned nCable |
|
|
|
|
TDeviceMap::const_iterator Iterator; |
|
|
|
|
|
|
|
|
|
// send voice dump to all MIDI interfaces
|
|
|
|
|
auto end = s_DeviceMap.end(); |
|
|
|
|
for(Iterator = s_DeviceMap.begin(); Iterator != end; ++Iterator) |
|
|
|
|
for (Iterator = s_DeviceMap.begin(); Iterator != s_DeviceMap.end(); ++Iterator) |
|
|
|
|
{ |
|
|
|
|
Iterator->second->Send (voicedump, sizeof(voicedump)*sizeof(uint8_t)); |
|
|
|
|
Iterator->second->Send(voicedump, sizeof(voicedump) * sizeof(uint8_t)); |
|
|
|
|
// LOGDBG("Send SYSEX voice dump %u to \"%s\"",nVoice,Iterator->first.c_str());
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|