65 |
pRgn = this->pInstrument->GetNextRegion(); |
pRgn = this->pInstrument->GetNextRegion(); |
66 |
} |
} |
67 |
|
|
68 |
|
// initialize modulation system |
69 |
|
ModulationSystem::Initialize(pAudioIO->Samplerate, pAudioIO->FragmentSize); |
70 |
|
|
71 |
// sustain pedal value |
// sustain pedal value |
72 |
PrevHoldCCValue = 0; |
PrevHoldCCValue = 0; |
73 |
SustainPedal = 0; |
SustainPedal = 0; |
76 |
} |
} |
77 |
|
|
78 |
AudioThread::~AudioThread() { |
AudioThread::~AudioThread() { |
79 |
|
ModulationSystem::Close(); |
80 |
if (pCommandQueue) delete pCommandQueue; |
if (pCommandQueue) delete pCommandQueue; |
81 |
if (pVoices) { |
if (pVoices) { |
82 |
for (uint i = 0; i < MAX_AUDIO_VOICES; i++) { |
for (uint i = 0; i < MAX_AUDIO_VOICES; i++) { |
124 |
pVoices[i]->RenderAudio(); |
pVoices[i]->RenderAudio(); |
125 |
if (pVoices[i]->IsActive()) active_voices++; // still active |
if (pVoices[i]->IsActive()) active_voices++; // still active |
126 |
else { // voice reached end, is now inactive |
else { // voice reached end, is now inactive |
127 |
ReleaseVoice(pVoices[i]); // remove voice from the list of active voices |
KillVoice(pVoices[i]); // remove voice from the list of active voices |
128 |
} |
} |
129 |
} |
} |
130 |
} |
} |
246 |
Voice** pVoicePtr = pmidikey->pActiveVoices->first(); |
Voice** pVoicePtr = pmidikey->pActiveVoices->first(); |
247 |
while (pVoicePtr) { |
while (pVoicePtr) { |
248 |
Voice** pVoicePtrNext = pMIDIKeyInfo[MIDIKey].pActiveVoices->next(); |
Voice** pVoicePtrNext = pMIDIKeyInfo[MIDIKey].pActiveVoices->next(); |
249 |
ReleaseVoice(*pVoicePtr); |
(*pVoicePtr)->Release(); |
250 |
pVoicePtr = pVoicePtrNext; |
pVoicePtr = pVoicePtrNext; |
251 |
} |
} |
252 |
} |
} |
253 |
} |
} |
254 |
|
|
255 |
/** |
/** |
256 |
* Releases the voice given with pVoice (no matter if sustain is pressed or |
* Immediately kills the voice given with pVoice (no matter if sustain is |
257 |
* not). This method will e.g. be directly called if a voice went inactive |
* pressed or not) and removes it from the MIDI key's list of active voice. |
258 |
* by itself. If sustain pedal is pressed the method takes care to free |
* This method will e.g. be called if a voice went inactive by itself. If |
259 |
* those sustain informations of the voice. |
* sustain pedal is pressed the method takes care to free those sustain |
260 |
|
* informations of the voice. |
261 |
*/ |
*/ |
262 |
void AudioThread::ReleaseVoice(Voice* pVoice) { |
void AudioThread::KillVoice(Voice* pVoice) { |
263 |
if (pVoice) { |
if (pVoice) { |
264 |
if (pVoice->IsActive()) pVoice->Kill(); //TODO: for now we're rude and just kill the poor, poor voice immediately :), later we add a Release() method to the Voice class and call it here to let the voice go through it's release phase |
if (pVoice->IsActive()) pVoice->Kill(); |
265 |
|
|
266 |
if (pMIDIKeyInfo[pVoice->MIDIKey].Sustained) { |
if (pMIDIKeyInfo[pVoice->MIDIKey].Sustained) { |
267 |
// check if the sustain pointer has to be moved, now that we release the voice |
// check if the sustain pointer has to be moved, now that we kill the voice |
268 |
RTEList<Voice*>::NodeHandle hSustainPtr = pMIDIKeyInfo[pVoice->MIDIKey].hSustainPtr; |
RTEList<Voice*>::NodeHandle hSustainPtr = pMIDIKeyInfo[pVoice->MIDIKey].hSustainPtr; |
269 |
if (hSustainPtr) { |
if (hSustainPtr) { |
270 |
Voice** pVoicePtr = pMIDIKeyInfo[pVoice->MIDIKey].pActiveVoices->set_current(hSustainPtr); |
Voice** pVoicePtr = pMIDIKeyInfo[pVoice->MIDIKey].pActiveVoices->set_current(hSustainPtr); |
316 |
while (pVoicePtr) { |
while (pVoicePtr) { |
317 |
Voice** pVoicePtrNext = pMIDIKeyInfo[*key].pActiveVoices->next(); |
Voice** pVoicePtrNext = pMIDIKeyInfo[*key].pActiveVoices->next(); |
318 |
dmsg(3,("Sustain CC: releasing voice on midi key %d\n", *key)); |
dmsg(3,("Sustain CC: releasing voice on midi key %d\n", *key)); |
319 |
ReleaseVoice(*pVoicePtr); |
(*pVoicePtr)->Release(); |
320 |
pVoicePtr = pVoicePtrNext; |
pVoicePtr = pVoicePtrNext; |
321 |
} |
} |
322 |
} |
} |
323 |
|
SustainedKeyPool->free(pMIDIKeyInfo[*key].pSustainPoolNode); |
324 |
|
pMIDIKeyInfo[*key].pSustainPoolNode = NULL; |
325 |
|
pMIDIKeyInfo[*key].Sustained = false; |
326 |
|
pMIDIKeyInfo[*key].hSustainPtr = NULL; |
327 |
} |
} |
328 |
|
//SustainedKeyPool->empty(); |
329 |
} |
} |
330 |
PrevHoldCCValue = Value; |
PrevHoldCCValue = Value; |
331 |
} |
} |