414 |
ActiveVoiceCount = ActiveVoiceCountTemp; |
ActiveVoiceCount = ActiveVoiceCountTemp; |
415 |
if (ActiveVoiceCount > ActiveVoiceCountMax) ActiveVoiceCountMax = ActiveVoiceCount; |
if (ActiveVoiceCount > ActiveVoiceCountMax) ActiveVoiceCountMax = ActiveVoiceCount; |
416 |
|
|
417 |
|
FrameTime += Samples; |
418 |
|
|
419 |
return 0; |
return 0; |
420 |
} |
} |
421 |
|
|
542 |
++iuiKey; |
++iuiKey; |
543 |
if (pKey->pActiveVoices->isEmpty()) FreeKey(pEngineChannel, pKey); |
if (pKey->pActiveVoices->isEmpty()) FreeKey(pEngineChannel, pKey); |
544 |
#if CONFIG_DEVMODE |
#if CONFIG_DEVMODE |
545 |
else { // FIXME: should be removed before the final release (purpose: just a sanity check for debugging) |
else { // just a sanity check for debugging |
546 |
RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first(); |
RTList<Voice>::Iterator itVoice = pKey->pActiveVoices->first(); |
547 |
RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end(); |
RTList<Voice>::Iterator itVoicesEnd = pKey->pActiveVoices->end(); |
548 |
for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key |
for (; itVoice != itVoicesEnd; ++itVoice) { // iterate through all voices on this key |
612 |
midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[key]; |
midi_key_info_t* pKey = &pEngineChannel->pMIDIKeyInfo[key]; |
613 |
|
|
614 |
pKey->KeyPressed = true; // the MIDI key was now pressed down |
pKey->KeyPressed = true; // the MIDI key was now pressed down |
615 |
|
pKey->Velocity = itNoteOnEvent->Param.Note.Velocity; |
616 |
|
pKey->NoteOnTime = FrameTime + itNoteOnEvent->FragmentPos(); // will be used to calculate note length |
617 |
|
|
618 |
// cancel release process of voices on this key if needed |
// cancel release process of voices on this key if needed |
619 |
if (pKey->Active && !pEngineChannel->SustainPedal) { |
if (pKey->Active && !pEngineChannel->SustainPedal) { |
674 |
::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOffEventOnKeyList->Param.Note.Key); |
::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(itNoteOffEventOnKeyList->Param.Note.Key); |
675 |
if (pRegion) { |
if (pRegion) { |
676 |
int voicesRequired = pRegion->Layers; |
int voicesRequired = pRegion->Layers; |
677 |
|
|
678 |
|
// MIDI note-on velocity is used instead of note-off velocity |
679 |
|
itNoteOffEventOnKeyList->Param.Note.Velocity = pKey->Velocity; |
680 |
|
|
681 |
// now launch the required amount of voices |
// now launch the required amount of voices |
682 |
for (int i = 0; i < voicesRequired; i++) |
for (int i = 0; i < voicesRequired; i++) |
683 |
LaunchVoice(pEngineChannel, itNoteOffEventOnKeyList, i, true, false); //FIXME: for the moment we don't perform voice stealing for release triggered samples |
LaunchVoice(pEngineChannel, itNoteOffEventOnKeyList, i, true, false); //FIXME: for the moment we don't perform voice stealing for release triggered samples |
801 |
|
|
802 |
// try to pick the oldest voice on the key where the new |
// try to pick the oldest voice on the key where the new |
803 |
// voice should be spawned, if there is no voice on that |
// voice should be spawned, if there is no voice on that |
804 |
// key, or no voice left to kill there, then procceed with |
// key, or no voice left to kill, then procceed with |
805 |
// 'oldestkey' algorithm |
// 'oldestkey' algorithm |
806 |
case voice_steal_algo_oldestvoiceonkey: { |
case voice_steal_algo_oldestvoiceonkey: { |
|
#if 0 // FIXME: broken |
|
807 |
midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[itNoteOnEvent->Param.Note.Key]; |
midi_key_info_t* pSelectedKey = &pEngineChannel->pMIDIKeyInfo[itNoteOnEvent->Param.Note.Key]; |
808 |
if (this->itLastStolenVoice) { |
itSelectedVoice = pSelectedKey->pActiveVoices->first(); |
809 |
itSelectedVoice = this->itLastStolenVoice; |
// proceed iterating if voice was created in this fragment cycle |
810 |
++itSelectedVoice; |
while (itSelectedVoice && !itSelectedVoice->hasRendered()) ++itSelectedVoice; |
811 |
} |
// if we haven't found a voice then proceed with algorithm 'oldestkey' |
812 |
else { // no voice stolen in this audio fragment cycle yet |
if (itSelectedVoice && itSelectedVoice->hasRendered()) break; |
|
itSelectedVoice = pSelectedKey->pActiveVoices->first(); |
|
|
} |
|
|
if (itSelectedVoice) { |
|
|
iuiSelectedKey = pSelectedKey->itSelf; |
|
|
break; // selection succeeded |
|
|
} |
|
|
#endif |
|
813 |
} // no break - intentional ! |
} // no break - intentional ! |
814 |
|
|
815 |
// try to pick the oldest voice on the oldest active key |
// try to pick the oldest voice on the oldest active key |
816 |
|
// from the same engine channel |
817 |
// (caution: must stay after 'oldestvoiceonkey' algorithm !) |
// (caution: must stay after 'oldestvoiceonkey' algorithm !) |
818 |
case voice_steal_algo_oldestkey: { |
case voice_steal_algo_oldestkey: { |
819 |
if (this->itLastStolenVoice) { |
if (this->itLastStolenVoice) { |
840 |
} |
} |
841 |
} |
} |
842 |
|
|
843 |
// steal oldest voice on the oldest key from this or any other engine channel |
// if we couldn't steal a voice from the same engine channel then |
844 |
|
// steal oldest voice on the oldest key from any other engine channel |
845 |
if (!itSelectedVoice) { |
if (!itSelectedVoice) { |
846 |
EngineChannel* pSelectedChannel = (pLastStolenChannel) ? pLastStolenChannel : pEngineChannel; |
EngineChannel* pSelectedChannel = (pLastStolenChannel) ? pLastStolenChannel : pEngineChannel; |
847 |
int iChannelIndex = pSelectedChannel->iEngineIndexSelf; |
int iChannelIndex = pSelectedChannel->iEngineIndexSelf; |
859 |
} |
} |
860 |
} |
} |
861 |
|
|
862 |
//FIXME: can be removed, just a sanity check for debugging |
#if CONFIG_DEVMODE |
863 |
if (!itSelectedVoice->IsActive()) { |
if (!itSelectedVoice->IsActive()) { |
864 |
dmsg(1,("gig::Engine: ERROR, tried to steal a voice which was not active !!!\n")); |
dmsg(1,("gig::Engine: ERROR, tried to steal a voice which was not active !!!\n")); |
865 |
return -1; |
return -1; |
866 |
} |
} |
867 |
|
#endif // CONFIG_DEVMODE |
868 |
|
|
869 |
// now kill the selected voice |
// now kill the selected voice |
870 |
itSelectedVoice->Kill(itNoteOnEvent); |
itSelectedVoice->Kill(itNoteOnEvent); |
1057 |
if (reader.read(&scale_tunes[0], 12) != 12) goto free_sysex_data; |
if (reader.read(&scale_tunes[0], 12) != 12) goto free_sysex_data; |
1058 |
uint8_t checksum; |
uint8_t checksum; |
1059 |
if (!reader.pop(&checksum)) goto free_sysex_data; |
if (!reader.pop(&checksum)) goto free_sysex_data; |
1060 |
// some are not sending a GS checksum, so we ignore it for now |
#if CONFIG_ASSERT_GS_SYSEX_CHECKSUM |
1061 |
//if (GSCheckSum(checksum_reader, 12)) goto free_sysex_data; |
if (GSCheckSum(checksum_reader, 12)) goto free_sysex_data; |
1062 |
|
#endif // CONFIG_ASSERT_GS_SYSEX_CHECKSUM |
1063 |
for (int i = 0; i < 12; i++) scale_tunes[i] -= 64; |
for (int i = 0; i < 12; i++) scale_tunes[i] -= 64; |
1064 |
AdjustScale((int8_t*) scale_tunes); |
AdjustScale((int8_t*) scale_tunes); |
1065 |
dmsg(3,("\t\t\tNew scale applied.\n")); |
dmsg(3,("\t\t\tNew scale applied.\n")); |
1203 |
} |
} |
1204 |
|
|
1205 |
String Engine::Version() { |
String Engine::Version() { |
1206 |
String s = "$Revision: 1.37 $"; |
String s = "$Revision: 1.40 $"; |
1207 |
return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword |
return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword |
1208 |
} |
} |
1209 |
|
|