--- linuxsampler/trunk/src/engines/sfz/SfzSignalUnitRack.cpp 2011/08/02 13:44:57 2225 +++ linuxsampler/trunk/src/engines/sfz/SfzSignalUnitRack.cpp 2011/08/04 19:02:36 2229 @@ -34,28 +34,26 @@ return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE; } - - void EGv1Unit::Trigger() { - ::sfz::Region* const pRegion = pVoice->pRegion; - - // the length of the decay and release curves are dependent on the velocity - const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity); - - // set the delay trigger - uiDelayTrigger = (pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease) * GetSampleRate(); - - EG.trigger(uint(pRegion->ampeg_start * 10), - std::max(0.0, pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease), - std::max(0.0, pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease), - std::max(0.0, pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease), - uint(std::min(std::max(0.0, 10 * (pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease)), 1000.0)), - std::max(0.0, pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease), - GetSampleRate()); + float SfzSignalUnit::GetInfluence(ArrayList< ::sfz::CC>& cc) { + float f = 0; + for (int i = 0; i < cc.size(); i++) { + int val = pVoice->GetControllerValue(cc[i].Controller); + f += (val / 127.0f) * cc[i].Influence; + } + return f; } void EGv2Unit::Trigger() { - EG.trigger(*pEGInfo, GetSampleRate(), pVoice->MIDIVelocity); + egInfo = *pEGInfo; + for (int i = 0; i < egInfo.node.size(); i++) { + float f = GetInfluence(egInfo.node[i].level_oncc); + egInfo.node[i].level = std::min(egInfo.node[i].level + f, 1.0f); + + f = GetInfluence(egInfo.node[i].time_oncc); + egInfo.node[i].time = std::min(egInfo.node[i].time + f, 100.0f); + } + EG.trigger(egInfo, GetSampleRate(), pVoice->MIDIVelocity); } @@ -98,6 +96,53 @@ GetSampleRate()); } + + void AmpEGUnit::Trigger() { + ::sfz::Region* const pRegion = pVoice->pRegion; + + // the length of the decay and release curves are dependent on the velocity + const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity); + + // set the delay trigger + float delay = pRegion->ampeg_delay + pRegion->ampeg_vel2delay * velrelease; + delay += GetInfluence(pRegion->ampeg_delaycc); + uiDelayTrigger = std::max(0.0f, delay) * GetSampleRate(); + + float start = (pRegion->ampeg_start + GetInfluence(pRegion->ampeg_startcc)) * 10; + + float attack = pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease; + attack = std::max(0.0f, attack + GetInfluence(pRegion->ampeg_attackcc)); + + float hold = pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease; + hold = std::max(0.0f, hold + GetInfluence(pRegion->ampeg_holdcc)); + + float decay = pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease; + decay = std::max(0.0f, decay + GetInfluence(pRegion->ampeg_decaycc)); + + float sustain = pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease; + sustain = 10 * (sustain + GetInfluence(pRegion->ampeg_sustaincc)); + + float release = pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease; + release = std::max(0.0f, release + GetInfluence(pRegion->ampeg_releasecc)); + + EG.trigger ( + uint(std::min(std::max(0.0f, start), 1000.0f)), attack, hold, decay, + uint(std::min(std::max(0.0f, sustain), 1000.0f)), release, GetSampleRate() + ); + } + + + LFOUnit::LFOUnit(SfzSignalUnitRack* rack) + : SfzSignalUnit(rack), pLfoInfo(NULL), pLFO(NULL), + suFadeEG(rack), suFreqOnCC(rack, this) + { } + + LFOUnit::LFOUnit(const LFOUnit& Unit) + : SfzSignalUnit(Unit), suFadeEG(static_cast(Unit.pRack)), + suFreqOnCC(static_cast(Unit.pRack), this) + { + Copy(Unit); + } void LFOUnit::Increment() { if (DelayStage()) return; @@ -105,6 +150,7 @@ SignalUnit::Increment(); Level = pLFO->Render(); + if (suFadeEG.Active()) Level *= suFadeEG.GetLevel(); } void LFOUnit::Trigger() { @@ -113,13 +159,27 @@ // set the delay trigger uiDelayTrigger = pLfoInfo->delay * GetSampleRate(); + if(pLfoInfo->fade != 0 || !pLfoInfo->fade_oncc.empty()) { + float f = pLfoInfo->fade; + f += GetInfluence(pLfoInfo->fade_oncc); + + if (f != 0) { + suFadeEG.uiDelayTrigger = pLfoInfo->delay * GetSampleRate(); + suFadeEG.EG.trigger(0, f, 0, 0, 1000, 0, GetSampleRate()); + } + } } + void LFOUnit::ValueChanged(CCSignalUnit* pUnit) { + pLFO->SetFrequency(std::max(0.0f, suFreqOnCC.GetLevel() + pLfoInfo->freq), GetSampleRate()); + } + + void LFOv1Unit::Trigger() { LFOUnit::Trigger(); lfo.trigger ( - pLfoInfo->freq, + pLfoInfo->freq + suFreqOnCC.GetLevel(), start_level_mid, 1, 0, false, GetSampleRate() ); @@ -149,24 +209,21 @@ else pLFO = lfos[pLfoInfo->wave]; pLFO->Trigger ( - pLfoInfo->freq, + pLfoInfo->freq + suFreqOnCC.GetLevel(), start_level_mid, 1, 0, false, GetSampleRate() ); pLFO->Update(0); - float phase = pLfoInfo->phase; - for (int i = 0; i < pLfoInfo->phase_oncc.size(); i++) { - int val = pVoice->GetControllerValue(pLfoInfo->phase_oncc[i].Controller); - phase += (val / 127.0f) * pLfoInfo->phase_oncc[i].Influence; - } + float phase = pLfoInfo->phase + GetInfluence(pLfoInfo->phase_oncc); if (phase != 0) pLFO->SetPhase(phase); } void AmpLFOUnit::Trigger() { ::sfz::Region* const pRegion = pVoice->pRegion; - pLfoInfo->delay = pRegion->amplfo_delay; - pLfoInfo->freq = pRegion->amplfo_freq; + pLfoInfo->delay = pRegion->amplfo_delay; + pLfoInfo->freq = pRegion->amplfo_freq; + pLfoInfo->fade = pRegion->amplfo_fade; pLfoInfo->volume = pRegion->amplfo_depth; LFOv1Unit::Trigger(); @@ -175,7 +232,8 @@ void PitchLFOUnit::Trigger() { ::sfz::Region* const pRegion = pVoice->pRegion; pLfoInfo->delay = pRegion->pitchlfo_delay; - pLfoInfo->freq = pRegion->pitchlfo_freq; + pLfoInfo->freq = pRegion->pitchlfo_freq; + pLfoInfo->fade = pRegion->pitchlfo_fade; pLfoInfo->pitch = pRegion->pitchlfo_depth; LFOv1Unit::Trigger(); @@ -183,14 +241,17 @@ void FilLFOUnit::Trigger() { ::sfz::Region* const pRegion = pVoice->pRegion; - pLfoInfo->delay = pRegion->fillfo_delay; - pLfoInfo->freq = pRegion->fillfo_freq; + pLfoInfo->delay = pRegion->fillfo_delay; + pLfoInfo->freq = pRegion->fillfo_freq; + pLfoInfo->fade = pRegion->fillfo_fade; pLfoInfo->cutoff = pRegion->fillfo_depth; LFOv1Unit::Trigger(); } - CCUnit::CCUnit(SfzSignalUnitRack* rack): CCSignalUnit(rack) { } + CCUnit::CCUnit(SfzSignalUnitRack* rack, Listener* l): CCSignalUnit(rack, l) { + pVoice = NULL; + } void CCUnit::Trigger() { for (int i = 0; i < Ctrls.size(); i++) { @@ -244,6 +305,7 @@ EGv2Unit* eg = GetRack()->volEGs[i]; if (!eg->Active()) continue; vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f); + } AmpLFOUnit* u = &(GetRack()->suAmpLFO); @@ -331,7 +393,9 @@ { suEndpoint.pVoice = suVolEG.pVoice = suFilEG.pVoice = suPitchEG.pVoice = voice; suAmpLFO.pVoice = suPitchLFO.pVoice = suFilLFO.pVoice = voice; - suPitchLFO.suDepthCC.pVoice = voice; + suPitchLFO.suDepthCC.pVoice = suPitchLFO.suFadeEG.pVoice = suPitchLFO.suFreqOnCC.pVoice = voice; + suFilLFO.suFadeEG.pVoice = suFilLFO.suFreqOnCC.pVoice = voice; + suAmpLFO.suFadeEG.pVoice = suAmpLFO.suFreqOnCC.pVoice = voice; for (int i = 0; i < EGs.capacity(); i++) { EGs[i] = new EGv2Unit(this); @@ -341,7 +405,9 @@ for (int i = 0; i < LFOs.capacity(); i++) { LFOs[i] = new LFOv2Unit(this); LFOs[i]->pVoice = voice; + LFOs[i]->suFadeEG.pVoice = voice; LFOs[i]->suPitchOnCC.pVoice = voice; + LFOs[i]->suFreqOnCC.pVoice = voice; } } @@ -397,6 +463,7 @@ lfo.pLfoInfo = &(pRegion->lfos[i]); LFOs.increment()->Copy(lfo); LFOs[LFOs.size() - 1]->suPitchOnCC.SetCCs(pRegion->lfos[i].pitch_oncc); + LFOs[LFOs.size() - 1]->suFreqOnCC.SetCCs(pRegion->lfos[i].freq_oncc); } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; } if (pRegion->lfos[i].pitch != 0 || !pRegion->lfos[i].pitch_oncc.empty()) { @@ -421,23 +488,39 @@ } suPitchLFO.suDepthCC.SetCCs(pRegion->pitchlfo_depthcc); + suPitchLFO.suFreqOnCC.SetCCs(pRegion->pitchlfo_freqcc); + + suFilLFO.suFreqOnCC.SetCCs(pRegion->fillfo_freqcc); + + suAmpLFO.suFreqOnCC.SetCCs(pRegion->amplfo_freqcc); Units.clear(); Units.add(&suVolEG); Units.add(&suFilEG); Units.add(&suPitchEG); + + Units.add(&suPitchLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO) Units.add(&suPitchLFO); Units.add(&suPitchLFO.suDepthCC); + Units.add(&suPitchLFO.suFadeEG); + + Units.add(&suAmpLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO) Units.add(&suAmpLFO); + Units.add(&suAmpLFO.suFadeEG); + + Units.add(&suFilLFO.suFreqOnCC); // Don't change order! (should be triggered before the LFO) Units.add(&suFilLFO); + Units.add(&suFilLFO.suFadeEG); for (int i = 0; i < EGs.size(); i++) { Units.add(EGs[i]); } for (int i = 0; i < LFOs.size(); i++) { + Units.add(&(LFOs[i]->suFreqOnCC)); // Don't change order! (should be triggered before the LFO) Units.add(LFOs[i]); + Units.add(&(LFOs[i]->suFadeEG)); Units.add(&(LFOs[i]->suPitchOnCC)); }