3 |
* LinuxSampler - modular, streaming capable sampler * |
* LinuxSampler - modular, streaming capable sampler * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck * |
* Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck * |
6 |
* Copyright (C) 2005-2009 Christian Schoenebeck * |
* Copyright (C) 2005-2008 Christian Schoenebeck * |
7 |
* Copyright (C) 2009 Grigor Iliev * |
* Copyright (C) 2009-2010 Christian Schoenebeck and Grigor Iliev * |
8 |
* * |
* * |
9 |
* This program is free software; you can redistribute it and/or modify * |
* This program is free software; you can redistribute it and/or modify * |
10 |
* it under the terms of the GNU General Public License as published by * |
* it under the terms of the GNU General Public License as published by * |
299 |
// lower minimum release time |
// lower minimum release time |
300 |
const float minReleaseTime = (float) MaxSamplesPerCycle / (float) SampleRate; |
const float minReleaseTime = (float) MaxSamplesPerCycle / (float) SampleRate; |
301 |
for (VoiceIterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) { |
for (VoiceIterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) { |
302 |
iterVoice->EG1.CalculateFadeOutCoeff(minReleaseTime, SampleRate); |
iterVoice->pEG1->CalculateFadeOutCoeff(minReleaseTime, SampleRate); |
303 |
} |
} |
304 |
pVoicePool->clear(); |
pVoicePool->clear(); |
305 |
} |
} |
564 |
int MinFadeOutSamples; ///< The number of samples needed to make an instant fade out (e.g. for voice stealing) without leading to clicks. |
int MinFadeOutSamples; ///< The number of samples needed to make an instant fade out (e.g. for voice stealing) without leading to clicks. |
565 |
D* pDiskThread; |
D* pDiskThread; |
566 |
|
|
|
int VoiceSpawnsLeft; ///< We only allow CONFIG_MAX_VOICES voices to be spawned per audio fragment, we use this variable to ensure this limit. |
|
567 |
int ActiveVoiceCountTemp; ///< number of currently active voices (for internal usage, will be used for incrementation) |
int ActiveVoiceCountTemp; ///< number of currently active voices (for internal usage, will be used for incrementation) |
568 |
VoiceIterator itLastStolenVoice; ///< Only for voice stealing: points to the last voice which was theft in current audio fragment, NULL otherwise. |
VoiceIterator itLastStolenVoice; ///< Only for voice stealing: points to the last voice which was theft in current audio fragment, NULL otherwise. |
569 |
RTList<uint>::Iterator iuiLastStolenKey; ///< Only for voice stealing: key number of last key on which the last voice was theft in current audio fragment, NULL otherwise. |
RTList<uint>::Iterator iuiLastStolenKey; ///< Only for voice stealing: key number of last key on which the last voice was theft in current audio fragment, NULL otherwise. |
1064 |
VoiceIterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first(); |
VoiceIterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first(); |
1065 |
VoiceIterator end = pOtherKey->pActiveVoices->end(); |
VoiceIterator end = pOtherKey->pActiveVoices->end(); |
1066 |
for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) { |
for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) { |
1067 |
if (itVoiceToBeKilled->Type != Voice::type_release_trigger) |
if (!(itVoiceToBeKilled->Type & Voice::type_release_trigger)) |
1068 |
itVoiceToBeKilled->Kill(itNoteOnEventOnKeyList); |
itVoiceToBeKilled->Kill(itNoteOnEventOnKeyList); |
1069 |
} |
} |
1070 |
} |
} |
1096 |
pKey->pEvents->free(itNoteOnEventOnKeyList); |
pKey->pEvents->free(itNoteOnEventOnKeyList); |
1097 |
|
|
1098 |
if (!pChannel->SoloMode || pChannel->PortamentoPos < 0.0f) pChannel->PortamentoPos = (float) key; |
if (!pChannel->SoloMode || pChannel->PortamentoPos < 0.0f) pChannel->PortamentoPos = (float) key; |
1099 |
pKey->RoundRobinIndex++; |
if (pKey->pRoundRobinIndex) { |
1100 |
|
(*pKey->pRoundRobinIndex)++; // counter specific for the key or region |
1101 |
|
pChannel->RoundRobinIndex++; // common counter for the channel |
1102 |
|
} |
1103 |
pChannel->listeners.PostProcessNoteOn(key, vel); |
pChannel->listeners.PostProcessNoteOn(key, vel); |
1104 |
} |
} |
1105 |
|
|
1201 |
VoiceIterator itVoiceToBeKilled = pKey->pActiveVoices->first(); |
VoiceIterator itVoiceToBeKilled = pKey->pActiveVoices->first(); |
1202 |
VoiceIterator end = pKey->pActiveVoices->end(); |
VoiceIterator end = pKey->pActiveVoices->end(); |
1203 |
for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) { |
for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) { |
1204 |
if (itVoiceToBeKilled->Type != Voice::type_release_trigger) |
if (!(itVoiceToBeKilled->Type & Voice::type_release_trigger)) |
1205 |
itVoiceToBeKilled->Kill(itNoteOffEventOnKeyList); |
itVoiceToBeKilled->Kill(itNoteOffEventOnKeyList); |
1206 |
} |
} |
1207 |
} |
} |
1306 |
bool HandleKeyGroupConflicts |
bool HandleKeyGroupConflicts |
1307 |
) = 0; |
) = 0; |
1308 |
|
|
1309 |
|
virtual int GetMinFadeOutSamples() { return MinFadeOutSamples; } |
1310 |
|
|
1311 |
|
int InitNewVoice ( |
1312 |
|
EngineChannelBase<V, R, I>* pChannel, |
1313 |
|
R* pRegion, |
1314 |
|
Pool<Event>::Iterator& itNoteOnEvent, |
1315 |
|
Voice::type_t VoiceType, |
1316 |
|
int iLayer, |
1317 |
|
int iKeyGroup, |
1318 |
|
bool ReleaseTriggerVoice, |
1319 |
|
bool VoiceStealing, |
1320 |
|
typename Pool<V>::Iterator& itNewVoice |
1321 |
|
) { |
1322 |
|
int key = itNoteOnEvent->Param.Note.Key; |
1323 |
|
typename MidiKeyboardManager<V>::MidiKey* pKey = &pChannel->pMIDIKeyInfo[key]; |
1324 |
|
if (itNewVoice) { |
1325 |
|
// launch the new voice |
1326 |
|
if (itNewVoice->Trigger(pChannel, itNoteOnEvent, pChannel->Pitch, pRegion, VoiceType, iKeyGroup) < 0) { |
1327 |
|
dmsg(4,("Voice not triggered\n")); |
1328 |
|
pKey->pActiveVoices->free(itNewVoice); |
1329 |
|
} |
1330 |
|
else { // on success |
1331 |
|
--VoiceSpawnsLeft; |
1332 |
|
if (!pKey->Active) { // mark as active key |
1333 |
|
pKey->Active = true; |
1334 |
|
pKey->itSelf = pChannel->pActiveKeys->allocAppend(); |
1335 |
|
*pKey->itSelf = itNoteOnEvent->Param.Note.Key; |
1336 |
|
} |
1337 |
|
if (itNewVoice->Type & Voice::type_release_trigger_required) pKey->ReleaseTrigger = true; // mark key for the need of release triggered voice(s) |
1338 |
|
return 0; // success |
1339 |
|
} |
1340 |
|
} |
1341 |
|
else if (VoiceStealing) { |
1342 |
|
// try to steal one voice |
1343 |
|
int result = StealVoice(pChannel, itNoteOnEvent); |
1344 |
|
if (!result) { // voice stolen successfully |
1345 |
|
// put note-on event into voice-stealing queue, so it will be reprocessed after killed voice died |
1346 |
|
RTList<Event>::Iterator itStealEvent = pVoiceStealingQueue->allocAppend(); |
1347 |
|
if (itStealEvent) { |
1348 |
|
*itStealEvent = *itNoteOnEvent; // copy event |
1349 |
|
itStealEvent->Param.Note.Layer = iLayer; |
1350 |
|
itStealEvent->Param.Note.ReleaseTrigger = ReleaseTriggerVoice; |
1351 |
|
pKey->VoiceTheftsQueued++; |
1352 |
|
} |
1353 |
|
else dmsg(1,("Voice stealing queue full!\n")); |
1354 |
|
} |
1355 |
|
} |
1356 |
|
|
1357 |
|
return -1; |
1358 |
|
} |
1359 |
|
|
1360 |
private: |
private: |
1361 |
Pool<V>* pVoicePool; ///< Contains all voices that can be activated. |
Pool<V>* pVoicePool; ///< Contains all voices that can be activated. |
1362 |
Pool<RR*> SuspendedRegions; |
Pool<RR*> SuspendedRegions; |