Getting Started with JUCE on Windows
Coding up a simple audio plugin with JUCE - the leading framework for multi-platform audio applications.

JUCE is a C++ library that can be used to develop your own audio plugins from scratch. If you are new to C++ and JUCE, coding up a plugin can be a daunting task. In this post we will go over how to set up a development environment on Windows and make a simple audio plugin using Microsoft Visual C++ (MSVC) and CMake.
We'll be making the simplest plugin in the book - a mute. (It just mutes your audio). Let's get started!
Install the MSVC compiler toolset
Microsoft Visual C++ (MSVC) can be downloaded from the Visual Studio downloads page. scroll down until you see Tools for Visual Studio 2019 under the All Downloads section and select the download for Build Tools for Visual Studio 2019. (Alternatively, you can download Visual Studio itself if you are planning to use the IDE)
This will launch the Visual Studio Installer, which will bring up a dialog showing the available workloads. Check the Desktop development with C++ workload and select Install.
Note that the installation doesn't add the compiler to the global system path. To use MSVC from a command line or VS Code, you must run from the Developer Command Prompt for Visual Studio. It's installed with the compiler and can be accessed from the start menu. To verify the installation, type 'cl' inside the Developer Command Prompt. You should see a copyright message with the version and basic usage description.
Download JUCE
You can find the JUCE library at https://github.com/juce-framework/JUCE. Download the repository as a .zip file or clone it into your PC.
Note that we are NOT using Projucer (JUCE's own project-configuration tool), but instead using CMake to setup the project. This gives us a better idea of what's happening.
Setup a new project
Open the Developer command prompt and navigate to the folder which you want to set up your project in. Open the folder with VS Code.
(Note: Opening VS Code from the start menu or a command prompt won't work because the necessary path environment variables not set)
cd C:/Code
mkdir mute-plugin
cd mute-plugin
code .
JUCE has provided us with some boilerplate code for CMake audio plugin projects. You can find it in in your JUCE download under JUCE\examples\CMake\AudioPlugin. Copy the contents of this folder into your project directory. You will also need to make a copy of the main JUCE folder inside your project. (You only need the extras and modules subfolders). Your file structure should look like this.
.
├── CMakeLists.txt
├── JUCE
│ ├── CMakeLists.txt
│ ├── extras
│ └── modules
├── PluginEditor.cpp
├── PluginEditor.h
├── PluginProcessor.cpp
└── PluginProcessor.h
Configure CMake
The CMakeLists.txt file specifies how your project is built. First, we need to tell CMake where the JUCE headers are located. We can either add the JUCE directory to our project or install JUCE globally on our system. We already copied in the JUCE directory into our project, so we need to tell CMake to add it by uncommenting the following line
add_subdirectory(JUCE)
Now you can go on to change other settings. The JUCE CMake API explains all the available settings. For our purposes we will only change some settings under juce_add_plugin()
juce_add_plugin(AudioPluginExample
COPY_PLUGIN_AFTER_BUILD TRUE
VST3_COPY_DIR C:/VST3
PLUGIN_MANUFACTURER_CODE Juce
PLUGIN_CODE Mute
FORMATS VST3
PRODUCT_NAME "Mute")
Here we have setup the project to build only the VST3 plugin and copy it to C:/VST3
Edit the source code
Now we need to make the plugin do something. The processing of the plugin is handled in processBlock(...) method of PluginProcessor.cpp, which we are going to edit. Delete the contents of the function and replace it with the following code.
void AudioPluginAudioProcessor::processBlock(juce::AudioBuffer<float> &buffer,
juce::MidiBuffer &midiMessages) {
auto *channeldata = buffer.getWritePointer(0);
for (int i = 0; i < buffer.getNumSamples(); i++) {
channeldata[i] = 0.0f;
}
}
This code does the following:
- Assigns a variable channeldata as the write pointer of the audio buffer. Selecting 0 in getWritePointer() will assign channeldata to the left input channel.
- Iterates through the audio buffer and sets it to 0.
If you want to mute both channels the code should be modified as follows
void AudioPluginAudioProcessor::processBlock(juce::AudioBuffer<float> &buffer,
juce::MidiBuffer &midiMessages) {
auto *channeldataL = buffer.getWritePointer(0);
auto *channeldataR = buffer.getWritePointer(1);
for (int i = 0; i < buffer.getNumSamples(); i++) {
channeldataL[i] = 0.0f;
channeldataR[i] = 0.0f;
}
}
Build the plugin
We can now go on and build the plugin. Execute the following commands in the root folder of your project
cmake -B cmake-build
cmake --build cmake-build
The plugin should build and get copied to C:/VST3 as we specified earlier. If you didn't set the copy plugin option, you can always see where the build was created in the command line output.
Test it in you DAW
Add the plugin to your DAW. Since we didn't specify a company name it should appear under yourcompany
Drag the plugin onto an audio track. The sound should be muted as you programmed. Turn off (bypass) the plugin and verify this.