--- linuxsampler/trunk/src/engines/gig/Voice.cpp 2016/10/19 12:28:40 3017 +++ linuxsampler/trunk/src/engines/gig/Voice.cpp 2019/08/23 11:44:00 3561 @@ -4,7 +4,8 @@ * * * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * * Copyright (C) 2005 - 2008 Christian Schoenebeck * - * Copyright (C) 2009 - 2015 Christian Schoenebeck and Grigor Iliev * + * Copyright (C) 2009 Christian Schoenebeck and Grigor Iliev * + * Copyright (C) 2010 - 2017 Christian Schoenebeck and Andreas Persson * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -58,7 +59,7 @@ si.ChannelCount = pSample->Channels; si.FrameSize = pSample->FrameSize; si.BitDepth = pSample->BitDepth; - si.TotalFrameCount = pSample->SamplesTotal; + si.TotalFrameCount = (uint)pSample->SamplesTotal; si.HasLoops = pRegion->SampleLoops; si.LoopStart = (si.HasLoops) ? pRegion->pSampleLoops[0].LoopStart : 0; @@ -278,7 +279,19 @@ pRegion->LFO1ControlDepth, pRegion->LFO1FlipPhase, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE); - pLFO1->update(pLFO1->ExtController ? GetGigEngineChannel()->ControllerTable[pLFO1->ExtController] : 0); + pLFO1->updateByMIDICtrlValue(pLFO1->ExtController ? GetGigEngineChannel()->ControllerTable[pLFO1->ExtController] : 0); + pLFO1->setScriptDepthFactor( + pNote->Override.AmpLFODepth.Value, + pNote->Override.AmpLFODepth.Final + ); + if (pNote->Override.AmpLFOFreq.isFinal()) + pLFO1->setScriptFrequencyFinal( + pNote->Override.AmpLFOFreq.Value, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE + ); + else + pLFO1->setScriptFrequencyFactor( + pNote->Override.AmpLFOFreq.Value, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE + ); } } @@ -322,7 +335,15 @@ pRegion->LFO2ControlDepth, pRegion->LFO2FlipPhase, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE); - pLFO2->update(pLFO2->ExtController ? GetGigEngineChannel()->ControllerTable[pLFO2->ExtController] : 0); + pLFO2->updateByMIDICtrlValue(pLFO2->ExtController ? GetGigEngineChannel()->ControllerTable[pLFO2->ExtController] : 0); + pLFO2->setScriptDepthFactor( + pNote->Override.CutoffLFODepth.Value, + pNote->Override.CutoffLFODepth.Final + ); + if (pNote->Override.CutoffLFOFreq.isFinal()) + pLFO2->setScriptFrequencyFinal(pNote->Override.CutoffLFOFreq.Value, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE); + else + pLFO2->setScriptFrequencyFactor(pNote->Override.CutoffLFOFreq.Value, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE); } } @@ -366,7 +387,15 @@ pRegion->LFO3ControlDepth, false, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE); - pLFO3->update(pLFO3->ExtController ? GetGigEngineChannel()->ControllerTable[pLFO3->ExtController] : 0); + pLFO3->updateByMIDICtrlValue(pLFO3->ExtController ? GetGigEngineChannel()->ControllerTable[pLFO3->ExtController] : 0); + pLFO3->setScriptDepthFactor( + pNote->Override.PitchLFODepth.Value, + pNote->Override.PitchLFODepth.Final + ); + if (pNote->Override.PitchLFOFreq.isFinal()) + pLFO3->setScriptFrequencyFinal(pNote->Override.PitchLFOFreq.Value, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE); + else + pLFO3->setScriptFrequencyFactor(pNote->Override.PitchLFOFreq.Value, pEngine->SampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE); } } @@ -461,19 +490,35 @@ } void Voice::TriggerEG1(const EGInfo& egInfo, double velrelease, double velocityAttenuation, uint sampleRate, uint8_t velocity) { + EG1.setStateOptions( + pRegion->EG1Options.AttackCancel, + pRegion->EG1Options.AttackHoldCancel, + pRegion->EG1Options.Decay1Cancel, + pRegion->EG1Options.Decay2Cancel, + pRegion->EG1Options.ReleaseCancel + ); EG1.trigger(pRegion->EG1PreAttack, RTMath::Max(pRegion->EG1Attack, 0.0316) * egInfo.Attack, pRegion->EG1Hold, pRegion->EG1Decay1 * egInfo.Decay * velrelease, pRegion->EG1Decay2 * egInfo.Decay * velrelease, pRegion->EG1InfiniteSustain, - pRegion->EG1Sustain, + (pNote && pNote->Override.Sustain.Final) ? + pNote->Override.Sustain.Value : + pRegion->EG1Sustain * (pNote ? pNote->Override.Sustain.Value : 1.f), RTMath::Max(pRegion->EG1Release * velrelease, 0.014) * egInfo.Release, velocityAttenuation, sampleRate / CONFIG_DEFAULT_SUBFRAGMENT_SIZE); } void Voice::TriggerEG2(const EGInfo& egInfo, double velrelease, double velocityAttenuation, uint sampleRate, uint8_t velocity) { + EG2.setStateOptions( + pRegion->EG2Options.AttackCancel, + pRegion->EG2Options.AttackHoldCancel, + pRegion->EG2Options.Decay1Cancel, + pRegion->EG2Options.Decay2Cancel, + pRegion->EG2Options.ReleaseCancel + ); EG2.trigger(uint(RgnInfo.EG2PreAttack), RgnInfo.EG2Attack * egInfo.Attack, false, @@ -523,4 +568,21 @@ return p; } + release_trigger_t Voice::GetReleaseTriggerFlags() { + release_trigger_t flags = + (pRegion->NoNoteOffReleaseTrigger) ? + release_trigger_none : release_trigger_noteoff; //HACK: currently this method is actually only called by EngineBase if it already knows that this voice requires release trigger, so I took the short way instead of checking (again) the existence of a ::gig::dimension_releasetrigger + switch (pRegion->SustainReleaseTrigger) { + case ::gig::sust_rel_trg_none: + break; + case ::gig::sust_rel_trg_maxvelocity: + flags |= release_trigger_sustain_maxvelocity; + break; + case ::gig::sust_rel_trg_keyvelocity: + flags |= release_trigger_sustain_keyvelocity; + break; + } + return flags; + } + }} // namespace LinuxSampler::gig