From c0a4df49a24f17ddb83fa060c78b91f61369d924 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Mon, 29 Apr 2024 16:47:17 +0200 Subject: [PATCH] Lb302: Consistent decay in time (#7230) The previous implementation of Lb302`s decay used a fixed decay factor that was multiplied with the signal until the minimum threshold of 1/65536 was crossed. This fixed factor resulted in different lengths in time for different sample rates. This is fixed by computing the decay factor by taking the sample rate into account as well. The new static method `computeDecayFactor` computes the factor that is needed to make a signal decay from 1 to a given attenuation over a given time. The parameters used in the call to that method in `Lb302Synth::process` have been fine-tuned such that, at a sample rate of 44.1 kHz, they result in a factor very close to the previous hard-coded factor of 0.99897516. --- plugins/Lb302/Lb302.cpp | 21 +++++++++++++++++++-- plugins/Lb302/Lb302.h | 1 - 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/plugins/Lb302/Lb302.cpp b/plugins/Lb302/Lb302.cpp index b0a6490b2..b85c26b0d 100644 --- a/plugins/Lb302/Lb302.cpp +++ b/plugins/Lb302/Lb302.cpp @@ -268,6 +268,16 @@ float Lb302Filter3Pole::process(const float& samp) // LBSynth // +static float computeDecayFactor(float decayTimeInSeconds, float targetedAttenuation) +{ + // This is the number of samples that correspond to the decay time in seconds + auto samplesNeededForDecay = decayTimeInSeconds * Engine::audioEngine()->processingSampleRate(); + + // This computes the factor that's needed to make a signal with a value of 1 decay to the + // targeted attenuation over the time in number of samples. + return std::pow(targetedAttenuation, 1. / samplesNeededForDecay); +} + Lb302Synth::Lb302Synth( InstrumentTrack * _instrumentTrack ) : Instrument(_instrumentTrack, &lb302_plugin_descriptor, nullptr, Flag::IsSingleStreamed), vcf_cut_knob( 0.75f, 0.0f, 1.5f, 0.005f, this, tr( "VCF Cutoff Frequency" ) ), @@ -282,7 +292,6 @@ Lb302Synth::Lb302Synth( InstrumentTrack * _instrumentTrack ) : deadToggle( false, this, tr( "Dead" ) ), db24Toggle( false, this, tr( "24dB/oct Filter" ) ), vca_attack(1.0 - 0.96406088), - vca_decay(0.99897516), vca_a0(0.5), vca_a(0.), vca_mode(VcaMode::NeverPlayed) @@ -481,6 +490,14 @@ int Lb302Synth::process(sampleFrame *outbuf, const int size) // TODO: NORMAL RELEASE // vca_mode = 1; + // Note: this has to be computed during processing and cannot be initialized + // in the constructor because it's dependent on the sample rate and that might + // change during rendering! + // + // At 44.1 kHz this will compute something very close to the previously + // hard coded value of 0.99897516. + auto decay = computeDecayFactor(0.245260770975f, 1.f / 65536.f); + for( int i=0; i= ENVINC float vca_attack, // Amp attack - vca_decay, // Amp decay vca_a0, // Initial amplifier coefficient vca_a; // Amplifier coefficient.