In this final lesson in the module, you will explore the structure of an effect plugin, learn about developing code using Klang Studio, and draw on what you have learnt about code and digital signal processing (DSP) to implement a gain (level) effect plugin.

LESSON PLAN

INSTRUCTIONS

Use the < > arrow(s) above to move through the topic. Each page explains a key concept using text and graphics, leading up to a practical task. You can return to any page at any time, using the arrows or drop-down menu, and also restart animations by simply clicking them.

From Process to Plugin

Together, the two lines from the previous lesson form the process() function of our plugin,
which describes the audio process applied to every input sample to produce the output.

Functions are named, reusable blocks of code defined for a specific purpose, called as needed. The process() function is triggered during DAW playback, called repeatedly
to apply the audio process to every input sample (e.g. 44,100 times a second).

A fundamental concept in programming, functions allow us to structure code, and break complex programs down into simpler, more modular parts — abstracting complexity.

From Process to Plugin

Code to define the function is contained in curly brackets, known as { braces }, which are used to mark the beginning and end of functions, objects, and other code structures in C++.

Unmatched braces (opening but no closing brackets, or vice versa) are another
common and easy mistake to make - but much harder for the compiler to catch!

From Process to Plugin

Code to define the function is contained in curly brackets, known as { braces }, which are used to mark the beginning and end of functions, objects, and other code structures in C++.

Unmatched braces (opening but no closing brackets, or vice versa) are another
common and easy mistake to make - but much harder for the compiler to catch!

To make it easier to see the structure (and ensure brackets are matched), it's important
to indent the code inside braces - using tab ⇥ or a fixed number of spaces (e.g. 3).

From Process to Plugin

The process() function is one part of the wider plugin, encapsulated by the MyEffect object.

An object (struct or class in C++) is a named, reusable code structure that can contain multiple variables, functions, or other objects, oriented around a specific purpose.

Objects are a core concept of C++, which is designed for object-oriented programming — the principle of reducing large, complex systems to simpler, modular, self-contained parts that logically mirror the world being modelled and can be developed and tested separately.

From Process to Plugin

MyEffect inherits the functionality of a generic Effect object, which includes all the base code for an effect plugin, so that we can focus on the audio processing and the UI.

We define the UI for our plugin in the object's constructor — a special function sharing the name of the object, called when it is created (when the plugin loads) to initialise itself.

In this instance, we'll define controls so that our UI contains a single Dial called "Gain",
(with the default range, 0.0 to 1.0), which we can then access in process() using controls[0]:

From Process to Plugin

The last remaining code required are two lines that add the Klang extension
to C++ and tell it to use the performance optimised versions of DSP objects.

We'll use these in all projects, so will generally omit them in these examples.

From Process to Plugin

We now have the complete source code for the gain effect, but before we move to Klang Studio to compile the plugin, there's one last programming tool to introduce: commenting.

Comments allow you to annotate and decorate your code, and write descriptions or notes
to yourself (and others). Anything after // is treated as a comment, rather than code.

On the course, you should annotate code with comments to help you remember how code works. You can also 'comment out' code to disable it, which can be useful for finding bugs!

Klang Studio
Install Klang Studio

Klang Studio is a complete C++ interactive developer environment (IDE) contained in an audio plugin, enabling you to develop synthesisers and effects live inside the DAW itself.

PRACTICAL: Gain Effect
Install Klang Studio
Use the guidance below to create a new project, add code, and build the gain plugin
then discover the different parts and features of Klang Studio by exploring the program.

Instructions / Tips (1/2)
  1. Find the Settings tab in Klang Studio.
    • Click here to open the studio from the browser.
    • In the lab, you can also place the learning materials
      (browser) on one screen and studio on the other.
    • Maximise windows to make the most of the screen space.
  2. Create a new Klang project called "Gain".
    • Use the ✚ add button in the Settings panel.
    • Enter "Gain" as the project name (without speech marks)
      and select Klang to create a new project file (Gain.k).
  3. Copy our code (right) and paste it into the project.
    • The names in our code must match the project filename, so the
      MyEffect object (and its constructor) have been renamed "Gain".
    • By default, new projects already include a basic gain effect,
      but you should practice selecting, copying, and pasting code.
  4. Click Build to compile and run the plugin.
#include <klang.h>
using namespace klang::optimised;

struct Gain : Effect {

	Gain() { 
		controls = { 
			Dial("Gain") 
		};
	}

	void process() { 
		param gain = controls[0];
		in * gain >> out;
	}

};
(continued over the page )
PRACTICAL: Gain Effect
Use the guidance below to create a new project, add code, and build the gain plugin
then discover the different parts and features of Klang Studio by exploring the program.

Instructions / Tips (2/2)
  1. Test the plugin.
    • Use the test sounds and transport bar to play example audio files.
    • Check it works as expected - 0.0 = silence; 1.0 = full volume.
    • Observe the analysis plots (e.g. Scope) to see the effect.
  2. Tweak the user interface (UI).
    • Replace the contents of the quoted string in the controls array.
    • Click Build to recompile the plugin and update the UI.
    • Can you work out how to add a second dial?
  3. Finally, archive and back up your work.
    • Add // comments to the code to explain concepts you might forget.
    • Project files (.k) are stored in Documents > Klang Projects > src
    • Alternatively, you can also copy and paste the code into a text file,
      using any text editor or word processor - or email yourself.
    • Be sure to develop a robust naming, file, and backup system!
#include <klang.h>
using namespace klang::optimised;

struct Gain : Effect {

	Gain() { 
		controls = { 
			Dial("Gain")
		};
	}

	void process() { 
		param gain = controls[0];
		in * gain >> out;
	}

};
Module Complete

This module explored core concepts in digital audio, signal processing (DSP), and programming,
while also introducing the technologies used on the course and developing our first plugins.

KEY CONCEPTS

  • Digital audio is the representation of sound by numbers (typically in the range -1.0 to 1.0). An analogue-to-digital converter (ADC) measures the amplitude of sound at regular intervals, dictated by the sample rate (e.g. 44,100Hz).
  • Digital signal processing (DSP) is the process of manipulating sound as numbers. Most audio processing is based on simple mathematical operators (add, multiply), used in combination to generate and manipulate of signals.
  • To output the result, samples are converted back to analogue sound by an digital-to-analogue convertor (DAC).
  • The amplitude (gain) of a signal can be changed by multipling (*) it by a scaling factor, or modulating it with another signal. Low-frequency amplitude modulation produces a tremolo effect; higher frequencies produce amplitude modulation (AM) synthesis resulting in new spectral content (sidebands).
  • Signals are mixed by adding them using the + operator, which can also be used to apply a constant offset.
  • Audio processes can be expressed using block diagrams, which are directed graphs that show signal flow, inputs, outputs, and components within an audio process. Block diagrams act as blueprints that can be realised in code.
  • Code expresses audio processes as sets of instructions (source code) to generate or manipulate data, executed by the computer. Languages like C++ compile the code to run natively on the CPU, for best performance.
  • The compiler builds code into an executable form, but can also be a rich source of information (warning, errors).
  • Klang is an extension of C++ designed for audio, designed to make it more accessible and expressive for digital signal processing (DSP), making it easier to develop portable, high-performance audio processes in C++.
  • C++ (and Klang) are designed for object-oriented programming (OOP), where related variables and functions are grouped into logical structues, allowing complex systems to be modularised and broken down into simpler parts.
  • Klang provides syntax, semantics, and objects for audio, representing signal flow with the << and >> operators.
  • Curly brackets, known as { braces } group code into functions and objects to structure and breakdown complex programs into manageable parts. As in maths, brackets ( ) help make the order of operations clear (as in BODMAS).

PLUGINS

  • Gain Effect - a simple level (or volume) control that varies the amplitude of a signal.

NEXT MODULE

  • MODULE 2 : Distortion