Right, so after being dead for a few months, someone used phoenix down on me and so I made a cute little software synthesizer in plain C. The runtime uses only integers, so I’m hoping to port it to a microcontroller like the AVR in my Arduino. So far it’s done a monophonic rendition of the intro of the Super Mario Bros. overworld theme. It used a variable pulse width square wave with amplitude modulation. I just had to hard code the notes in C, which was laborious.
I’ll make a simple tracker for it once I clean up the code a bit and add some more features, like PCM and noise voices. It can do realtime audio generation if you pipe the output into /dev/dsp on a unix or unix-like system. I dumped the output into a file, imported the raw data in audacity as 8 bit unsigned integers with the appropriate sample rate. The sample rate is hard coded into the frequency table file in the source code. Luckily I made a program in C to generate those for me. I’ll go into more of the technical details later. For now, some wave files!
The very first one, firstnoise8000, is the very first thing that came out of my program. With a samplerate of 8000, it’s suitable to be piped to /dev/dsp. It sounds gritty because of the low samplerate. The next one, firstnoise 44100, is the same samplerate as a standard audio CD. Also probably most music you have in whatever mp3 player you may or may not own. It’s much clearer. I also played a bit more with some extra junk at the end. The end bit is two square waves. One is almost the A above middle C, 440 Hz, and the other is detuned down by sort of one tick.
Those I made and experimented on October the tenth and eleventh. On the twelveth, I drove over to a friend’s house to drive them to an appointment. Their parents were gone, but they finally awoke and let me in. They promptly fell into bed again. I spent just under an hour making this short bit of actual music. I incorportated both waveforms I have successfully programmed, square with variable pulse width and sawtooth. I intend to make something that’s like a sawtooth with variable pulse width, but this one I tried to make as computationally light as possible. At full volume, it does this:
The free running counter that describes where in the waveform a sample exists is unsigned 16 bit. The output is signed 8 bit, so I shit the most significant byte down, so it’s 0-255 and move it down so it fits in the signed integer. At a volume that is not a power of two minus one, it does this:
This is the only one so far that has division in it. I avoid it because some low power devices don’t have division as a hardware feature, so it can be slow. 8 bit AVR microcontrollers are an example of this. At powers of two, a switch case substitutes bit shifting for division. A single bit shift down is the same as dividing by two but very computationally light. This is what it does at a volume of 63:
Right, now to the music. It’s an excerpt from the boss music of Sonic the Hedgehog 2 for the SEGA Genesis. A game I played in my childhood and is one of my all time favorites. Wikipedia says it’s the second top selling game for the Genny.
The bass is cranked out by the sawtooth. The lead is the square wave. At the start of each note, it starts out at middle pulse width and gets one smaller each sample. That argument is an unsigned 16 bit integer, so that’s not incredibly fast. I looped it 4 times in audacity so you could get a feel for it. I also uploaded the version where it stayed as a normal square wave for comparison.
I’m not sharing the source code at the moment. It’s incredibly dirty and hacky. My next post about it will include the source code and it will have more features like noise generation and some PCM audio. I’ll also figure out how to interface it with SDL audio. A simple tracker will probably come after that. Because the voices are separate bits of code, I’m not sure how I’ll interface them with the tracker. It either needs to be compiled into the tracker or be linked dynamically, which I’ll have to learn and is also OS dependent. Or I could use a scripting language, like python. A microcontroller demo will be soon.