Arduino Tone Polyphony – Part 3

Having achieved my full 12-note polyphony both over MIDI and using built-in keyboard encoding, the last part of this experiment was to see what range was possible using this method for tones.  This project manages four octaves with 12-note polyphony and tuning that, whilst isn’t perfect, isn’t too bad either.

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

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

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

Parts list

  • Arduino Uno
  • 12x 10k resistors
  • 1x 10uF non-polar capacitor
  • Audio amplification
  • Arduino MIDI Interfaces for MIDI receiving
  • Breadboards and jumper wires

The Circuit

This is back to using the same circuit as described in part 1.

There is a problem though (you can probably hear it in the video).   There is some interference that appears to be related to the USB interface. I’ve tried two different USB interfaces but it is a problem with both.

I am not an electronics person though, so apart from adding some capacitors across power rails, I’m not really sure how to debug or correct something like this.  Of course, this is sending out tones over hand-inserted resistors in a solderless breadboard – so I’m hardly expecting Hi-Fi quality sound!  I might try adding a filter stage at some point.

But feel free to let me know in the comments if you know how to fix it.

The Code

The approach to supporting more than a single octave range of notes is to go back to removing the link between keypresses and tone generation.  This code does that by maintaining a playing[] list.  When a noteOn is received the required frequency counter is placed in a free slot in the playing list.  Once there are no free slots, no more notes will sound.  On receiving a noteOff the corresponding entry is removed from the playing[] list.

The range of frequencies has been expanded now to include all notes from C2 to C5.  My first try kept the 40uS TICK (as described in part 1) which wasn’t too bad until it got to the very highest notes.  B4 and C5 were almost a semitone sharp!

However running through the calculations again with a 30uS TICK shows that the range of rounded frequencies isn’t too bad at all.


There are a couple of entries higher up where the required frequency would sit on exactly a 0.5 TICK boundary.  Consequently when either rounding up or down, you’ll get a larger error.  On the whole the tracking isn’t too bad. Some of the 5ths sound a bit out, and might benefit from some manual calibration.

Examining the timings for the interrupt routine using my test pin again, we can see that for 12-note polyphony, when no notes are playing, the code spends approximately half its time in the interrupt routine and half in the main loop.  As more notes are enabled, the time in the interrupt routine increases, but it never gets to the point where no MIDI handling is possible.

With less note polyphony a faster TICK may be possible, thus improving the frequency tracking further.

Find it on Github here.

Closing Thoughts

It has been interesting to see how far I could push a standard Arduino Uno, and I think I am probably at my limit now.

The next step is probably to move the concept to a more powerful microcontroller platform.  As I’ve mentioned before, this might be a fun one to take to the Raspberry Pi Pico.



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s