220a Final Project
An FM Synthesizer built with STK for use with Pd
(and other audio applications)
Sean Bratnober
Fall 2006
For my final project
I implemented a four operator FM Synthesizer using STK (Synthesis Tool
Kit). This synthesizer is written with platform-independent C and
C++ code so that it can be easily ported to other audio applications,
like Pd, Max/MSP, and applications that support VST or Audio Unit
plugins.
A brief explanation of FM Synthesis
About the FMSynth instrument
About STK
Building the FMSynth instrument in STK
FMSynth Source Code
FMSynth - A Pd implementation for Linux
FMSynth - A Cocoa implementation for OS X
A brief explanation of FM Synthesis
FM (Frequency Modulation) synthesis is a type of audio synthesis where
the frequency of one waveform is modulated by the output of another waveform.
The frequency modulation tutorial patch in Pd (A07.frequency.mod.pd) is
an excellent introduction to the basics of FM synthesis.
This represents FM synthesis at the most basic level. This patch
has two operators (operators are synonymous with oscillators and other
unit generators like square and sawtooth wave generators), with the top
operator modulating the one below it. The output (bottom) operator
is modulated by adding the output of the modulating (top) operator to
its frequency. The modulation index effectively acts as the gain
of the modulation operator, and it determines the range of the
frequency of the output operator. In this case, the 440Hz carrier
frequency of the output operator is modulated from 202Hz to 678Hz
(440Hz +/- 238Hz) at a frequency of 667Hz.
The following two images (thank you Wikipedia) represent a 220Hz
carrier (output) tone modulated by a 440Hz modulating tone with 4
different modulation indices. The first image is the time domain
representation of the tones, and the second image is the frequency
domain representation of them.
The soundfile for these tones is here:
FM tutorial tones
By modulating the frequency of the bottom operator, we can generate
different timbres from it. In a typical FM synthesis
configuration, we play different notes by setting the frequencies
(before modulation) of our operators at ratios of the frequencies of
each note. Setting
the modulating frequency to a harmonic
relationship with the carrier frequency (ie, the modulating frequency
is an integer multiple of the carrier) can generate harmonic tones from
the carrier operator. Some FM synthesizers (like my FMSynth
instrument) also allow you to set certain operators to a fixed
frequency (before modulation) to create other interesting sounds.
The following patch (note: you must have the output~
patch in your directory for this to work) updates the tutorial patch to
allow control over the ratios of the operators (the first patch uses
fixed frequencies.)
The outputs of the operators can also scaled with envelopes (like ADSR)
to add another dimension to FM synthesis. This patch adds ADSR envelopes to the generators of the tutorial patches (note: you must have the output~ and adsr patches in your directory for this to work).
A typical FM synthesizer will use different arrangements of operators
(these arrangements are called algorithms) to generate different
sounds. The FMSynth instrument uses four operators that can be
arranged with the following eleven algorithms:
About the FMSynth instrument
As mentioned above, the FMSynth STK instrument contains four operators
that can be arranged with eleven different algorithms. The
operators can be set to use configurable ratio or fixed frequencies,
and the gains, modulation indices, and ADSR envelope parameters of each
operator can also be controlled. The operators can also be configured to use sine, sawtooth, square, and noise unit generators. All of these parameters can be set directly (with supported audio applications) or through MIDI messages.
About STK
From the STK website:
"The Synthesis ToolKit in C++ (STK) is a set of open source
audio signal processing and algorithmic synthesis classes written in
the C++ programming language. STK was designed to facilitate rapid
development of music synthesis and audio processing software, with an
emphasis on cross-platform functionality, realtime control, ease of
use, and educational example code. The Synthesis ToolKit is extremely
portable (it's mostly platform-independent C and C++ code), and it's
completely user-extensible (all source included, no unusual libraries,
and no hidden drivers)."
Building the FMSynth instrument in STK
The FMSynth instrument class was built with the following four STK classes:
FM
The FM class provides wavetable synthesis of sine waves for a
user-specified number of oscillators. The frequencies of these
sine waves are changed by setting the data interpolation rates of the
wavetables using a looping frequencies. Wavetable synthesis is
used instead of direct sine wave generation to reduce the computation
needed to generate the sine waves. Direct sine wave generation
involves computationally intensive arithmetic operations like
division.
BlitSaw
BlitSquare
The Blit classes generate sawtooth and sqaure waves using the band-limited interpolation algorithm described here:
Alias-Free Digital Synthesis of Classic Analog Waveforms
The discontinuities of sawtooth and square waves cause aliasing issues
when generated through standard wavetable synthesis. The BLIT
algorithm used in these classes provides a method of generating these
waveforms by using band-limited impulse trains. Proper
implementation of these waveforms in the FMSynth instrument requires
harmonic limiting to avoid aliasing.
Noise
This class generates white noise based on a random number generator.
Since white noise, by definition, generates all frequencies at
random, its frequency cannot be set or modulated. If a noise
generator is the output generator of an algorithm in FMSynth, you're
only going to hear noise.
FMSynth Source Code
FMSynth.h
FMSynth.cpp
FMSynth - A Pd implementation for Linux
FMSynthSTK-Pd.zip
Follow the README file for info on how to build this. The extern
has only been built for the PlanetCCRMA machines, but a little
tinkering should get it to work in other Linux environments. The
extern was built using Chris Chafe's STK extern build tools using
Scheme (thank you Chris!). I included the other STK instruments
he built as well. The FMSynthDemo patch displayed here is also
provided.
FMSynth - A Cocoa implementation for OS X
The XCode project for this is here.