When synthesizers first hit the scene back in the mid-20th century, many were monophonic instruments, capable of producing just one pitch at a time. This was a major limitation, and over time polyphonic synthesizers began to flood into the scene, greatly expanding performance possibilities. [Kevin] decided to build his own polyphonic synthesizer, but far from taking the easy route, he built it around the Arduino Uno – not a platform particularly well known for its musical abilities!
[Kevin]’s build manages 12-note polyphony, an impressive feat for the ATmega328 at the heart of the Arduino Uno. It’s done by running an interrupt on a timer at a steady rate, and implementing 12 counters, one per note. When a counter overflows, a digital IO pin is flipped. This outputs a square wave at a certain pitch on the IO pin, producing the given note. The outputs of 12 digital IO pins are mixed together with a simple resistor arrangement, producing a basic square wave synth. Tuning isn’t perfect, but [Kevin] notes a few ways it could be improved down the line.
[Kevin] has added features along the way, expanding the simple synth to work over several octaves via MIDI, while also building a small tactile button keyboard, too. It’s a project that serves as a great gateway into basic synthesis and music electronics, and we’re sure [Kevin] learned a lot along the way. We’ve seen other microcontroller synths before too, like this tiny device that fits inside a MIDI plug. Video after the break.
9 thoughts on “12-Note Polyphony On An Arduino Synth”
Very clever! If I’m remembering right, this is the sort of deal you used to be able to get as a dedicated chip for electronic organs, called a “top octave generator” — you’d then use flipflops or binary counters to divide the square waves down to lower octaves. If your TOG gave you an A8 (= 7040Hz), then each divider would split that in half for A7=3520Hz, A6=1760Hz, A5=880Hz, A4=440Hz, and so on. As synthesis conquered the electronic organ, and digital overtook analog, all these chips were discontinued long ago.
(My own efforts in MIDI polyphony went the easy route, using the Teensy Audio Library to build a round-robin of eight oscillator-envelope-filter blocks to feed a mixer. Never got it to more than a novelty, taking USB-MIDI from a computer and spitting out assorted waveforms; I should dust that off and see what Teensy 4s can do with it.)
I built synths using those top octave generators back in the 70′ and 80’s. But they started at a much higher frequency to give more accuracy on the divide down. In any case, I really like the hack of the analog summation. But I think you could improve this project by implementing numerically-controlled oscillators (NCOs) like are used in Direct Digital Synthesis (DDS) systems. The way these work is that at each tick you calculate how much further you are in each waveform (i.e the phase), and then lookup what value you should output. That can be as simple as an interpolated lookup table. You can run many NCOs, each at different frequencies, and then sum them all together to find the appropriate value to send out your DAC. Keeping in the spirit of the project, the DAC can be implemented as an R2R ladder off of a bunch of digital outputs. To be fancy, you should low pass filter and amplify the result. Not only would this technique give more accurate frequencies and potentially more polyphony, you can also use different waveforms – you aren’t limited to square waves. They can even be different for each channel. To go even further, it’s not hard to add attack envelopes as well – that’s just another thing that accumulates phase.
Are you talking about something a bit like this:
I’ve tried to include a range of digital synthesis methods on my blog, but this particular project was simply starting from the “hey, someone has managed a three note tone() function for the Arduino, I wonder if its possible to do more” position just to see how far it could go.
Thanks for the comments on “top octave generators”, all fascinating stuff – I’ll go and have a read.
Shameless plug to a saved version of my old web-page (thank heavens for people who save this stuff, I lost it long ago).
I did a DDS with an R2R ladder back in 2001.
When I saw this project, I immediately thought of doing a many-notes polyphony version using DDS.
Very simple, just have a bunch of adder constants into a sine-table (or whatever waveform).
Step them at a suitable clockfrequency and mix the various values.
But, there – “mix”- is where the problem lies as you only have 8 bits. You can easily add the tones together in a 16-bit variable, but quantizing down to 8 bits in the end is going to be messy for a number of reasons.
With 16 (or more) bits of output, this would have been much, much easier.
One way, that would give some headroom would be to have 6-bit (or maybe even 5-bit) samples from the tables, that’ll allow you to add 4 (or 8) notes without clipping.
As the waveforms are not coherent, you might get 16 or more notes before serious clipping would occur.
Output could (and even in your project), be PWM, requiring only ONE pin instead of 8. A simple low-pass filter kills the clock frequency.
For those interested in digital mixing and stuff, I found some interesting articles here:
Especially the one about “Dither”.
Right on on with 16-bit. These days with SoA DSP MCUs this should be routine. Now in fact, with stacked GPUs, the World is wide open, with no ‘pin’ or bandwidth limits. Even I, working medical ultrasound imaging, run this kind of DSP on my “junk” stuff. Give me a challenge!
Twelve! :-D Great hack!
That’s a clever way to make polyphony on Arduino !
A few years ago I played with this library, that gives four polyphonic voices from lookup tables : https://github.com/dzlonline/the_synth. I’ve modified it to have height voices, it works great. :)
Nicely done with the interrupt timer! I have not seen this much polyphony on an arduino without some sort of shield. Keep up the good work :)
Anybody has heard of Tim Follin? You should. In fact, an article about him would be the first retrotechtacular post I’d read in years.
Please be kind and respectful to help make the comments section excellent. (Comment Policy)