Generate Real-time Audio on the Arduino using Pulse Code Modulation
So. There are a bewildering variety of options for generating sound via the Arduino, but I’m trying to make a real-time synthesizer, with the following features:
- Arbitrary waveform shape, including the ability to add harmonics for a more musical sound
- Generate any frequency dependent on sensor input
- Efficient processor usage to allow for effects such as reverb, echo, envelope shaping, etc.
- A minimum of external hardware
Audio output for the Arduino is pretty well-tilled soil, but surprisingly most of the previously published options are geared towards canned sound playback, or tone generation without a focus on musicality. I’ve implemented an algorithm called Pulse Code Modulation, and I think it has a lot of potential. Keep reading for an explanation of how it works and why it’s awesome.
Pages: 1 2

July 2nd, 2009 at 8:28 pm
Hey Max,
I like the stuff you’re doing with the Arduino (I got linked to this page from the Arduino forums)
I’m trying to get your PWM example to work. When I compile the code I get an error regarding this line: “if (waveindex > 47)”
It doesn’t recognize the parameter “gt”
What is this parameter? What does the semi-colon do in an if statement (I’ve never seen it before like this) and of what significance is 47?
July 2nd, 2009 at 8:40 pm
Nevermind, I guess the greater than symbol got formatted strangely in your example. Works like a charm! Cheers!
July 3rd, 2009 at 8:25 am
The ‘;gt’ is a WordPress bug, it’s supposed to be ‘< '. WordPress doesn't handle code posts very well.
The 47 is just the size of the sample array (48, because we're counting from zero) in this iteration of the code. In the final version of the code, posted here:
http://www.maxwellrosspierson.com/2009/06/20/arduino-thereminsynth-final-walkthrough/3/
I’m using a 36-sample array, and I’ve also coded that up properly with a #define value, rather than a hardcoded number.
July 16th, 2009 at 4:36 am
Hello Glen. I love your website.
I’m building a project right now or at least learning how to program the arduino. Anyways, I was wondering if you could suggest a piece of simplified code for me to produce a dual tone of 350hz and 440hz using your sampled sine method.
Any help will be greatly appreciated.
Thanks very much for reading.
July 16th, 2009 at 6:48 pm
Hi Richard,
I hadn’t thought of it before, but DTMF is a pretty ideal application for this code. You could create a sample of the combined frequencies the length of which will be the Least Common Multiple of the two frequencies, I think. The method I used to generate the sample is covered here:
http://www.maxwellrosspierson.com/2009/05/26/arduino-thereminsynthesizer-update/
But, for your application, you might be able to just generate the sine wave values inside the ISR in real time using the built-in Arduino trig functions.
May 19th, 2010 at 8:36 am
Nevermind, I guess the greater than symbol got formatted strangely in your example. Works like a charm! Cheers!
May 19th, 2010 at 1:23 pm
Hey Bruce, there’s a link in the post to download the source code. I would use that, since WordPress’s ability to post code correctly is notoriously troublesome.
October 9th, 2010 at 8:28 am
thanks Zeus I’ve found this page (and thank you especially!), now I finally (should) have understood how this stuff works and how to manipulate the sound at runtime!
d
February 22nd, 2011 at 7:34 pm
Thanks for this amazing info! am i correct in thinking that the code above, while showing two arrays (sine and sineovertones) actually only uses one of those arrays in the code? i hope so because i couldnt find SINE linked anywhere in the code.
i even deleted the array and heard no change in sound.
just wanted to check
thanks!
May 7th, 2011 at 10:30 pm
Technically, a signed char has a range of –128 to 127. A value of 128 + 128 = 256 won’t be usable by analogWrite().