(2 Weeks)
You may work in PAIRS for this lab.
Note: You need your own set of headphones to get the audio output for this lab.
WARNING: The audio output to headphones is quite loud. You probably don't want to put the earphones directly on your ears unless you have volume control on the headphones.
In this lab, you will design and implement a music player/recorder system. Ideally, music input would come from the keyboard, and be recorded into RAM. Music output will be produced by playing back the contents of RAM in playback mode, otherwise the output will be the current note from the keyboard. Unfortunately, there are some (undocumented) complications when trying to use the PS/2 port and the stereo codec simultaneously. Therefore, instead of using the keyboard for input, we will partition the RAM into two segments - one for the source (loaded with a .hex file), and the other for the destination. The RAM can easily be partitioned in half by holding the highest RAM line low when accessing the source partition, and holding it high when accessing the destination partition. Output will be through the 3.5mm stereo jack on the XSTends board to your headphones. You do not need a music background to do this lab, but if you do not have one (or even if you do), you will probably want to read this Micro-introduction to Music .
There are several functions that are required for the final design in this lab, but they can be implemented incrementally. We recommend that you create a simple test system, where you merely walk through the source RAM and generate the audio output. Once you have done that, you can expand the system to write to the destination RAM and generate the audio output at the same time. Now you can add RAM playback from either the destination or the source area and the other required features. It will be much better for you to have only part of the desired functionality implemented, but working 100%, than for you to have an "almost working" design for all the functions. (Part marks are available, but only for a functional implementation of each separate function.)
The system uses a 15 Hz clock (provided by the OSC4 component) to sample the input and play the music. The notes are stored in RAM using MIDI note numbers, which range from 0 to 127. Since the RAM has a data bus width of 8 bits, we store an extra bit for padding with each note. This way each RAM access reads or writes an 8-bit quantity for the MIDI note number. The provided MIDI_TONE unit takes MIDI note numbers as input and produces a signal with the correct frequency for that note. In order to do this, it must have a 50 MHz clock input. Just connect clk to pin 13, which is the 50 MHz board clock. Note that 15 Hz (15 samples/second) is not really adequate to get a "good" recording, since this can cause noticeable changes in note timing and duration due to missing first samples (key pressed just after clock) or extra ending samples (key release just after clock). However, a slower clock increases the length of music that can be stored in the 32 KB of RAM. You will probably not notice this problem, since the .hex files were generated using a program and not recorded from a source.
Question 1: How much music (time length of sample) can we store with our design? (There is 32KB of RAM, partitioned exactly in half)
Question 2: How much could we store at the CD-quality rate of 48 KHz?
Question 3: Taking into account ease of design, maximum possible length of recording and quality of recording, what would be the "best" (i.e. best compromise between all 3 factors) choice of sample rate in your opinion? Justify you answer.
The functions that your system should have are:
About Transposition: Move all output up or down by a certain amount. This applies to all playback from the source, in both PLAY SOURCE and RECORD modes. You should record the transposed (changed) notes in record mode. You should change the MIDI note value by the transposition value, which will be in the range [-12, +12] (one octave has a total of 13 notes (7 notes, plus the base note one octave higher, plus 5 accidentals. For our transposition of one octave, this gives us up to 12 different transposition values, since the base note is a transposition of 0). To transpose, just add the required value to the MIDI number. For example, transposing by +4 would move a C to E (C -> C# -> D -> D# -> E, 4 steps up), and transposing by -4 would move E back down to C.
CLARIFICATION: The source and dest RAMs
have their own address counters. The reset signal should set the "currently
active" RAM counter to 0. (i.e. if playing source, then set source addr
to 0, if playing dest, set dest addr to 0, etc...)
Similar to lab 4, you are using the RAM lines for multiple purposes simultaneously:
RAM read, RAM write, and LED output (bonus). Therefore you need a faster
clock in order to perform all these tasks simultaneously. Moreover, since
you are switching back and forth between RAM locations, you will need to
buffer your data to not affect playback and to allow copy from source to
dest.
You should also have LED output to display the state of the system:
On the XS40 LED:
Bonus (5%, to a max of 100%) : On the XSTend LEDs, show the amount of transposition. Use the first LED to indicate the direction of transposition, and use the second LED to display the amount (use hex digits for values larger than 9). As in lab 4, you will need to take into account that the XStends LEDs use the same lines as the RAM. You may want to use a faster clock in order to keep the display from blinking when you go to RAM. This is OK, but you need to ensure that it still plays at the same speed.
Feel free to change these units to make them fit your design, although changes are probably not necessary. Also note that your design will be quite complex, and will take quite a while to implement.
MIDI_TONE VHDL code (txt ) : tone generator using 50 MHz clock and MIDI note values. Note 0 is used for silence. Also, many notes (very high and very low ranges) have been omitted from the unit, and these will also result in silence.
SINEGEN VHDL code (txt ) : Sine wave generator module. Required for output to the stereo codec. A sine wave will generate a tone with the same frequency as the sine wave. The amplitude of the sine wave controls the volume.
SERIALIZER VHDL code (txt ) : Required for output to the stereo codec. The codec needs samples from a sine wave as input, but the data must be transferred to it serially. Also, the codec requires a master and serial clock, and a left/right channel select signal. These signals have a moderately complicated set of interdependencies and other specs from the codec that must be followed, so this unit takes care of all those details for you.
MIDI notes : which MIDI note corresponds to which musical note, for interest sake only.
Connect the units like this to get your audio output: (the note input
for the MIDI_TONE unit should come from the KB_MIDI unit or RAM, as appropriate
for the current state of the system)
Sample songs (HEX files) (as recorded to RAM, using a design similar to this lab... Don't expect too much (due to low sample rate)...)
[Return to CMPUT 329 Lab Home Page]