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:
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.
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