Laboratory 8 (team) -- Music synthesizer

Worth: 180 points
Assigned: 6 March 2009
Due: 17 April 2009
No late days may be used on this assignment.

Overview

This lab is the capstone project for the class. Your team will design, implement, and demonstrate a microprocessor-based music synthesizer on the DE2. Your synthesizer will run as a program on the E100 CPU that you completed in Lab 6. Your synthesizer will take input from the DE2's I/O devices (e.g., PS/2 keyboard, mouse, microphone, SD card, serial port, switches) and generate music on a speaker connected to the DE2's line out connector and other output on the DE2's I/O devices (VGA, LCD, LEDs, serial port).

Your team will have considerable freedom in designing your synthesizer. For example, your team should think about:

Digital audio

Sounds are pressure waves in some material (usually air). A sound is created by a disturbance that generates a pressure wave. That pressure wave travels to your ear, and your ear sends signals to your brain that you interpret as sound.

Different pressure waves lead to different sounds. When you strike a tuning fork, it produces a pressure wave that is a sine wave of some frequency, and we hear that as a pure tone. High-frequency sine waves lead to high-pitched sounds; low-frequency sine waves lead to low-pitched sounds. Remarkably, all periodic signals can be represented as the sum of multiple sine waves of various frequencies, amplitudes, and phases (take EECS 216 to learn more).

Digital audio refers to samples of these pressure waves. We can store the "shape" of a wave by sampling it at a high frequency. Later, we can reproduce the pressure wave by sending these samples to a speaker, which vibrates according to the sampled value and recreates an approximation of the original pressure wave. Here's a good tutorial on digital audio.

Your synthesizer will generate sound by sending samples to the speaker controller, which forwards those samples to the DE2 line out. For example, if you send samples that approximate a 440 Hz sine wave, then the speaker controller will produce that sine wave on the DE2 line out connector.

Each sample sent to the speaker controller is a 16-bit, signed value in the range [-32768, 32767]. A value represents the magnitude of the wave at an instant in time. The speaker controller produces sound at an 8 KHz sampling rate, so the time interval between samples is 0.125 ms. For example, the following samples represent a sine wave with amplitude 1024 and frequency 440 Hz. There are 19 samples before the samples start to repeat, so one period of these samples covers a time span of 2.375 ms (which is approximately the period of a 440 Hz sine wave).
Samples
0
346
652
881
1005
1011
897
677
376
32
-316
-627
-864
-999
-1015
-912
-700
-406
-64
repeat...

The samples you send determine what sound gets produced by the speakers. Increasing the amplitude of the samples increases the volume. Increasing the frequency of the samples (i.e. shortening the period) raises the pitch.

A sine wave of frequency 440 Hz corresponds to the note known as concert A; this is the note that an oboist plays at the start of an orchestra concert and sounds like this.

In western music, there are 12 notes in an octave, e.g. A, A#, B, C, C#, D, D#, E, F, F#, G, G#. After that, the names of the notes start repeating. The frequency of each note is approximately 1.059463094 times the frequency of the note below (1.059463094 = 21/12). E.g., the frequency of the A# directly above concert A is about 466.2 Hz). Because there are 12 notes in an octave, the note that is one octave above concert A (which is also called A) is double the frequency of concert A, or 880 Hz. Of course, your synthesizer may use a different scale than that of western music.

Tips

When writing large programs, it is essential to have consistent, clear structure. Divide your program into well-defined functions with clearly documented interfaces. Break your program up into multiple files (e.g., each device driver should be in its own file). This will help you work in parallel--different people can work on different parts without needing to understand implementation details from the other parts. Use consistent, meaningful names for variables and functions, e.g., for return addresses, constants, and instruction labels. We suggest you prefix labels with the name of the function or file in which the label occurs.

We recommend managing your files with a revision control system, such as SVN. Revision control systems make it easier to coordinate between multiple people and help you manage multiple versions (e.g., if your new version has a bug, you can quickly get back to an old version). Here is a tutorial for the SVN revision control system.

Your program will probably be simultaneously managing multiple devices and tasks. For example, you might want to read keyboard input at the same time as sending sound samples to the speakers. To do this, you'll need to avoid waiting indefinitely for slow input devices. Otherwise, the sound from the speakers will pause while you wait for input. You can avoid waiting for slow input devices by first checking if the input device is ready with input and only reading the device if it is ready. If the input device is not ready, you can continue with other tasks, such as sending sound samples to the speakers. This style of programming is called event-driven programming.

Turning in your project

Your project will be evaluated based on your music synthesizer code, your oral project presentation (which should include a demonstration of your music synthesizer), and your final report. After the demonstration, one member of your team should submit a ZIP file that contains the following:

To create a ZIP file music.zip that contains a set of files and directories, run a command like:
zip -r music.zip file1 file2 dir1 dir2 ...
The ZIP file will contain the files and directories specified in the command (including files and directories contained within the specified directories). Another way to create the ZIP file is by right clicking on the directory you want to include, then selecting Create archive..., then entering an archive name ending in .zip.