Klang C++
Language Reference (draft)
|
klang is a language for the design and development of realtime audio processes in C++.
As a dialect of modern C++, klang enables synthesisers and effects to be written in clearer, more concise language, using the concept of streams and OOP to combine the performance of native C++ and clarity of visual/data-flow languages, such as block diagrams or patch-based tools like Max or PureData, and is designed to facilitate rapid prototyping of audio processing, as well as experimentation, knowledge sharing, and learning.
Designed for both professional and academic use, klang hopes to facilitate the sharing of DSP knowledge with the community-led development of an open library of reference examples.
NOTE: The klang language is under active development, so syntax may change between pre-release versions.
To use klang in a C++ project, simply include the klang.h header file in your C++ project.
#include <klang.h> using namespace klang::optimised;
Audio objects are then accessible using the klang
namespace (e.g. Effect, Sine). klang tries to use plain language to describe objects, so the namespace is used to avoid conflict with similar terms in other APIs or code. If this is not needed, add the using namespace
directive as shown above.
The core data type in klang is signal
, an extension of the basic C type float
with additional audio and streaming functionality. In many cases, signals can be used interoperably with floats, facilitating integration of klang with other C++ code, while enabling signal-flow expressions, such as in the following wah-wah effect ...
... where lpf
is a low-pass filter, in
is the input signal, out
the output signal, and mod
is a signal used to modulate the filter's parameter (~cutoff frequency), based on a low-frequency (3Hz) sine oscillator (lfo
).
DSP components, like oscillators or filters, are declared as objects (using struct or class) as either a Generator
(output only) or Modifier
(input / output), supplying functions to handle parameter setting (set()
) and signal processing (process()
) ...
Here, the Modifier
parent class adapts the LPF code so it can be used as before. Parameters have type param
, which is derived from signal
, allowing constants, floats, or signals to be used interchangeably with or as parameters. Code may use either signal (<<, >>) or mathematical (=) operators interchangeable, to allow you to express the audio process in a manner best suited to the context or other reference material. Filters are often described in mathematical terms, so you could also write: out = (a * in) + (b * out);
.
More complex audio processes are created by combining klang objects, as in this simple subtractive synthesiser:
This class supplies the Note
definition to be used as part of a synthesiser (Synth
- see the Examples linked below). It processes audio, but also handles events such as a note on, where the supplied pitch is converted to a frequency (in Hz) for use in the oscillator. By default, without code to handle a note off, the note and audio processing will be automatically terminated when one is received.
But most instruments continue making sound after a note is 'released'...
This example shapes the note and adds a release stage using an ADSR amplitude envelope. The ADSR
is a type of Envelope
that takes four parameters (attack, decay, sustain, release - set in on()
) and uses its output to scale the (*) amplitude of the signal. To add the 'release' stage and continue processing audio after a note off, we add the off()
event and trigger the release of an ADSR envelope. Now, process()
will continue to be called until you tell it to stop()
, which we call when the ADSR is finished (that is, adsr.finished()
is true).
For further techniques, see the Examples below.
The /examples folder contains an evolving selection of examples (and tests):
See https://nash.audio/klang >> KLANG EXAMPLES for online, interactive demos of the above.
This object defines the processing for a single synth note that can then be used in any audio C++ project, placing the following code fragments at appropriate points in your code (e.g. myEffect/mySynth mini-plugin or any AU/VST plugin, JUCE app, etc.):
For ready-made AU/VST compatible C++ templates for Xcode and Visual Studio, see the github.com/nashnet/myeffect and github.com/nashnet/mysynth repositories. rapIDE (Klang Studio) plugins also support a pure Klang live coding mode.
For more information about the project, or to get involved, email Chris Nash (klang@nash.audio).