FM sound synthesis

FM synthesis can be used to make a more interesting sound that can be string-like, or drum-like, or just plain strange.

The basic waveform equation is:

wave = envelopemain * sin(Fmain*t + envelopefm*(sin(Ffm*t)))

For each of the envelopes, I used exponential functions, such that:

envelope =

Ao * e(-dk_rate*t) * (1-e(-attack_rate*t))

These exponetial functions are compactly calculated at each time step

as first-order differential equations, requiring one multiply each, if

the decay and attack rates are specified as the fractional change in

amplitude per decay sample. So a slow rate of decay would be 0.999 and a

fast rate 0.005. A fast rise would be 0.0 and a slow rise 0.99. Note

that for significant amplitude, you need the attack time to be shorter

than the decay rate.


fm envelope

All arithmetic is done in 16:16 fixed point for good accuracy and

speed. The 32-bit fixed notation gives enough dynamic range so that the

algorithm does not dither in the range of the DAC. The macros for fixed

point are given on a separate page.

The oscillators are implemented as Direct Digital Synthesis units,

accessing a 256 entry sine table. The output is to one channel of a

stereo 12-bit SPI attached DAC. (code, ZIP of project). A separate program

just outputs to damped sine waves to the stereo DAC channels. All

programs use Protothreads to control execution. About 13% of the cpu is

used (at opt level 1) to generate one FM synth channel. Examples at