First VST : Reverse Delay | Algorithm Design | Forum

Avatar

Please consider registering
guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed Topic RSS sp_TopicIcon
First VST : Reverse Delay
Avatar
Member
Members
October 26, 2021 - 9:13 am
Member Since: September 27, 2021
Forum Posts: 5
sp_UserOfflineSmall Offline

Hello everyone,

I made a first a plugin which is a reverse delay with a "ducking" effect.

If you are interested, this is the Aspik project I have done : https://github.com/Johan-David/ReverseDelay

If you have any advice to improve the plugin, I will be happy to hear that Wink

Avatar
Admin
November 25, 2021 - 3:24 am
Member Since: January 1, 2020
Forum Posts: 103
sp_UserOfflineSmall Offline

Hi Johan congratulations on making your effect, it definitely sounds cool. Hope you're not too discouraged by the lack of response here.

I'd have written sooner but I had an annoying CMake error while building this. Tried a couple of things but might have a differing VST sdk version to what you used.

If you make a future update I'd like to try again. Apologies for now.

Avatar
Anglia
Member
Members
December 12, 2021 - 7:32 pm
Member Since: June 2, 2014
Forum Posts: 46
sp_UserOfflineSmall Offline

Johan said
Hello everyone,

I made a first a plugin which is a reverse delay with a "ducking" effect.

If you are interested, this is the Aspik project I have done : https://github.com/Johan-David/ReverseDelay

If you have any advice to improve the plugin, I will be happy to hear that Wink  

Hi Johan,

Good stuff. I've just completed mine too. I decided to plug in the Side Chain Processing as a composite IAudioSignalProcessor member object in my custom implementation of the AudioDelay, multiplying the wet signal with the output of EnvelopeDetectorSideChainSignalProcessor.processAudioSample method. This way I was able to use the same AudioDelay class for a plain old Digital Delay (as per the book), using a 'stubbed out' IAudioSignalProcessor as Side Chain Processor, which always returns 1 from its processAudioSample method, then plugging in a EnvelopeDetectorSideChainSignalProcessor for the ducking delay:

double DelayGainCalculator::processAudioSample(double xn)
{
	// --- calc threshold
	const double threshValue = pow(10.0, parameters.threshold_dB / 20.0);
	const double deltaValue = xn - threshValue;
 
	const double wetGainMin = pow(10.0, parameters.wetGainMin_dB / 20.0);
	const double wetGainMax = pow(10.0, parameters.wetGainMax_dB / 20.0);
 
 double yn = 1.0;
 // --- if above the threshold, modulate the filter fc
	if (deltaValue > 0.0) // || delta_dB > 0.0)
	{
		// --- best results are with linear values when detector is in dB mode
		double modulatorValue = (deltaValue * parameters.sensitivity);
        boundValue(modulatorValue, wetGainMin, wetGainMax);
        yn = modulatorValue;
	}
 
    return yn;
}

 

// EnvelopeDetectorSideChainSignalProcessor.processAudioSample (called from AudioDelay's processAudioSample method):

    double processAudioSample(double xn) override
    {
        // Amplify signal by sideChainGain
        const double sideChainGain = pow(10.0, parameters.sideChainGain_dB / 20.0);
        xn *= sideChainGain;
 
        // --- detect the signal
	    const double detect_dB = envDetector.processAudioSample(xn);
	    const double detectValue = pow(10.0, detect_dB / 20.0);
 
        // Pass it through Delay Gain Calculator
        const double yn = delayGainCalculator.processAudioSample(detectValue);
 
        return 1 - yn;
    }

 

Your DSP code is subtly different. I shall experiment with those differences, as I'm still not entirely happy with the sound of mine.

https://github.com/DoomyDwyer/ASPiKProjects/tree/main/Memento

And here's my GUI. I spent far too long on this, but it is the nicest GUI I've produced so far. The "Memento" ducking delay was also by far the most complex plugin design I've dealt with so far, due to the polymorphism needed to be able to swap out different Side Chain Processors for the different Delay pedals I've build (Normal & Ducking, using the same Delay class). I had to skill up on Templates pretty quick to get that working.

Image Enlarger

Avatar
Anglia
Member
Members
December 13, 2021 - 2:44 pm
Member Since: June 2, 2014
Forum Posts: 46
sp_UserOfflineSmall Offline

Johan said
Hello everyone,

I made a first a plugin which is a reverse delay with a "ducking" effect.

If you are interested, this is the Aspik project I have done : https://github.com/Johan-David/ReverseDelay

If you have any advice to improve the plugin, I will be happy to hear that Wink  

Hi Johan,

If I'm reading it right, you're getting a value back from the AudioDetector in dB, but you're then subtracting threshold, which has already been converted from dB to linear in your setParameters() method.

Avatar
Anglia
Member
Members
December 13, 2021 - 5:56 pm
Member Since: June 2, 2014
Forum Posts: 46
sp_UserOfflineSmall Offline

So, following the description of the Ducking Delay to the letter, I ended up with this:

It's a tricky pedal to get to sound nice. If for example the amplitude of the signal is always around the threshold, and there's a large difference between wet min & max gain, you can hear the effect switching between attenuation & amplification mode. Subtle changes make all the difference though, and with some care a nice "swell" can be heard:

double EnvelopeDetectorSideChainSignalProcessor::processAudioSample(double xn) override {
     // Amplify signal by sideChainGain
     xn *= sideChainGain;
     // --- detect the signal
     const double detect_dB = envDetector.processAudioSample(xn);
     const double detectValue = pow(10.0, detect_dB * 0.05);
     // Pass it through Delay Gain Calculator
     const double yn = delayGainCalculator.processAudioSample(detectValue);
     return yn;
 }

double DelayGainCalculator::processAudioSample(double xn)
{
    // If above the threshold, attenuate the wet mix by the wetGainMin factor
    double yn = wetGainMin;
    if (xn < threshValue)
    {
        // if below the threshold, amplify the wet mix
        yn = xn * parameters.sensitivity;
        // Keep within min & max wet gain bounds
        boundValue(yn, wetGainMin, wetGainMax);
    }
 
    return yn;
}
Avatar
Anglia
Member
Members
December 23, 2021 - 12:50 pm
Member Since: June 2, 2014
Forum Posts: 46
sp_UserOfflineSmall Offline

I eventually ended up with this code for my DelayGainCalculator. It gives a nice smooth transition between the levels of the wet signal above and below the threshold, unless wetGainMin and wetGainMax are insanely far apart. Note that I'm subtracting xn (which is the detected level from the AudioDetector [linear]) from threshValue, not the other way around. As the dry signal's level approaches the threshold, this delta becomes smaller, causing the wet signal to be amplified less. I found that this causes less of a sudden jump in the level of the wet signal as the dry signal transitions across the threshold value.

double DelayGainCalculator::processAudioSample(double xn) 
{
     // If above the threshold, side chain output is always equal to wetGainMin
     double yn = wetGainMin;
     if (xn < threshValue)
     {
         // If below the threshold,
         // do unipolar modulation to determine side chain output, up to a maximum value of wetGainMax
         yn  = doUnipolarModulationFromMin(parameters.sensitivity * (threshValue - xn), wetGainMin, wetGainMax);
     }
     return yn; 
}
Forum Timezone: America/New_York

Most Users Ever Online: 152

Currently Online:
11 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

Chaes: 56

Skyler: 48

StevieD: 46

Derek: 46

Frodson: 45

Peter: 43

TheSmile: 43

Nickolai: 43

clau_ste: 39

jeanlecode: 37

Member Stats:

Guest Posters: 1

Members: 775

Moderators: 1

Admins: 6

Forum Stats:

Groups: 13

Forums: 42

Topics: 846

Posts: 3353

Moderators: W Pirkle: 690