An Update: I’ve made considerable progress in improving the quality of the audio output. In the prior post, I was generating a square wave with the pulse frequency determined by an input from a capacitive sensor. It sounded, to put it succinctly, awful. Since I was generating it through the main loop() code, it was also susceptible to processor load problems, i.e. when an analogRead() was done, it would stop the waveform generation and start it again for ~100mS. I’m now using interrupt-driven Pulse Code Modulation to generate an arbitrary waveform, and it sounds surprisingly decent, actually.
It’s Like This, Y’all: Since with this setup I can generate an arbitrary waveform, I first spent some time investigating what makes a tone sound musical, or not. I started by taking a recorded piano key and doing a frequency spectrum analysis of it in Audacity. Here’s what that looks like:
And the accompanying spectrum analysis:
You can see that the strongest tone is at the fundamental frequency of middle C, 261Hz. But there are also spikes at the harmonics of that frequency, e.g. 523Hz, 784Hz, 1046Hz. Interestingly enough, the strongest harmonics are those corresponding to powers of 2, i.e. f * 2n. I’ve read that even-numbered harmonics are more pleasant-sounding than odd-numbered harmonics, and this would seem to support that idea. Also, as you add in the odd-numbered harmonics, the waveform approaches a triangle wave, which is definitely less pleasant to listen to than a sine wave.
Thus Informed, I started working to create a waveform of my own. I set up a frequency and a bunch of multiples of it in Audacity, and played around with increasing or decreasing the amplitude of specific overtones, until I had a sound I was happy with, like so:
From this I discovered that the undertone (1/2 * f) and other partials make a huge difference in the quality of the tone. I wanted to post this file up so other people can play around with it, but apparently with the associated sample files it’s around 50Mb, so you’ll have to recreate it yourself. I highly recommend it, it’s interesting. For comparison, here is a recording of a piano, middle c tone:
grand-piano-fazioli-major-c-middle1
And here’s my generated tone:
The generated version sounds different because there’s no envelope shaping on it– it’s just a constant amplitude. However, I if you listen to both a few times the tone is somewhat similar.
Next, I started working at digitizing a single waveform. I couldn’t figure out an easy way to do this directly from my generated tone, so instead I built the values in Excel:
I then copied the summed values (column N) into a 48 element char array in my Arduino sketch. If you want this spreadsheet, here ya go. Finally, here’s another Unintended Comedy Amateur Hour video of me playing around with the generated sound in the Arduino:
I’m going to talk a little more about the specific programming techniques I used to make the Arduino do this in a separate post.
Update: that post is here.