{"id":11559,"date":"2020-04-06T15:55:59","date_gmt":"2020-04-06T15:55:59","guid":{"rendered":"https:\/\/audioordeal.co.uk\/?p=11559"},"modified":"2020-04-06T15:59:35","modified_gmt":"2020-04-06T15:59:35","slug":"how-to-build-a-vst-lesson-5-limiter-2","status":"publish","type":"post","link":"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/","title":{"rendered":"How to build a VST \u2013 Lesson 5: Limiter 2"},"content":{"rendered":"\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"\"\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

In the last lesson I showed you how to build a limiter VST<\/a> that works on one channel of audio. Find the code so far at this link.<\/p>

https:\/\/github.com\/aRycroft\/JuceTutorial4<\/span><\/a><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t

Circular Buffer Class<\/h2>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Last time we wrote some code in the processBlock<\/strong> to create a circular audio buffer. It would be nice to not have to copy this logic everytime we wanted a circular buffer. We can encapsulate the code we wrote into a CircularBuffer <\/strong>class that we can use in multiple projects without copying and pasting code.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Right\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

In your Projucer project right click in the file viewer and select ‘<\/strong>Add New Cpp & Header file..’\u00a0<\/strong><\/p>

Call the files CircularBuffer.cpp and CircularBuffer.h, make sure they are in the source folder.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
<\/div>\n\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"CircularBuffer\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

In CircularBuffer.h <\/strong>write this base code that declares a class called CircularBuffer. The class name should always be the same as the name of the file.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t

\n\t\t\t\t
\n\t\t\t\t\t\t\t

class CircularBuffer {<\/em>
public:<\/em>
private:<\/em>
};<\/em><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

In the header file we need to declare what functions this class will have. We write function prototypes that say what the function will return, and what inputs it has.<\/p>

We want to be able to write and read data in the buffer, but we don’t need to decide at which index.\u00a0<\/p>

float getData();
void setData(float data);<\/em><\/p>

getData<\/strong> doesn’t require any variables, it will just return the data at the current writeIndex.<\/p>

setData<\/strong> doesn’t need an index, it will only set the data at the current readIndex.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Add\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

In CircularBuffer.h <\/strong>public section add the getData and setData function signatures.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

We also need a way to move the read and writeIndexes.<\/p>

void nextSample();<\/em><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"add\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Add the nextSample<\/strong> signature.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

So far we’ve added function signatures in the public section of the class, which means any other class can call these functions. We need to declare some private variables to handle the buffer logic. These won’t be accessible by other classes.<\/p>

int writeIndex;
int readIndex;
int delayLength;<\/em><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Add\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Add writeIndex, readIndex <\/strong>and delayLength<\/strong> to the private header section.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

We’ll also need an AudioSampleBuffer<\/strong> to store the samples. To declare this we need to write this line to include the source code for this type of buffer.<\/p>

#include “..\/JuceLibraryCode\/JuceHeader.h”<\/em><\/p>

Now we can declare the following variable.<\/p>

AudioSampleBuffer buffer;<\/em><\/p>

\u00a0<\/div>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"#include\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Add #include and AudioSampleBuffer<\/strong><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

The final thing we need to do in the header file is add a constructor method. This is called once when a new CircularBuffer<\/strong> object is created, and deals with any intialisation that needs to happen.\u00a0<\/p>

C++ also requires you to write a default constructor, this is called with no arguments.<\/p>

CircularBuffer();
CircularBuffer(int bufferSize, int delayLength);<\/em><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Declare\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Adding a constructor and default constructor function.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Now we’ve declared everything we need in the header file to start coding CircularBuffer.cpp<\/strong>.\u00a0<\/p>

We need to create definitions of each of these functions in the cpp file. In visual studio by clicking on the functions and pressing alt + enter\u00a0<\/strong>then selecting create definition, it will do this for you automatically. Otherwise make your CircularBuffer.cpp <\/strong>file\u00a0look like the picture below.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Create\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Your CircularBuffer.cpp<\/strong> file should look like this.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Add this code to the default constructor. It just sets an empty AudioSampleBuffer and all other variables to 0.<\/p>

buffer = AudioSampleBuffer();<\/em>
writeIndex = readIndex = delayLength = 0;<\/em><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"\"\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Default constructor method.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Add this code to CircularBuffer(int bufferSize, int delayLength);<\/em><\/p>

buffer = AudioSampleBuffer(1, bufferSize); \/\/1
<\/span>buffer.clear(); \/\/2
<\/span><\/em>writeIndex = delayLength; \/<\/span><\/em>\/3<\/em><\/span>
readIndex = 0; \/\/4
this->delayLength = delayLength;\u00a0\/\/5<\/span><\/span><\/span><\/em><\/p>

1- Call the constructor for an AudioSampleBuffer.
2- Clear all samples in the buffer.
3- The writeIndex should be delayLength spaces infront of the readIndex.
4- Set readIndex to 0;
5- Save the delayLength passed into the constructor in a variable in the object.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Call\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

CircularBuffer constructor with initialisation code.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Next code the getData<\/b>\u00a0and setData<\/b>\u00a0functions.<\/p>

return buffer.getSample(0, readIndex); \/\/1<\/span><\/em><\/p>

buffer.setSample(0,<\/span> writeIndex, data); \/\/2<\/span><\/em><\/p>

1- Finds the sample in the readIndex position of the buffer.
2- Sets data as the value in the buffer at the writeIndex position.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"\"\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

getData <\/b>and setData <\/b>functions.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

We can reuse some of the code we wrote in the Limiter processBlock <\/strong>for the nextSample<\/strong> function.\u00a0<\/p>

int bufferLength = buffer.getNumSamples();<\/em>
readIndex = ((bufferLength + writeIndex) – delayLength) % bufferLength;<\/em>
writeIndex = (writeIndex + 1) % bufferLength;<\/em><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Write\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

This is similar to what we wrote in the processBlock<\/strong>, it finds the next read and write indexes.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

At this point our CircularBuffer<\/strong> class has all the functionality we need to use it in the PluginProcessor.<\/strong><\/p>

Take the following steps to use it in the PluginProcessor.<\/p>

1- Add #include “CircularBuffer.h”<\/em> in PluginProcessor.h.
2- Replace AudioSampleBuffer delayBuffer<\/em>; with\u00a0CircularBuffer delayBuffer;<\/em> in the header file.
3-\u00a0<\/em>Replace the AudioSampleBuffer initialisation code in prepareToPlay with delayBuffer = CircularBuffer(10, 1);<\/em><\/p>

After taking these steps we can replace the code we previously wrote in the processBlock<\/strong> function.<\/p>

float limitedSample = gain * delayBuffer.getData();<\/em>
delayBuffer.setData(sample);<\/em>
delayBuffer.nextSample();<\/em><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"\"\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Replace the old circular buffer code with the class functions we just wrote. You can tidy up by deleting the old writeIndex, readIndex, delayIndex and bufferLength<\/strong> variables.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Build your plugin now and it should work exactly how it did before. By encapsulating the CircularBuffer<\/strong> logic into it’s own class you can now use it in any of your projects. It also makes the processBlock<\/strong> a lot tidier and easier to read.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t

Adding more channels<\/h2>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

After writing that class it’s very easy to add more channels to our plugin. For each channel we’ll need a dedicated CircularBuffer.\u00a0<\/strong>We can store all of these in an Array and select each one depending on the channel of audio currently being processed in the processBlock<\/strong>.<\/p>

Juce has a built-in array that we’ll use for this.<\/p>

Array < CircularBuffer > allBuffers;<\/em><\/p>

Declare this in you header file. The <> brackets just mean we want an array of CircularBuffer<\/strong> objects.<\/p>

Next in prepareToPlay<\/strong> add the following code.<\/p>

allBuffers = Array < CircularBuffer > ();<\/em><\/p>

for (int channel = 0; channel < getNumOutputChannels(); channel++) {<\/em>
allBuffers.add(CircularBuffer(10, 1));<\/em>
}<\/em><\/p>

Here we initialise the allBuffers <\/strong>array and add a new CircularBuffer<\/strong> for each channel of output audio in the plugin.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"\"\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

prepareToPlay\u00a0<\/strong>with the new initialisation code.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Write another for loop inside the main process loop that goes from 0 to the total number of output channels.<\/p>

auto* data = buffer.getWritePointer(channel);
CircularBuffer* delayBuffer = &allBuffers.getReference(channel);<\/em><\/p>

These lines of code get the data and delayBuffer for the current channel.<\/p>

Don’t worry about the syntax in the second line of code, we need to use it so we get a pointer to the object stored in the array not a copy. Read up about C pointers if you’d like to know more\u00a0 \ud83d\ude42<\/p>

You will also need to change the code at the bottom of the processBlock\u00a0<\/strong>to use (->) instead of (.)\u00a0\u00a0<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Get\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

processBlock\u00a0<\/b>with stereo functionality.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t

Quick UI<\/h2>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

The last thing we’ll do in this tutorial is make a quick and easy UI for the plugin. Start by moving the limiterThresh<\/strong>, attackTime<\/strong> and releaseTime<\/strong> variables to the PluginProcessor<\/strong> header file, in the public section.\u00a0<\/p>

We also need to set some default values for the PluginEditor<\/b>\u00a0to be able to change the values.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Move\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

PluginProcessor.h\u00a0<\/strong>with new public declarations.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Now we can access these variables from the PluginEditor\u00a0<\/strong>class.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Declare\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

In\u00a0PluginEditor.h\u00a0<\/strong>declare three new Sliders.<\/p>

Slider threshold, at, rt;<\/em><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

In\u00a0PluginEditor.cpp\u00a0<\/strong>write the following code to add the sliders to the gui.<\/p>

addAndMakeVisible(&threshold);<\/em>
threshold.setValue(0);<\/em>
threshold.setRange(-60.0f, 10.0f, 0.001);<\/em><\/p>

addAndMakeVisible(&at);<\/em>
at.setRange(0.0f, 10.0f, 0.001);<\/em><\/p>

addAndMakeVisible(&rt);<\/em>
rt.setRange(0.0f, 10.0f, 0.001);<\/em><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Add\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Add this code to create 3 sliders, these don’t affect anything yet.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Then in the r<\/strong>esized\u00a0<\/b>function set where they will be drawn in the gui.<\/p>

threshold.setBounds(50, 50, 200, 50);<\/em>
at.setBounds(50, 150, 200, 50);<\/em>
rt.setBounds(50, 250, 200, 50);<\/em><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Set\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

This sets where the sliders will be placed in the gui.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Add these lines of code to the\u00a0PluginEditor\u00a0<\/strong>constructor.<\/p>

These functions set the variables we previously exposed in the PluginProcessor\u00a0<\/strong>class.<\/p>

threshold.onValueChange = [this] {<\/em>
processor.limiterThresh= std::pow(10, (threshold.getValue() \/ 20));<\/em>
};<\/em><\/p>

at.onValueChange = [this] {<\/em>
processor.attackTime= 1 – std::pow(MathConstants < float > ::euler, ((1 \/ processor.getSampleRate()) * -2.2f) \/ at.getValue());<\/em>
};<\/em><\/p>

rt.onValueChange = [this] {<\/em>
processor.releaseTime= 1 – std::pow(MathConstants < float > ::euler, ((1 \/ processor.getSampleRate()) * -2.2f) \/ rt.getValue());<\/em>
};<\/em><\/p>

Theses functions also convert from a decibel to linear scale for the threshold<\/strong>, and from time to linear for attackTime<\/strong> and releaseTime<\/strong>.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"\"\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

Add these functions to allow the PluginEditor<\/strong> to change values in PluginProcessor<\/strong>.<\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t

\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t

More Encapsulation??<\/h2>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t\t\t

This is all the code I’ll be doing in this tutorial. Build the plugin and try it out! It’s fairly basic but I think it sounds pretty good.<\/p>

If you’re looking for more to do, think about how you could encapsulate this code further. Currently if the left channel of audio is loud and turning on the limiter, the right channel is limited too. Could you write a new class to also encapsulate the gain<\/strong> and xPeak<\/strong> variables? This would mean each channel is limited independently.\u00a0<\/p>

You could also move all the code currently in\u00a0ProcessBlock<\/strong> to the new class. Meaning you would only need to call one function for each sample in the block. This would make it really easy to add a limiter effect to any other plugins you’re making.<\/p>

Find the code for this tutorial here.<\/p>

https:\/\/github.com\/aRycroft\/JuceTutorial5<\/span><\/a><\/p>\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"

In the last lesson I showed you how to build a limiter VST that works…<\/p>\n","protected":false},"author":5,"featured_media":11617,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[5],"tags":[2126,1898,2123],"jetpack_publicize_connections":[],"yoast_head":"\nHow to build a VST \u2013 Lesson 5: Limiter 2<\/title>\n<meta name=\"description\" content=\"Part 2 of a lesson to build an audio limiter VST using the JUCE library. Tutorial includes writing custom buffer and limiter classes.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to build a VST \u2013 Lesson 5: Limiter 2\" \/>\n<meta property=\"og:description\" content=\"Part 2 of a lesson to build an audio limiter VST using the JUCE library. Tutorial includes writing custom buffer and limiter classes.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/\" \/>\n<meta property=\"og:site_name\" content=\"Audio Ordeal\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/audioordeal\/\" \/>\n<meta property=\"article:published_time\" content=\"2020-04-06T15:55:59+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-04-06T15:59:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i2.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1366%2C768&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1366\" \/>\n\t<meta property=\"og:image:height\" content=\"768\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Alex Rycroft\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@audioordeal\" \/>\n<meta name=\"twitter:site\" content=\"@audioordeal\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alex Rycroft\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"19 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/\"},\"author\":{\"name\":\"Alex Rycroft\",\"@id\":\"https:\/\/audioordeal.co.uk\/#\/schema\/person\/65b8c997e71b94e5b808a95c59b915dd\"},\"headline\":\"How to build a VST \u2013 Lesson 5: Limiter 2\",\"datePublished\":\"2020-04-06T15:55:59+00:00\",\"dateModified\":\"2020-04-06T15:59:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/\"},\"wordCount\":1327,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/audioordeal.co.uk\/#organization\"},\"image\":{\"@id\":\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1366%2C768&ssl=1\",\"keywords\":[\"JUCE\",\"limiter\",\"programming VST\"],\"articleSection\":[\"Production\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/\",\"url\":\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/\",\"name\":\"How to build a VST \u2013 Lesson 5: Limiter 2\",\"isPartOf\":{\"@id\":\"https:\/\/audioordeal.co.uk\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1366%2C768&ssl=1\",\"datePublished\":\"2020-04-06T15:55:59+00:00\",\"dateModified\":\"2020-04-06T15:59:35+00:00\",\"description\":\"Part 2 of a lesson to build an audio limiter VST using the JUCE library. Tutorial includes writing custom buffer and limiter classes.\",\"breadcrumb\":{\"@id\":\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#primaryimage\",\"url\":\"https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1366%2C768&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1366%2C768&ssl=1\",\"width\":1366,\"height\":768},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/audioordeal.co.uk\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to build a VST \u2013 Lesson 5: Limiter 2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/audioordeal.co.uk\/#website\",\"url\":\"https:\/\/audioordeal.co.uk\/\",\"name\":\"Audio Ordeal\",\"description\":\"Music Production, Podcast, and DJ Tutorials\",\"publisher\":{\"@id\":\"https:\/\/audioordeal.co.uk\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/audioordeal.co.uk\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/audioordeal.co.uk\/#organization\",\"name\":\"Audio Ordeal\",\"url\":\"https:\/\/audioordeal.co.uk\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/audioordeal.co.uk\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2018\/12\/20264578_449563855429575_294261634867900376_n.png?fit=960%2C960&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2018\/12\/20264578_449563855429575_294261634867900376_n.png?fit=960%2C960&ssl=1\",\"width\":960,\"height\":960,\"caption\":\"Audio Ordeal\"},\"image\":{\"@id\":\"https:\/\/audioordeal.co.uk\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/audioordeal\/\",\"https:\/\/x.com\/audioordeal\",\"https:\/\/www.instagram.com\/audioordeal\/\",\"https:\/\/www.youtube.com\/channel\/UCgF1D5SH0zrnq30JX4QU0dg?view_as=subscriber\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/audioordeal.co.uk\/#\/schema\/person\/65b8c997e71b94e5b808a95c59b915dd\",\"name\":\"Alex Rycroft\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/audioordeal.co.uk\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/dcf4b4c69b617f9e1e8349e83eb0bf33?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/dcf4b4c69b617f9e1e8349e83eb0bf33?s=96&d=identicon&r=g\",\"caption\":\"Alex Rycroft\"},\"description\":\"Producer, DJ, Musician and Audio Programmer. Writing tutorials for Audio Ordeal about using JUCE and Max for Live.\",\"url\":\"https:\/\/audioordeal.co.uk\/author\/alexrycroft\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to build a VST \u2013 Lesson 5: Limiter 2","description":"Part 2 of a lesson to build an audio limiter VST using the JUCE library. Tutorial includes writing custom buffer and limiter classes.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/","og_locale":"en_US","og_type":"article","og_title":"How to build a VST \u2013 Lesson 5: Limiter 2","og_description":"Part 2 of a lesson to build an audio limiter VST using the JUCE library. Tutorial includes writing custom buffer and limiter classes.","og_url":"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/","og_site_name":"Audio Ordeal","article_publisher":"https:\/\/www.facebook.com\/audioordeal\/","article_published_time":"2020-04-06T15:55:59+00:00","article_modified_time":"2020-04-06T15:59:35+00:00","og_image":[{"width":1366,"height":768,"url":"https:\/\/i2.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1366%2C768&ssl=1","type":"image\/png"}],"author":"Alex Rycroft","twitter_card":"summary_large_image","twitter_creator":"@audioordeal","twitter_site":"@audioordeal","twitter_misc":{"Written by":"Alex Rycroft","Est. reading time":"19 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#article","isPartOf":{"@id":"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/"},"author":{"name":"Alex Rycroft","@id":"https:\/\/audioordeal.co.uk\/#\/schema\/person\/65b8c997e71b94e5b808a95c59b915dd"},"headline":"How to build a VST \u2013 Lesson 5: Limiter 2","datePublished":"2020-04-06T15:55:59+00:00","dateModified":"2020-04-06T15:59:35+00:00","mainEntityOfPage":{"@id":"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/"},"wordCount":1327,"commentCount":0,"publisher":{"@id":"https:\/\/audioordeal.co.uk\/#organization"},"image":{"@id":"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1366%2C768&ssl=1","keywords":["JUCE","limiter","programming VST"],"articleSection":["Production"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/","url":"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/","name":"How to build a VST \u2013 Lesson 5: Limiter 2","isPartOf":{"@id":"https:\/\/audioordeal.co.uk\/#website"},"primaryImageOfPage":{"@id":"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#primaryimage"},"image":{"@id":"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1366%2C768&ssl=1","datePublished":"2020-04-06T15:55:59+00:00","dateModified":"2020-04-06T15:59:35+00:00","description":"Part 2 of a lesson to build an audio limiter VST using the JUCE library. Tutorial includes writing custom buffer and limiter classes.","breadcrumb":{"@id":"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#primaryimage","url":"https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1366%2C768&ssl=1","contentUrl":"https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1366%2C768&ssl=1","width":1366,"height":768},{"@type":"BreadcrumbList","@id":"https:\/\/audioordeal.co.uk\/how-to-build-a-vst-lesson-5-limiter-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/audioordeal.co.uk\/"},{"@type":"ListItem","position":2,"name":"How to build a VST \u2013 Lesson 5: Limiter 2"}]},{"@type":"WebSite","@id":"https:\/\/audioordeal.co.uk\/#website","url":"https:\/\/audioordeal.co.uk\/","name":"Audio Ordeal","description":"Music Production, Podcast, and DJ Tutorials","publisher":{"@id":"https:\/\/audioordeal.co.uk\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/audioordeal.co.uk\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/audioordeal.co.uk\/#organization","name":"Audio Ordeal","url":"https:\/\/audioordeal.co.uk\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/audioordeal.co.uk\/#\/schema\/logo\/image\/","url":"https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2018\/12\/20264578_449563855429575_294261634867900376_n.png?fit=960%2C960&ssl=1","contentUrl":"https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2018\/12\/20264578_449563855429575_294261634867900376_n.png?fit=960%2C960&ssl=1","width":960,"height":960,"caption":"Audio Ordeal"},"image":{"@id":"https:\/\/audioordeal.co.uk\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/audioordeal\/","https:\/\/x.com\/audioordeal","https:\/\/www.instagram.com\/audioordeal\/","https:\/\/www.youtube.com\/channel\/UCgF1D5SH0zrnq30JX4QU0dg?view_as=subscriber"]},{"@type":"Person","@id":"https:\/\/audioordeal.co.uk\/#\/schema\/person\/65b8c997e71b94e5b808a95c59b915dd","name":"Alex Rycroft","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/audioordeal.co.uk\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/dcf4b4c69b617f9e1e8349e83eb0bf33?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/dcf4b4c69b617f9e1e8349e83eb0bf33?s=96&d=identicon&r=g","caption":"Alex Rycroft"},"description":"Producer, DJ, Musician and Audio Programmer. Writing tutorials for Audio Ordeal about using JUCE and Max for Live.","url":"https:\/\/audioordeal.co.uk\/author\/alexrycroft\/"}]}},"featured_image_urls":{"full":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1366%2C768&ssl=1",1366,768,false],"thumbnail":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?resize=150%2C150&ssl=1",150,150,true],"medium":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=300%2C169&ssl=1",300,169,true],"medium_large":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=640%2C360&ssl=1",640,360,true],"large":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=640%2C360&ssl=1",640,360,true],"1536x1536":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1366%2C768&ssl=1",1366,768,true],"2048x2048":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1366%2C768&ssl=1",1366,768,true],"newsphere-slider-full":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?resize=1280%2C720&ssl=1",1280,720,true],"newsphere-featured":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1024%2C576&ssl=1",1024,576,true],"newsphere-medium":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?resize=720%2C380&ssl=1",720,380,true],"woocommerce_thumbnail":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?resize=300%2C300&ssl=1",300,300,true],"woocommerce_single":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=600%2C337&ssl=1",600,337,true],"woocommerce_gallery_thumbnail":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?resize=100%2C100&ssl=1",100,100,true],"ppec_logo_image_size":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=107%2C60&ssl=1",107,60,true],"ppec_header_image_size":["https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=160%2C90&ssl=1",160,90,true]},"author_info":{"info":["Alex Rycroft"]},"category_info":"<a href=\"https:\/\/audioordeal.co.uk\/category\/production\/\" rel=\"category tag\">Production<\/a>","tag_info":"Production","comment_count":"0","jetpack_featured_media_url":"https:\/\/i0.wp.com\/audioordeal.co.uk\/wp-content\/uploads\/2020\/04\/Artboard-1.png?fit=1366%2C768&ssl=1","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pawm8q-30r","jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/audioordeal.co.uk\/wp-json\/wp\/v2\/posts\/11559"}],"collection":[{"href":"https:\/\/audioordeal.co.uk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/audioordeal.co.uk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/audioordeal.co.uk\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/audioordeal.co.uk\/wp-json\/wp\/v2\/comments?post=11559"}],"version-history":[{"count":23,"href":"https:\/\/audioordeal.co.uk\/wp-json\/wp\/v2\/posts\/11559\/revisions"}],"predecessor-version":[{"id":11621,"href":"https:\/\/audioordeal.co.uk\/wp-json\/wp\/v2\/posts\/11559\/revisions\/11621"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/audioordeal.co.uk\/wp-json\/wp\/v2\/media\/11617"}],"wp:attachment":[{"href":"https:\/\/audioordeal.co.uk\/wp-json\/wp\/v2\/media?parent=11559"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/audioordeal.co.uk\/wp-json\/wp\/v2\/categories?post=11559"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/audioordeal.co.uk\/wp-json\/wp\/v2\/tags?post=11559"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}