# SynthQuest  5: Implementing ADSR

Welcome back to the SynthQuest series, where we’re building a VST from scratch. This is Episode 5, and today’s quest is to implement ADSR and open our synth inside a DAW for the first time. If you’re joining us for the first time, be sure to check out the previous episodes to catch up. Alright, let’s begin with a small video clip of 27 seconds to hear ADSR (attack/decay/sustain/release) in action–

%[https://www.youtube.com/watch?v=3FQMnk_uzYU] 

Now, I’ll provide the literal definitions of all these, but after reading, watch the video again (using headphones), and you will get a good idea:

* **Attack:** The time it takes for a sound to rise from silence to its peak amplitude when a note is pressed.
    
* **Decay: T**he time it takes for the sound to drop from its peak amplitude to the sustain level.
    
* **Sustain:** Steady amplitude level that the sound holds as long as the note is held.
    
* **Release:**  The time it takes for the sound to fade from the sustain level to silence when the note is released.
    

We will declare a **juce::ADSR** object as a private member in the *SynthVoice* class in *pluginProcessor.h* file. At the same time, we’ll also declare **juce::ADSR::Parameters** object; this will be useful later.

`juce::ADSR adsr;`

`juce::ADSR::Parameters adsrParams;`

After that, go to the pluginProcessor.cpp file and set the sample rate in the *SynthVoice::prepareToPlay()* function, write:

`adsr.setSampleRate(sampleRate);`

Then in the **SynthVoice::startNote()** function write

`adsr.noteOn();`

This lets the **ADSR** object know where to start the attack phase of the envelope. Also,

`osc.setFrequency(juce::MidiMessage::getMidiNoteInHertz(midiNoteNumber));`

There are two functions above, one is getMidiNoteInHertz(), which converts the midiNoteNumber to its respective frequency, and then that frequency is fed to the osc.setFrequency() function. The oscillator needs to know which frequency to play.

In the **SynthVoice::stopNote()** function:

`adsr.noteOff();`

This starts the release phase of the envelope. Check out the official documentation to learn more about this class and its functions [here.](https://docs.juce.com/master/classADSR.html)

Let’s go to the **SynthVoice::renderNextBlock()** function and apply this ADSR to the audio buffer for it to show effect:

`adsr.applyEnvelopeToBuffer(outputBuffer, startSample, numSamples);`

With this line, we now have a fully-fledged basic synthesizer which can play any note you tap on, and you can write your melodies now. Build the program by clicking on *build solution* or by pressing Ctrl+Shift+B. If your build is successful, it should show something like this:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1747473682032/149b93cd-aea1-44a5-8a1f-8da3b418c402.png align="center")

The main .vst3 file’s location (in the terminal) for me is – `E:\Files\C Projects\juce projects\basicOsc\basicOsc\Builds\VisualStudio2022\x64\Debug\VST3\basicOst.vst3\Contents\x86_64-win\basicOsc.vst3`

Now, to test our plugin in a DAW, first of course we’ll need a DAW, so let’s download one. *Reaper* would be a good option; it is free and lightweight. [You can download Reaper from here.](https://www.reaper.fm/download.php) Its installation is really easy. Create this folder if it’s not there already `C:\Program Files\Common Files\VST3` , and paste the .vst3 file in that folder. After installation, open *Reaper* and go to **options-&gt;preferences-&gt;Plug-ins-&gt;VST** and then see if that folder is there or not, if not add it by clicking on *edit path list* and rescan for plugins. In most cases, it is there by **default**.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1747473757388/bb59456e-fbe9-48c7-9bd1-fa8a786bebd3.png align="center")

After this, go to **track-&gt;insert virtual instrument on new track,** then just search for the VST and open it:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1747473825304/17bb8ccf-1af6-4c5a-9126-a6f5141fd2e0.png align="center")

Open the VST and then press Alt+B for the MIDI controller.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1747473929960/0361f7c2-f56f-4382-a4d8-54d5b5382c1f.png align="center")

Every time you build the project, you’ll have to copy the .vst3 file to the VST3 folder for your DAW to recognise it.

Alright, now let’s try to understand what an *AudioProcessorValueTreeState* (APVTS) class is. See, in a plugin some parameters or *knobs* can be modulated to change the sound, and we know that to make GUI elements in our plugin, we have to edit the pluginEditor files, but to efficiently link GUI components to the DSP code and ensure parameter changes are properly made, we need to take help of the APVTS class.

Let’s write its code, open the pluginProcessor.h file, and declare an APVTS object publicly in the *AudioProcessor* class.

`juce::AudioProcessorValueTreeState theValueTree;`

And after this, we need a helper function which will help us to create new parameters (like gain, pan, etc) and it will feed the parameters to the APVTS object. This function returns a ParameterLayout, which will be required when we initialize the APVTS in the pluginProcessor.cpp file.

`juce::AudioProcessorValueTreeState::ParameterLayout createParams();`

I am going to declare it privately in the AudioProcessor class of the pluginProccessor.h file. After this, your pluginProcessor.h file should look like this:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1747473969082/9fb04fab-1672-4d0e-aeba-2bd6f9049933.png align="center")

Now, let’s head over to the pluginProcessor.cpp file and initialize our APVTS object.

`theValueTree(*this, nullptr, "Parameters", createParams())`

This is the line of code, the first argument is the parent class, the second one is the undoManager (we don’t need this now, that’s why *nullptr*), third one is the name of the parameter group, and the fourth one is the parameter creation helper function which returns a ParameterLayout class having all the parameters. Now, your constructor should look like this:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1747474009594/b95868f2-ff97-487b-a3fe-1d479feeb7b3.png align="center")

You can check out the *synth-quest-5* branch in the GitHub re[posito](https://github.com/kashyap-harshit/basic-osc-tutorial)ry for the code till here. In the next episode, we’ll be implementing the *createParams()* function and start with the GUI of the VST. *Merci,* and see you in the next one!
