|
|
|
@ -46,7 +46,7 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt, |
|
|
|
|
m_pSoundDevice (0), |
|
|
|
|
m_bChannelsSwapped (pConfig->GetChannelsSwapped ()), |
|
|
|
|
#ifdef ARM_ALLOW_MULTI_CORE |
|
|
|
|
m_nActiveTGsLog2 (0), |
|
|
|
|
// m_nActiveTGsLog2 (0),
|
|
|
|
|
#endif |
|
|
|
|
m_GetChunkTimer ("GetChunk", |
|
|
|
|
1000000U * pConfig->GetChunkSize ()/2 / pConfig->GetSampleRate ()), |
|
|
|
@ -61,8 +61,12 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt, |
|
|
|
|
m_bLoadPerformanceBankBusy(false) |
|
|
|
|
{ |
|
|
|
|
assert (m_pConfig); |
|
|
|
|
|
|
|
|
|
m_nToneGenerators = m_pConfig->GetToneGenerators(); |
|
|
|
|
m_nPolyphony = m_pConfig->GetPolyphony(); |
|
|
|
|
LOGNOTE("Tone Generators=%d, Polyphony=%d", m_nToneGenerators, m_nPolyphony); |
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < CConfig::ToneGenerators; i++) |
|
|
|
|
for (unsigned i = 0; i < CConfig::AllToneGenerators; i++) |
|
|
|
|
{ |
|
|
|
|
m_nVoiceBankID[i] = 0; |
|
|
|
|
m_nVoiceBankIDMSB[i] = 0; |
|
|
|
@ -93,15 +97,20 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt, |
|
|
|
|
m_nAftertouchTarget[i]=0; |
|
|
|
|
|
|
|
|
|
m_nReverbSend[i] = 0; |
|
|
|
|
m_uchOPMask[i] = 0b111111; // All operators on
|
|
|
|
|
|
|
|
|
|
m_pTG[i] = new CDexedAdapter (CConfig::MaxNotes, pConfig->GetSampleRate ()); |
|
|
|
|
assert (m_pTG[i]); |
|
|
|
|
|
|
|
|
|
m_pTG[i]->setEngineType(pConfig->GetEngineType ()); |
|
|
|
|
m_pTG[i]->activate (); |
|
|
|
|
// Active the required number of active TGs
|
|
|
|
|
if (i<m_nToneGenerators) |
|
|
|
|
{ |
|
|
|
|
m_uchOPMask[i] = 0b111111; // All operators on
|
|
|
|
|
|
|
|
|
|
m_pTG[i] = new CDexedAdapter (m_nPolyphony, pConfig->GetSampleRate ()); |
|
|
|
|
assert (m_pTG[i]); |
|
|
|
|
|
|
|
|
|
m_pTG[i]->setEngineType(pConfig->GetEngineType ()); |
|
|
|
|
m_pTG[i]->activate (); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned nUSBGadgetPin = pConfig->GetUSBGadgetPin(); |
|
|
|
|
bool bUSBGadget = pConfig->GetUSBGadget(); |
|
|
|
|
bool bUSBGadgetMode = pConfig->GetUSBGadgetMode(); |
|
|
|
@ -156,6 +165,11 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt, |
|
|
|
|
// Quad DAC 8-channel mono only an option for RPI 5
|
|
|
|
|
m_bQuadDAC8Chan = pConfig->GetQuadDAC8Chan (); |
|
|
|
|
#endif |
|
|
|
|
if (m_bQuadDAC8Chan && (m_nToneGenerators != 8)) |
|
|
|
|
{ |
|
|
|
|
LOGNOTE("ERROR: Quad DAC Mode is only valid when number of TGs = 8. Defaulting to non-Quad DAC mode,"); |
|
|
|
|
m_bQuadDAC8Chan = false; |
|
|
|
|
} |
|
|
|
|
if (m_bQuadDAC8Chan) { |
|
|
|
|
LOGNOTE ("Configured for Quad DAC 8-channel Mono audio"); |
|
|
|
|
m_pSoundDevice = new CI2SSoundBaseDevice (pInterrupt, pConfig->GetSampleRate (), |
|
|
|
@ -206,11 +220,11 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt, |
|
|
|
|
setMasterVolume(1.0); |
|
|
|
|
|
|
|
|
|
// BEGIN setup tg_mixer
|
|
|
|
|
tg_mixer = new AudioStereoMixer<CConfig::ToneGenerators>(pConfig->GetChunkSize()/2); |
|
|
|
|
tg_mixer = new AudioStereoMixer<CConfig::AllToneGenerators>(pConfig->GetChunkSize()/2); |
|
|
|
|
// END setup tgmixer
|
|
|
|
|
|
|
|
|
|
// BEGIN setup reverb
|
|
|
|
|
reverb_send_mixer = new AudioStereoMixer<CConfig::ToneGenerators>(pConfig->GetChunkSize()/2); |
|
|
|
|
reverb_send_mixer = new AudioStereoMixer<CConfig::AllToneGenerators>(pConfig->GetChunkSize()/2); |
|
|
|
|
reverb = new AudioEffectPlateReverb(pConfig->GetSampleRate()); |
|
|
|
|
SetParameter (ParameterReverbEnable, 1); |
|
|
|
|
SetParameter (ParameterReverbSize, 70); |
|
|
|
@ -261,7 +275,7 @@ bool CMiniDexed::Initialize (void) |
|
|
|
|
LOGNOTE("Program Change: Disabled"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < CConfig::ToneGenerators; i++) |
|
|
|
|
for (unsigned i = 0; i < m_nToneGenerators; i++) |
|
|
|
|
{ |
|
|
|
|
assert (m_pTG[i]); |
|
|
|
|
|
|
|
|
@ -283,7 +297,7 @@ bool CMiniDexed::Initialize (void) |
|
|
|
|
reverb_send_mixer->gain(i,mapfloat(m_nReverbSend[i],0,99,0.0f,1.0f)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
m_PerformanceConfig.Init(); |
|
|
|
|
m_PerformanceConfig.Init(m_nToneGenerators); |
|
|
|
|
if (m_PerformanceConfig.Load ()) |
|
|
|
|
{ |
|
|
|
|
LoadPerformanceParameters();
|
|
|
|
@ -453,12 +467,16 @@ void CMiniDexed::Run (unsigned nCore) |
|
|
|
|
|
|
|
|
|
// process the TGs, assigned to this core (2 or 3)
|
|
|
|
|
|
|
|
|
|
assert (m_nFramesToProcess <= CConfig::MaxChunkSize); |
|
|
|
|
unsigned nTG = CConfig::TGsCore1 + (nCore-2)*CConfig::TGsCore23; |
|
|
|
|
for (unsigned i = 0; i < CConfig::TGsCore23; i++, nTG++) |
|
|
|
|
assert (m_nFramesToProcess <= m_pConfig->MaxChunkSize); |
|
|
|
|
unsigned nTG = m_pConfig->GetTGsCore1() + (nCore-2)*m_pConfig->GetTGsCore23(); |
|
|
|
|
for (unsigned i = 0; i < m_pConfig->GetTGsCore23(); i++, nTG++) |
|
|
|
|
{ |
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_pTG[nTG]->getSamples (m_OutputLevel[nTG],m_nFramesToProcess); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG < m_pConfig->GetToneGenerators()) |
|
|
|
|
{ |
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_pTG[nTG]->getSamples (m_OutputLevel[nTG],m_nFramesToProcess); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -480,7 +498,8 @@ void CMiniDexed::BankSelect (unsigned nBank, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
nBank=constrain((int)nBank,0,16383); |
|
|
|
|
|
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
if (GetSysExFileLoader ()->IsValidBank(nBank)) |
|
|
|
|
{ |
|
|
|
@ -509,7 +528,9 @@ void CMiniDexed::BankSelectMSB (unsigned nBankMSB, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
nBankMSB=constrain((int)nBankMSB,0,127); |
|
|
|
|
|
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
// MIDI Spec 1.0 "BANK SELECT" states:
|
|
|
|
|
// "The transmitter must transmit the MSB and LSB as a pair,
|
|
|
|
|
// and the Program Change must be sent immediately after
|
|
|
|
@ -530,7 +551,9 @@ void CMiniDexed::BankSelectLSB (unsigned nBankLSB, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
nBankLSB=constrain((int)nBankLSB,0,127); |
|
|
|
|
|
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
unsigned nBank = m_nVoiceBankID[nTG]; |
|
|
|
|
unsigned nBankMSB = m_nVoiceBankIDMSB[nTG]; |
|
|
|
|
nBank = (nBankMSB << 7) + nBankLSB; |
|
|
|
@ -578,7 +601,9 @@ void CMiniDexed::ProgramChange (unsigned nProgram, unsigned nTG) |
|
|
|
|
nProgram=constrain((int)nProgram,0,31); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
m_nProgram[nTG] = nProgram; |
|
|
|
|
|
|
|
|
|
uint8_t Buffer[156]; |
|
|
|
@ -617,7 +642,9 @@ void CMiniDexed::SetVolume (unsigned nVolume, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
nVolume=constrain((int)nVolume,0,127); |
|
|
|
|
|
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
m_nVolume[nTG] = nVolume; |
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
@ -630,7 +657,9 @@ void CMiniDexed::SetPan (unsigned nPan, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
nPan=constrain((int)nPan,0,127); |
|
|
|
|
|
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
m_nPan[nTG] = nPan; |
|
|
|
|
|
|
|
|
|
tg_mixer->pan(nTG,mapfloat(nPan,0,127,0.0f,1.0f)); |
|
|
|
@ -643,7 +672,9 @@ void CMiniDexed::SetReverbSend (unsigned nReverbSend, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
nReverbSend=constrain((int)nReverbSend,0,99); |
|
|
|
|
|
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
m_nReverbSend[nTG] = nReverbSend; |
|
|
|
|
|
|
|
|
|
reverb_send_mixer->gain(nTG,mapfloat(nReverbSend,0,99,0.0f,1.0f)); |
|
|
|
@ -655,7 +686,9 @@ void CMiniDexed::SetMasterTune (int nMasterTune, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
nMasterTune=constrain((int)nMasterTune,-99,99); |
|
|
|
|
|
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
m_nMasterTune[nTG] = nMasterTune; |
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
@ -668,7 +701,9 @@ void CMiniDexed::SetCutoff (int nCutoff, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
nCutoff = constrain (nCutoff, 0, 99); |
|
|
|
|
|
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
m_nCutoff[nTG] = nCutoff; |
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
@ -681,7 +716,9 @@ void CMiniDexed::SetResonance (int nResonance, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
nResonance = constrain (nResonance, 0, 99); |
|
|
|
|
|
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
m_nResonance[nTG] = nResonance; |
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
@ -694,7 +731,9 @@ void CMiniDexed::SetResonance (int nResonance, unsigned nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::SetMIDIChannel (uint8_t uchChannel, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (uchChannel < CMIDIDevice::ChannelUnknown); |
|
|
|
|
|
|
|
|
|
m_nMIDIChannel[nTG] = uchChannel; |
|
|
|
@ -713,6 +752,7 @@ void CMiniDexed::SetMIDIChannel (uint8_t uchChannel, unsigned nTG) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef ARM_ALLOW_MULTI_CORE |
|
|
|
|
/* This doesn't appear to be used anywhere...
|
|
|
|
|
unsigned nActiveTGs = 0; |
|
|
|
|
for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++) |
|
|
|
|
{ |
|
|
|
@ -725,6 +765,7 @@ void CMiniDexed::SetMIDIChannel (uint8_t uchChannel, unsigned nTG) |
|
|
|
|
assert (nActiveTGs <= 8); |
|
|
|
|
static const unsigned Log2[] = {0, 0, 1, 2, 2, 3, 3, 3, 3}; |
|
|
|
|
m_nActiveTGsLog2 = Log2[nActiveTGs]; |
|
|
|
|
*/ |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
m_UI.ParameterChanged (); |
|
|
|
@ -732,7 +773,9 @@ void CMiniDexed::SetMIDIChannel (uint8_t uchChannel, unsigned nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::keyup (int16_t pitch, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
|
|
|
|
|
pitch = ApplyNoteLimits (pitch, nTG); |
|
|
|
@ -744,7 +787,9 @@ void CMiniDexed::keyup (int16_t pitch, unsigned nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::keydown (int16_t pitch, uint8_t velocity, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
|
|
|
|
|
pitch = ApplyNoteLimits (pitch, nTG); |
|
|
|
@ -756,7 +801,8 @@ void CMiniDexed::keydown (int16_t pitch, uint8_t velocity, unsigned nTG) |
|
|
|
|
|
|
|
|
|
int16_t CMiniDexed::ApplyNoteLimits (int16_t pitch, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return -1; // Not an active TG
|
|
|
|
|
|
|
|
|
|
if ( pitch < (int16_t) m_nNoteLimitLow[nTG] |
|
|
|
|
|| pitch > (int16_t) m_nNoteLimitHigh[nTG]) |
|
|
|
@ -777,14 +823,18 @@ int16_t CMiniDexed::ApplyNoteLimits (int16_t pitch, unsigned nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setSustain(bool sustain, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_pTG[nTG]->setSustain (sustain); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CMiniDexed::panic(uint8_t value, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
if (value == 0) { |
|
|
|
|
m_pTG[nTG]->panic (); |
|
|
|
@ -793,7 +843,9 @@ void CMiniDexed::panic(uint8_t value, unsigned nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::notesOff(uint8_t value, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
if (value == 0) { |
|
|
|
|
m_pTG[nTG]->notesOff (); |
|
|
|
@ -802,7 +854,9 @@ void CMiniDexed::notesOff(uint8_t value, unsigned nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setModWheel (uint8_t value, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_pTG[nTG]->setModWheel (value); |
|
|
|
|
} |
|
|
|
@ -810,35 +864,45 @@ void CMiniDexed::setModWheel (uint8_t value, unsigned nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setFootController (uint8_t value, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_pTG[nTG]->setFootController (value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setBreathController (uint8_t value, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_pTG[nTG]->setBreathController (value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setAftertouch (uint8_t value, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_pTG[nTG]->setAftertouch (value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setPitchbend (int16_t value, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_pTG[nTG]->setPitchbend (value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CMiniDexed::ControllersRefresh (unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_pTG[nTG]->ControllersRefresh (); |
|
|
|
|
} |
|
|
|
@ -853,7 +917,7 @@ void CMiniDexed::SetParameter (TParameter Parameter, int nValue) |
|
|
|
|
switch (Parameter) |
|
|
|
|
{ |
|
|
|
|
case ParameterCompressorEnable: |
|
|
|
|
for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++) |
|
|
|
|
for (unsigned nTG = 0; nTG < m_nToneGenerators; nTG++) |
|
|
|
|
{ |
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_pTG[nTG]->setCompressor (!!nValue); |
|
|
|
@ -931,7 +995,8 @@ int CMiniDexed::GetParameter (TParameter Parameter) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::SetTGParameter (TTGParameter Parameter, int nValue, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
switch (Parameter) |
|
|
|
|
{ |
|
|
|
@ -986,7 +1051,7 @@ void CMiniDexed::SetTGParameter (TTGParameter Parameter, int nValue, unsigned nT |
|
|
|
|
|
|
|
|
|
int CMiniDexed::GetTGParameter (TTGParameter Parameter, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
|
|
|
|
|
switch (Parameter) |
|
|
|
|
{ |
|
|
|
@ -1037,7 +1102,9 @@ int CMiniDexed::GetTGParameter (TTGParameter Parameter, unsigned nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::SetVoiceParameter (uint8_t uchOffset, uint8_t uchValue, unsigned nOP, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
assert (nOP <= 6); |
|
|
|
|
|
|
|
|
@ -1070,7 +1137,9 @@ void CMiniDexed::SetVoiceParameter (uint8_t uchOffset, uint8_t uchValue, unsigne |
|
|
|
|
|
|
|
|
|
uint8_t CMiniDexed::GetVoiceParameter (uint8_t uchOffset, unsigned nOP, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return 0; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
assert (nOP <= 6); |
|
|
|
|
|
|
|
|
@ -1094,13 +1163,15 @@ std::string CMiniDexed::GetVoiceName (unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
char VoiceName[11]; |
|
|
|
|
memset (VoiceName, 0, sizeof VoiceName); |
|
|
|
|
VoiceName[0] = 32; // space
|
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
|
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_pTG[nTG]->setName (VoiceName); |
|
|
|
|
|
|
|
|
|
if (nTG < m_nToneGenerators) |
|
|
|
|
{ |
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_pTG[nTG]->setName (VoiceName); |
|
|
|
|
} |
|
|
|
|
std::string Result (VoiceName); |
|
|
|
|
|
|
|
|
|
return Result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1142,6 +1213,7 @@ void CMiniDexed::ProcessSound (void) |
|
|
|
|
void CMiniDexed::ProcessSound (void) |
|
|
|
|
{ |
|
|
|
|
assert (m_pSoundDevice); |
|
|
|
|
assert (m_pConfig); |
|
|
|
|
|
|
|
|
|
unsigned nFrames = m_nQueueSizeFrames - m_pSoundDevice->GetQueueFramesAvail (); |
|
|
|
|
if (nFrames >= m_nQueueSizeFrames/2) |
|
|
|
@ -1162,7 +1234,7 @@ void CMiniDexed::ProcessSound (void) |
|
|
|
|
|
|
|
|
|
// process the TGs assigned to core 1
|
|
|
|
|
assert (nFrames <= CConfig::MaxChunkSize); |
|
|
|
|
for (unsigned i = 0; i < CConfig::TGsCore1; i++) |
|
|
|
|
for (unsigned i = 0; i < m_pConfig->GetTGsCore1(); i++) |
|
|
|
|
{ |
|
|
|
|
assert (m_pTG[i]); |
|
|
|
|
m_pTG[i]->getSamples (m_OutputLevel[i], nFrames); |
|
|
|
@ -1181,9 +1253,10 @@ void CMiniDexed::ProcessSound (void) |
|
|
|
|
// Audio signal path after tone generators starts here
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
assert (CConfig::ToneGenerators == 8); |
|
|
|
|
|
|
|
|
|
if (m_bQuadDAC8Chan) { |
|
|
|
|
// This is only supported when there are 8 TGs
|
|
|
|
|
assert (m_nToneGenerators == 8); |
|
|
|
|
|
|
|
|
|
// No mixing is performed by MiniDexed, sound is output in 8 channels.
|
|
|
|
|
// Note: one TG per audio channel; output=mono; no processing.
|
|
|
|
|
const int Channels = 8; // One TG per channel
|
|
|
|
@ -1233,7 +1306,7 @@ void CMiniDexed::ProcessSound (void) |
|
|
|
|
|
|
|
|
|
if(nMasterVolume > 0.0) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t i = 0; i < CConfig::ToneGenerators; i++) |
|
|
|
|
for (uint8_t i = 0; i < m_nToneGenerators; i++) |
|
|
|
|
{ |
|
|
|
|
tg_mixer->doAddMix(i,m_OutputLevel[i]); |
|
|
|
|
reverb_send_mixer->doAddMix(i,m_OutputLevel[i]); |
|
|
|
@ -1358,7 +1431,7 @@ bool CMiniDexed::SavePerformance (bool bSaveAsDeault) |
|
|
|
|
|
|
|
|
|
bool CMiniDexed::DoSavePerformance (void) |
|
|
|
|
{ |
|
|
|
|
for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++) |
|
|
|
|
for (unsigned nTG = 0; nTG < CConfig::AllToneGenerators; nTG++) |
|
|
|
|
{ |
|
|
|
|
m_PerformanceConfig.SetBankNumber (m_nVoiceBankID[nTG], nTG); |
|
|
|
|
m_PerformanceConfig.SetVoiceNumber (m_nProgram[nTG], nTG); |
|
|
|
@ -1377,8 +1450,14 @@ bool CMiniDexed::DoSavePerformance (void) |
|
|
|
|
m_PerformanceConfig.SetNoteLimitLow (m_nNoteLimitLow[nTG], nTG); |
|
|
|
|
m_PerformanceConfig.SetNoteLimitHigh (m_nNoteLimitHigh[nTG], nTG); |
|
|
|
|
m_PerformanceConfig.SetNoteShift (m_nNoteShift[nTG], nTG); |
|
|
|
|
m_pTG[nTG]->getVoiceData(m_nRawVoiceData);
|
|
|
|
|
m_PerformanceConfig.SetVoiceDataToTxt (m_nRawVoiceData, nTG);
|
|
|
|
|
if (nTG < m_pConfig->GetToneGenerators()) |
|
|
|
|
{ |
|
|
|
|
m_pTG[nTG]->getVoiceData(m_nRawVoiceData); |
|
|
|
|
} else { |
|
|
|
|
// Not an active TG so provide default voice by asking for an invalid voice ID.
|
|
|
|
|
m_SysExFileLoader.GetVoice(CSysExFileLoader::MaxVoiceBankID, CSysExFileLoader::VoicesPerBank+1, m_nRawVoiceData); |
|
|
|
|
} |
|
|
|
|
m_PerformanceConfig.SetVoiceDataToTxt (m_nRawVoiceData, nTG);
|
|
|
|
|
m_PerformanceConfig.SetMonoMode (m_bMonoMode[nTG], nTG);
|
|
|
|
|
|
|
|
|
|
m_PerformanceConfig.SetModulationWheelRange (m_nModulationWheelRange[nTG], nTG); |
|
|
|
@ -1412,7 +1491,9 @@ bool CMiniDexed::DoSavePerformance (void) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setMonoMode(uint8_t mono, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_bMonoMode[nTG]= mono != 0;
|
|
|
|
|
m_pTG[nTG]->setMonoMode(constrain(mono, 0, 1)); |
|
|
|
@ -1423,7 +1504,9 @@ void CMiniDexed::setMonoMode(uint8_t mono, uint8_t nTG) |
|
|
|
|
void CMiniDexed::setPitchbendRange(uint8_t range, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
range = constrain (range, 0, 12); |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_nPitchBendRange[nTG] = range; |
|
|
|
|
|
|
|
|
@ -1435,7 +1518,9 @@ void CMiniDexed::setPitchbendRange(uint8_t range, uint8_t nTG) |
|
|
|
|
void CMiniDexed::setPitchbendStep(uint8_t step, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
step= constrain (step, 0, 12); |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_nPitchBendStep[nTG] = step; |
|
|
|
|
|
|
|
|
@ -1448,7 +1533,9 @@ void CMiniDexed::setPortamentoMode(uint8_t mode, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
mode= constrain (mode, 0, 1); |
|
|
|
|
|
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_nPortamentoMode[nTG] = mode; |
|
|
|
|
|
|
|
|
@ -1460,7 +1547,9 @@ void CMiniDexed::setPortamentoMode(uint8_t mode, uint8_t nTG) |
|
|
|
|
void CMiniDexed::setPortamentoGlissando(uint8_t glissando, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
glissando = constrain (glissando, 0, 1); |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_nPortamentoGlissando[nTG] = glissando; |
|
|
|
|
|
|
|
|
@ -1472,7 +1561,9 @@ void CMiniDexed::setPortamentoGlissando(uint8_t glissando, uint8_t nTG) |
|
|
|
|
void CMiniDexed::setPortamentoTime(uint8_t time, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
time = constrain (time, 0, 99); |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_nPortamentoTime[nTG] = time; |
|
|
|
|
|
|
|
|
@ -1483,7 +1574,9 @@ void CMiniDexed::setPortamentoTime(uint8_t time, uint8_t nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setModWheelRange(uint8_t range, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
|
|
|
|
|
m_nModulationWheelRange[nTG] = range; |
|
|
|
@ -1496,7 +1589,9 @@ void CMiniDexed::setModWheelRange(uint8_t range, uint8_t nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setModWheelTarget(uint8_t target, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
|
|
|
|
|
m_nModulationWheelTarget[nTG] = target; |
|
|
|
@ -1508,7 +1603,9 @@ void CMiniDexed::setModWheelTarget(uint8_t target, uint8_t nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setFootControllerRange(uint8_t range, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
|
|
|
|
|
m_nFootControlRange[nTG]=range; |
|
|
|
@ -1521,7 +1618,9 @@ void CMiniDexed::setFootControllerRange(uint8_t range, uint8_t nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setFootControllerTarget(uint8_t target, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
|
|
|
|
|
m_nFootControlTarget[nTG] = target; |
|
|
|
@ -1533,7 +1632,9 @@ void CMiniDexed::setFootControllerTarget(uint8_t target, uint8_t nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setBreathControllerRange(uint8_t range, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
|
|
|
|
|
m_nBreathControlRange[nTG]=range; |
|
|
|
@ -1546,7 +1647,9 @@ void CMiniDexed::setBreathControllerRange(uint8_t range, uint8_t nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setBreathControllerTarget(uint8_t target, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
|
|
|
|
|
m_nBreathControlTarget[nTG]=target; |
|
|
|
@ -1558,7 +1661,9 @@ void CMiniDexed::setBreathControllerTarget(uint8_t target, uint8_t nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setAftertouchRange(uint8_t range, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
|
|
|
|
|
m_nAftertouchRange[nTG]=range; |
|
|
|
@ -1571,7 +1676,9 @@ void CMiniDexed::setAftertouchRange(uint8_t range, uint8_t nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setAftertouchTarget(uint8_t target, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
|
|
|
|
|
m_nAftertouchTarget[nTG]=target; |
|
|
|
@ -1583,7 +1690,9 @@ void CMiniDexed::setAftertouchTarget(uint8_t target, uint8_t nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::loadVoiceParameters(const uint8_t* data, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
|
|
|
|
|
uint8_t voice[161]; |
|
|
|
@ -1604,7 +1713,9 @@ void CMiniDexed::loadVoiceParameters(const uint8_t* data, uint8_t nTG) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::setVoiceDataElement(uint8_t data, uint8_t number, uint8_t nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
|
|
|
|
|
m_pTG[nTG]->setVoiceDataElement(constrain(data, 0, 155),constrain(number, 0, 99)); |
|
|
|
@ -1614,7 +1725,9 @@ 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 (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return 0; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
|
|
|
|
|
return(m_pTG[nTG]->checkSystemExclusive(pMessage, nLength)); |
|
|
|
@ -1625,10 +1738,17 @@ 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); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG < m_nToneGenerators) |
|
|
|
|
{ |
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
m_pTG[nTG]->getVoiceData(data); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
// Not an active TG so grab a default voice
|
|
|
|
|
m_SysExFileLoader.GetVoice(CSysExFileLoader::MaxVoiceBankID, CSysExFileLoader::VoicesPerBank+1, data); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
dest[0] = 0xF0; // SysEx start
|
|
|
|
|
dest[1] = 0x43; // ID=Yamaha
|
|
|
|
@ -1791,7 +1911,7 @@ bool CMiniDexed::DoSavePerformanceNewFile (void) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::LoadPerformanceParameters(void) |
|
|
|
|
{ |
|
|
|
|
for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++) |
|
|
|
|
for (unsigned nTG = 0; nTG < CConfig::AllToneGenerators; nTG++) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
BankSelect (m_PerformanceConfig.GetBankNumber (nTG), nTG); |
|
|
|
@ -1865,7 +1985,9 @@ bool CMiniDexed::IsValidPerformanceBank(unsigned nBankID) |
|
|
|
|
|
|
|
|
|
void CMiniDexed::SetVoiceName (std::string VoiceName, unsigned nTG) |
|
|
|
|
{ |
|
|
|
|
assert (nTG < CConfig::ToneGenerators); |
|
|
|
|
assert (nTG < CConfig::AllToneGenerators); |
|
|
|
|
if (nTG >= m_nToneGenerators) return; // Not an active TG
|
|
|
|
|
|
|
|
|
|
assert (m_pTG[nTG]); |
|
|
|
|
char Name[11]; |
|
|
|
|
strncpy(Name, VoiceName.c_str(),10); |
|
|
|
|