Arduino FM MIDI Synthesis with Mozzi

This project takes the Mozzi library a bit further and combines the Mozzi example code for potentiometers, FM synthesis and MIDI into one.  If you are just using the code “as is” this is a beginner project.  To get into the detail of the code though takes it into “advanced” territory!

  • In Part 2 the code is further developed and more controls are added!

Warning! I strongly recommend using an old or second hand keyboard for your MIDI experiments.  I am not responsible for any damage to expensive instruments!

These are the key Arduino tutorials for the main concepts used in this project:

If you are new to Arduino, see the Getting Started pages.

Parts list

  • Arduino Uno
  • 2x 10k potentiometers
  • 1x 270Ω resistor
  • 1x 100nF capacitor
  • MIDI In device (see Arduino MIDI Interfaces)
  • Breadboard and jumper wires

The Circuit

ArduinoMozziMIDIFMSynth_bb

The basic sound generation is the same as for the Arduino PWM MIDI Synthesis with Mozzi, but I’ve added a resistor and capacitor to create a simple low-pass filter on the output from pin 9, as suggested in the Mozzi tutorial on output circuits.

I’ve added two potentiometers connected to analog inputs A0 and A1 to control the synthesizer parameters and MIDI is connected to the RX pin. Note that, as always, MIDI will have to be disabled to allow the uploading of sketches.

I’ve built this up on a proto-shield but you could easily do the same with a normal breadboard.

The Code

The code is a little more involved this time. Once again though if you just want to experiment you can upload the code and get on with playing about.

This is basically still the Mozzi_MIDI_Input example but now with added potentiometers and oscillators.

Find it on GitHub here.

Advanced Discussion

This code has two oscillators set up. aSin1 is the main “carrier” frequency and aSin2 is the “modulator” frequency.  The carrier frequency is set based on the MIDI note on messages received.  The modulator frequency is set as a ratio of the carrier frequency and that ratio is determined by the position of one of the potentiometers.

Oscillators in Mozzi have two functions to get them to progress to the next sample to be output.  Most oscillators use the .next() method – you can see this in use in updateAudio for aSin2.next(). But there is also a .phMod() method which applies modulation whilst deciding what the next output sample should be.

I’m not going to go into significant detail here – to be perfectly honest, I’m still working out how to use the Mozzi library, but the essence of the code I have so far is as follows.

  • The Mozzi updateControl function reads the pots, uses one to set the level of modulation (between 0 and 1023) and one to set the modulation frequency ratio to use (between 0 and 31).
  • The code uses the same envelope as used in Arduino PWM MIDI Synthesis with Mozzi which is triggered with a note on message and stopped on note off.
  • The frequency of the carrier oscillator is set by the received MIDI note and the frequency of the modulator oscillator is set as a multiple of the carrier specified by the modratio parameter.
  • The oscillators are combined in the updateAudio function, which has to be kept as quick as possible.

The main issue is keeping track of the size of calculated values and making sure they don’t overflow the size of the variables they are stored in.  All the main modulation and frequency variables are defined as ints – hence are 16 bit values.  The modulation calculation in updateAudio uses a built-in Mozzi type Q15n16 which is a fixed-point arithmetic variable with a 15 bit integer part and a 16 bit fractional part.

The Mozzi documentation for phMod() states that the fractional part of the modulation parameter represents a “full swing” of -1 to +1 in terms of “modulating the phase by one whole table at a time” so I’ve tried to scale the levels of the calculated parameter to reflect that full scale “swing” using a range of 0 to 65535.

You can get quite a large range of effects by changing the scale of the modulation parameter at this point.  See the comments in the code for details.

There is a TEST_PLAY mode.  If you uncomment this line, the code will “play itself” – i.e. generate an internal MIDI note on, then note off event which is useful if you want to experiment with the synthesis parameters without needing an external MIDI device hooked up to it.

There are several issues with this code as is.

  1. In some configurations I get a persistent background tone if I’m not careful and I’m not sure what causes it – it might be some weird aliasing in the software or might be a signal picked up in the hardware.
  2. Some values of modulation ratio and levels sound like they are causing clipping to occur so the scaling of all the steps in the calculations still aren’t fully correct for all values.
  3. This is using the principles from some of the examples that are called “FM synthesis” but I’m not entirely convinced what I’m doing here is genuine frequency modulation synthesis, but its still interesting.

Find it on GitHub here.

Closing Thoughts

I’m still not entirely sure I really understand how Mozzi is really working yet, so there is plenty still to do should I wish to.  This is a very basic example still, there is smoothing of frequency changes to look into, different waveforms, alternative modulation schemes, and so on.  It might be worthwhile taking more of the synthesis code from the FMSynth example and adding MIDI and an envelope to that rather than the other way round.

A simple addition to this setup though would just be to set the ADSR envelop parameters with more potentiometers to allow adjusting of the envelope.

Kevin

Leave a comment