Tuesday, September 18, 2012

Dropping Beats (Almost)

This was an interesting week in my exploration of sound synthesis. I'll first sum up briefly what I erm, did:
  • Read chapters 1 & 2 of The Theory and Techniques of Electronic Music
  • Perused the first chapter of The Audio Programming Book, realized it was equivalent to walking through the first month of a basic programming class, and rued the hour I wasted attempting to glean any useful information from the chapter
  • Spent about ~12 hours setting up an environment in which I could program on an AVR microcontroller without having to work through the god-forsaken smoldering wreck of a program Arduino calls an IDE. More on this later
  • Developed a super simple square wave generator on an AVR microcontroller which uses pulse width modulation
  • Started laying out a design for a fast-PWM based sine wave generator for the AVR uc
So, sound and sound synthesis. Sound is essentially a waveform generated by some physical reverbration which travels through some medium, or not-vacuum. These waveforms can range through a variety of complexities, but are each periodic. As an aside, the neat thing about these waves is that we can describe each complex wave as a sum of (conceivably) infinite simple sinusoidal waves, à la the Fourier series. The Fourier series actually describes a technique of synthesizing complex sounds - additive synthesis.

At any rate, the difficulty with the creation of these waveforms arises when we look at how a computer represents data and the nature of said waveforms. A wave in its natural habitat is continuous, which is to say that its values are not countable or discernible; it is infinitely granular. However, the computer works in terms of discrete values, most notably ones and zeros.

As it were, we can represent these continuous waveforms discretely by providing an array of values in which each value in the array corresponds to a value at a particular point in time on the wave. The greater the number of values taken from a set time length (often the length of one period of the wave), the higher the resolution of the emulated wave. Using this array of data points, or wavetable, we can send these values to a digital-to-analog converter which will translate each word to a corresponding voltage level. The number of samples we send to output per unit time, or sample rate, is dictated by the frequency of the waveform when the size of the wavetable is fixed.

Wavetable synthesis is quite flexible, and while there are alternatives, it is effective for my purposes at the present time. Using multiple tables, I can superpose wave values at various ratios to produce a sort of additive wavetable output.

ENOUGH chit chat, on to the "doing things" bit!

This past weekend I spent [significant] time working with my Arduino microcontrollers in an attempt to produce a low-level, basic oscillator.

First off, I have to say this: Arduinos are neat little products, especially when first diving into microcontroller programming (or programming in general). They were perfect for when I first started writing code a year ago. However, this ease of use comes at a price. The Arduino libraries abstract away a load of low-level stuff which, while making many aspects of the board easy to use, adds serious overhead to the program and removes a lot of control from the client. On top of this, when using the IDE (though I'm not certain its even worthy of such a title), the Arduino avr-gcc configuration builds all the libraries automatically into your code, which adds about half a kB of dead weight if you're not using the libraries.

Given these issues and the time-sensitive nature of audio programming, I decided to dig into the Arduino in an attempt to gain more control over what is being loaded onto my board. As it turns out, my particular board centers around the ATmel ATmega328P microcontroller. It's a decent little 8-bit chip with some nice features; perfect for some simple proof-of-concept code which I hope to write. For the ATmel AVR microcontroller line, there has been written an open source set of libraries, called avr-libc that abstracts away the assembly language nonsense of the AVR chips without creating much (or any) overhead. The Arduino libraries are actually built on top of this code. So, the trick was to find a way to write code for my AVR chip without having to go through the Arduino libraries.

It turns out that ATmel offers a [real] IDE, built around Visual Studio 2010, for AVR UCs. I snatched this up quicker than an attractive girl can walk away from a computer engineer. However, and as it always is, this didn't quite work out of the box (much to the dismay of my blood pressure). Since the Arduino came with a bootloader loaded on the chip that wasn't completely compatible with any of the avrdude (the programmer for AVR UCs) bootloaders outright, I had to create a new programmer rule which sends the arduino config options to avrdude. By perusing a bit of the Interwebs and some minor experimenting, I managed to configure the IDE to work with the Arduino. After much of the headaches, I was finally able to have full control of what code went on my board.

The goal of this week's project was to get started with prototyping an oscillator on a microcontroller. My process went through several iterations.

First, I tried generating a sine wave by creating a low resolution, 8-bit wavetable (about 60 samples) and outputting the values to 8 pins on the Arduino. These 8 pins fed into an R-2R ladder with a voltage follower configuration to try and stabilize the output of the ladder. Unfortunately, this setup did not operate as I had hoped; hooking it up to an oscilloscope revealed that the output was just far too noisy. I think if I were to use this technique, a much higher quality DAC would be necessary.

Given that this approach failed, I went to the trusty ol' Internets to try and find something that could get me through this quandry. Through my searches, I found an interesting supplementary document provided for the ATmegaXX series microcontrollers by ATmel on the uses of fast pulse width modulation, or fast PWM. PWM is a technique used to emulate different voltage levels when only HIGH or LOW is available. By outputting a square wave with differing duty cycles, different average, or effective, voltage levels can be achieved. By varying the duty cycle over time and providing a high pass filter to smooth out the bumps, a sine wave can be emulated.

I fully intend on implementing such a technique soon, but first I thought it prudent to simply exercise my microcontroller programming muscles (which are quite a bit atrophied) by writing code to produce a simple 50% duty cycle square wave at a given frequency.

An important set concepts particular to microcontroller programming and pertaining to clocks and timer interrupts come into play with this code. Interrupts provide a way to execute time sensitive actions or perceive external input without eating up precious instructions in the main, uhm, "thread". In this case, we want an interrupt to trigger every time we want to change the output pin from HIGH to LOW as it corresponds to the frequency of our waveform. To do so, we'll set up interrupts to start an interrupt service routine, or ISR, every time the clock counter hits a certain value. After the ISR executes, the counter is reset, and the counting continues again.

The counter value at which the interrupt should trigger can be determined by using several factors: the system clock frequency, the desired output frequency, and the prescaler value. The system clock on this particular Arduino is said, by the datasheet, to be 16 MHz. We want to output a wave oscillating at 440 Hz (pitch A4). To do so, we must divide the clock frequency by twice the output frequency, since we need to toggle the output twice per period. The prescaler value is a way to control the resolution of the clock, since the timer compare registers are only either 8-bit (max 255) or 16-bit (max 65,535). We divide by the chosen prescaler, and voila, we have our counter value.

Here's the code:



And here's the output on an oscilloscope:


AND finally, the hardware (disregard the remnants of the R-2R DAC):


Next time, I'll delve into the mysterious and powerful of world of fast PWM! OOooooOOOo!!!! Other stuff may be talked about as well. We shall see.

--- end transmission ---

Monday, September 10, 2012

The Resource Hunt

Sound synthesis, as I have quickly come to discover, associates itself with a large range of topics in mathematics, electronics, and computation. It has been no small task to sieve through the cacophony which constitutes the Internet, but I believe I have produced several nuggets of gold through my efforts over the past week or so.

The resources which I have amassed thus far are follows:

  • Mathematics of the Discrete Fourier Transform with Audio Applications, 2nd Edition by Jules O. Smith III
  • The Theory and Technique of Electronic Music by Miller Puckette
  • The Audio Programming Book by Richard Boulanger and Victor Lazzarini
  • Sound Synthesis Theory (a Wikibook)
Of course, a plethora of Wikipedia pages and code library documentation will be supplementing the literature above.

The resources which I have compiled appear to be sound (pun!), but, as is the issue with leading any independent study, I will not know until I have invested any substantial amount of time into the readings. As I delve into each of these texts, I will be certain to provide my thoughts on the quality of the resource.

As an aside, since my intent with this study is to gain a working knowledge of software techniques of sound synthesis, I will be putting far less emphasis on Fourier mathematics as compared to outright sound synthesis/manipulation theory and algorithms.

For this week (09/10 - 09/16):

  1. read The Audio Programming Book, Ch. 1 (Audio Programming in C)
  2. read The Theory and Technique of Electronic Music, Ch. 1-2 (Sinusoids, amplitude and frequency; Wavetables and samplers); do the associated exercises
  3. peruse information on Discrete Fourier Transforms and Fast Fourier Transform techniques
  4. begin implementing a simple wavetable Arduino synth and test it using an oscilloscope
  5. blog about my adventures!
--End transmission--

Tuesday, September 4, 2012

Hello, World!

The purpose of this blog is to chronicle my work for ECE 4974, an independent study course in the Electrical and Computer Engineering Department at Virginia Tech. I intend to provide visibility to my work as I strive to accrue and apply knowledge about DSP, audio and music synthesis in software, and human-computer interfacing with respects to the arts and music. Ideally, I shall be making posts several times a week with information, ideas, and reflections about the information I have gathered throughout the week.

So, hello world! I hope my musings and discussions shall be enlightening, entertaining, and enkindling for you, the reader. I'm excited that you have decided to embark on this journey with me, so relax, indulge my verbose and often wayward writing style, and feel free to correct any heinous errors I might make. Happy coding!