A course in JUCE, modern C++ and shipping audio software

Build audio plugins in C++, then ship them.

From your first sine wave to a signed, licensed plugin in other people's sessions. You write real JUCE code from the first lesson and hear it as you type.

Sonic Supernova is one route through audio programming. You learn JUCE by building effects you can hear. You pick up modern C++ right before each plugin needs it. And you finish the way professionals do: tested, signed, packaged and licensed.

Thirty-seven stations.
One route.

Read each stage from top to bottom. The C++ you need comes right before the plugin that uses it, and the shipping work runs alongside from the first stage.

JUCE plugin, 17 modules Just Enough C++, 11 modules Distribution and Licensing, 9 modules
Stage 1

First sounds

Make a tone, learn what a plugin is, then control level and position.
00Hello, Sound
C1Values & Types
C2Functions & Lambdas
C3Classes & Enums
C4Inheritance & Polymorphism
F1Plugin Anatomy
01Gain
C5Values, Pointers & References
02Pan
Ship in parallel
D1Plugin Formats
Stage 2

Shaping sound

Parameters the host can automate, then effects that reshape the waveform.
F2Parameters & State
03Tremolo
C9Templates
04Bitcrusher
05Distortion
Ship in parallel
D2Continuous Integration
D3Testing & pluginval
Stage 3

Real time and frequency

Memory over time, the rules of the audio thread, and thinking in spectra.
C6Memory & Ownership
C7Containers & Spans
06Delay
C11Threads & Mutexes
C8Undefined Behaviour
F3Real-time Safety
07Thinking in Frequency
08Filter
Ship in parallel
D4macOS Signing
D5Windows Installers
D6Linux Packaging
Stage 4

Seeing sound

An editor of your own, with meters, a scope and a spectrum analyser.
C10Headers, Sources & the Build
F4GUI & Meters
09Oscilloscope
10Spectrum
Ship in parallel
D7Licensing with Keygen.sh
D8License Server
Stage 5

Dynamics and your own plugin

A compressor, then a full channel strip that you validate and ship.
11Compressor
12Capstone: Channel Strip
Ship in parallel
D9Pricing & Storefront

Designed around how programmers learn.

Every module uses the same few techniques from learning research. You will notice them as habits, not as theory.

C++ arrives when you need it.

Each language feature is taught right before the plugin that first uses it, so you practise it within the hour on something you can hear.

Every lesson starts by remembering.

A warm-up of up to three questions from earlier modules opens each theory page. Recalling older material at intervals is what makes it stay.

Guess first, then press Run.

Before your first run you predict what you will hear. Each exercise becomes a small experiment, and a wrong guess is the most useful kind.

Support fades as you improve.

Fix a planted bug, rearrange the lines of the fix if you are stuck, then extend the plugin on your own with no hints at all.

Three rooms in every module.

Watch the idea, write the code, then see and hear what it did. All of it runs in your browser, with nothing to install.

03Tremolo TheoryPracticeVisualizers
gain = 1 − depth · (½ + ½ sin φ) rate 2.0 Hz · depth 0.8
Chapter 2 · An LFO is a slow oscillator ShortStandardDeep

The LFO runs at a few hertz, far below anything you hear as pitch. Multiply the signal by it and you hear the level rise and fall instead.

Warm-up · 1 of 3 From 01 Gain: what does multiplying every sample by 0.5 do to the level? Lowers it by about 3 dBLowers it by about 6 dB ✓
Before you start F2 Parameters & State. Depth and rate are parameters the host can automate.C2 Functions & Lambdas. The LFO shape is a small function.
math ↔ code
φ += 2π · rate / fs
phase += phaseInc;
Theory. An animated scene draws the signal while the transcript explains it at the depth you choose. The maths sits next to the C++ it turns into.

C++20 and C++23, the way audio code needs it.

The audio thread has strict rules. It can't allocate memory, take a lock or wait for anything, or you hear a click. Modern C++ lets you follow those rules and have the compiler check them. Here is a tremolo's processBlock as you will write it by module F3.

Source/PluginProcessor.cpp
void processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer&)
1 [[clang::nonblocking]] override
{
2 depth.setTargetValue (depthParam->load (std::memory_order_relaxed));
for (auto ch = 0; ch < buffer.getNumChannels(); ++ch)
{
3 std::span samples { buffer.getWritePointer (ch),
(size_t) buffer.getNumSamples() };
for (auto& s : samples)
s *= gainAt (depth.getNextValue());
}
}
// Written by the GUI thread, read by the audio thread
4std::atomic<float>* depthParam {};
static_assert (std::atomic<float>::is_always_lock_free);
  1. 1[[clang::nonblocking]]Clang warns at compile time if anything called from here may allocate or lock. RealtimeSanitizer catches what slips through when the plugin runs.
  2. 2juce::SmoothedValueRamps the depth across the block instead of jumping, which removes the zipper noise you hear when a knob moves.
  3. 3std::spanA view of one channel with its length attached. The range-for cannot run past the end of the buffer.
  4. 4std::atomicThe GUI and audio threads share the value without a lock, and the static_assert proves it is lock-free on this platform.

The Just Enough C++ track

Eleven modules, each with a memory diagram you can step through line by line.
C1Values & Typesauto, brace initialisation, const, constexpr, narrowing
C2Functions & Lambdasparameters, lambdas and captures, std::function
C3Classes & Enumsmembers, constructors, enum class, designated initialisers
C4Inheritance & Polymorphismvirtual and pure virtual, override, final
C5Values, Pointers & Referencesvalue, pointer and reference semantics, std::optional
C6Memory & Ownershipnew and delete, RAII, unique_ptr, shared_ptr
C7Containers & Spansstd::array, std::vector, std::span, ranges
C8Undefined Behaviouruninitialised reads, memory you do not own, sanitizers
C9Templatesfunction and class templates, concepts
C10Headers, Sources & the Builddeclarations, linking, static and dynamic libraries
C11Threads & Mutexesstd::mutex, std::atomic, lock-free hand-off

Sonic Supernova for CLion.

When an exercise is ready to become a real plugin, the CLion plugin creates the JUCE project, sets up CMake and checks your toolchain. Then it stays docked beside your code with the lesson, its checks and plain-language build errors.

TRtremolo⌄ main ⌄ tremolo · Debug ⌄ ▶
New Project C++ Executable C++ Library JUCE audio project C Executable
Name:tremolo Location:~/AudioProjects/tremolo
What are you building?
Audio effectProcesses sound that's already there. Reverb, distortion, EQ, delay.
SynthesiserCreates sound from MIDI notes. Needs no audio input.
MIDI effectChanges notes, not sound. Arpeggiators, chord generators.
Standalone appA normal application, not a plugin. The simplest place to start.
How do you want to build the interface?
C++The standard way. Everything in one language, fast to load, and total control over custom drawing and metering. You'll write more code to get a good-looking result.
Web (Svelte + TypeScript)Build the interface with HTML and CSS, with live reload while the plugin runs. Far faster to make something beautiful. Costs extra memory and startup time per plugin instance, which matters in a large session.
How should the project teach?Explain as you goJust the code
Three decisions, then Create. Name the project, choose what you are building and how to make its interface. Formats, plugin codes, the C++ standard and CI stay behind Advanced with sensible defaults.

From a build on your machine to a product people buy.

The Distribution and Licensing track covers formats, testing, signing, installers for three platforms, licensing and a storefront. You deploy the licensing yourself, on infrastructure you control.

Build and test

D1Plugin FormatsVST3, AU, CLAP, LV2 and Standalone, and what each host expects.
D2Continuous IntegrationEvery format on every platform, built on each push.
D3Testing & pluginvalDSP unit tests, pluginval, real DAWs and crash reports.

Sign and package

D4macOS SigningDeveloper ID, notarisation and a signed installer.
D5Windows InstallersCode signing and an installer that puts files in the right place.
D6Linux PackagingTarballs and .deb, dependencies, testing in Reaper and Bitwig.

License and sell

D7Licensing with Keygen.shLicense models, keys and machines, offline activation.
D8License ServerDeploy on AWS, GCP or Scaleway, with store webhooks.
D9Pricing & StorefrontPricing models, payment providers, downloads and updates.
D7 · D8

Licensing with Keygen.sh, on your own server.

Keygen.sh manages licenses, keys and machine activations, and you can host it yourself. You pick a license model, validate keys inside the plugin, verify the signed response on the device and support offline activation for studio machines that never go online.

Then you deploy the small service around it on AWS, GCP or Scaleway, and connect your store so a sale creates a license and emails the key.

1
Purchaseyour storeThe store sends a webhook when someone buys the plugin.
2
License createdyour serverYour service asks Keygen for a license and emails the key to the customer.
3
Activationplugin → KeygenOn first launch the plugin sends the key and a fingerprint of the machine.
4
Signed responseKeygen → pluginKeygen returns a license file signed for that machine.
5
Verified on the deviceinside the pluginThe plugin checks the signature locally, so it keeps working offline.
The activation path you build and deploy in D7 and D8.

Questions

Do I need to know C++ first?

No. The Just Enough C++ track starts with values and types, and each module comes right before the JUCE module that first uses it. If you already write C++, you can skip those stops.

Do I need a background in maths or signal processing?

No. Module 00 starts with one sine wave, and each theory page shows the maths beside the code it becomes. Comfort with basic algebra helps.

Where does my code run?

In your browser. Exercises are compiled by clang to WebAssembly against real JUCE, run in an AudioWorklet and play through your speakers, with AddressSanitizer, UndefinedBehaviorSanitizer and RealtimeSanitizer catching mistakes. For your own projects, the CLion plugin generates a standard JUCE and CMake project on your machine.

Do I need CLion?

Not for the browser lessons. You need it for the CLion plugin, which turns exercises into real projects and adds the Doctor, build explanations and in-IDE checks.

Do I have to use Keygen.sh for licensing?

No. The licensing modules use Keygen.sh because you can host it yourself, and the ideas carry over to other providers: license models, activation, signed responses and offline use.

How long does the course take?

It depends on your pace. Module 00 takes about five minutes, and most modules fit in one or two sittings. The full route is designed to be followed over months.

Your first sound takes five minutes.

Module 00 has you write a sine wave, change one number and hear it change. The rest of the route builds from there.

Start with Hello, Sound