FM Synthesis is an old-school way of generating musical instrument sounds, initially popularised by the Adlib and SoundBlaster PC sound cards in the late â€™80s (and, of course, in piano keyboards). Hereâ€™s an example of what FM Synth music sounded like in games. Ahh the nostalgia.

A friend who is a school music teacher found that his students all use the same identical samples for instruments for their creations. So I created YouSynth, a web app that allows you to create any instrument you like using a basic form of FM synthesis, and download that instrument as WAV file you can use anywhere, as well as play around with it using an attached MIDI keyboard. Please check it out!

So as to not leave out the maths teachers, I thought Iâ€™d write an article about how the maths for FM synthesis works! I think itâ€™s fascinating, hopefully you might too. My dream is that maybe a maths teacher somewhere would use this as an interesting demonstration of applied maths to pique their studentsâ€™ interest :)

To start with, hereâ€™s the gist of it - for each sample, the value is:

```
sin(
carrierFrequency * time * 2 * pi
+
sin(modulatorFrequency * time * 2 * pi) * modulatorEnvelope
) * carrierEnvelope
```

Now letâ€™s break that down.

The carrier frequency is the fundamental frequency of the note. Eg for A4, itâ€™s 440 Hz. For Middle C, aka C4, itâ€™s ~261.6 Hz.

For each note you go up (including sharps), the frequency is multiplied by `2^(1/12)`

.
The `1/12`

is because there are 12 freqencies in each octave when including the sharps.
The `2^`

is because frequencies double with each octave. Eg A4 is 440 Hz, and A5 is 880 Hz.

When working with MIDI, each note gets a number representation: C4=60, C#4=61, D4=62, etc.
To convert from a midi note to a frequency, the formula is: `440 * 2 ^ ((midiNote - 69) / 12)`

.

The time in the above formula is in seconds since the note started playing.
Since youâ€™d typically be generating samples at a rate of 44100 or 48000 Hz, to convert from
the sample number to the time, this formula applies: `time = sample / sampleRate`

.

The `2 * pi`

is necessary because sin repeats its output every multiple of 2 * pi on its input.
An interesting aside: Credible mathematicians consider that tau (2 * pi) should be taught to students
instead of pi, because it is so common that we need to double pi before using it, so why not just use the
double as the famous constant, then? See the Tau manifesto.

The modulator is the waveform that â€˜modulatesâ€™ the fundamental frequency. Think of it as the whammy bar on a guitar being wiggled up and down quickly.

Typically the modulator frequency is a whole-number multiple or fraction of the fundamental frequency. Eg for a fundamental of 440 Hz, the following modulator frequencies all sound â€˜niceâ€™: 110 (440/4), 146.7 (440/3), 220 (440/2), 440, 880, 1320, etc.

The envelopes control the amplitude/volume of the carrier and modulator over time. From initially zero, quickly up to 100%, then down to a sustained volume of perhaps 50%, where it remains while the piano key is held, then when the key is released, it gradually returns to 0.

A common strategy is the ADSR envelope.

During the attack stage: `amplitude = time / attackDuration`

.

During decay stage: `amplitude = 1 - (time - attackDuration) / decayDuration * (1 - sustainAmplitude)`

.

During sustain stage: `amplitude = sustainAmplitude`

.

During release stage: `amplitude = sustainAmplitude - releasingTime / releaseDuration`

.

To make more interesting sounds, other waveforms besides sine waves can be used. Some common ones are square, triangle, and sawtooth. Here are their formulae which repeat every multiple of 1 on the input:

- Sine
`= sin(x * 2 * pi)`

- Square
`= 4 * floor(x) - 2 * floor(2 * x) + 1`

- Triangle
`= 2 * abs(2 * (x + 0.25 - floor(x + 0.75))) - 1`

- Sawtooth
`= 2 * (x - floor(x + 0.5))`

So there you have it, the maths behind basic FM Synthesis. Thanks for reading, hope you found this fascinating, at least a tiny bit, God bless!

Photo by Vackground on Unsplash

You can read more of my blog here in my blog archive.

(Comp Sci, Hons - UTS)

Software Developer (Freelancer / Contractor) in Australia.

I have worked at places such as Google, Cochlear, Assembly Payments, News Corp, Fox Sports, NineMSN, FetchTV, Coles, Woolworths, Trust Bank, and Westpac, among others. If you're looking for help developing an iOS app, drop me a line!

**Get in touch:**

[email protected]

github.com/chrishulbert

linkedin