Xuemin Hang: email@example.com
Marcel Xu: firstname.lastname@example.org
The code for direct digital synthesis was especially tricky to write. Although the range of audible music frequencies are low enough such that we can make use of interrupts that execute at a regular interval, we faced a lot of difficulty getting the output, be it a sine wave, sawtooth or simple square wave to sound clean. There was always an additional tingly noise which we could not get rid of. However, by writing the code in assembly language in main(), we could produce a clean and smooth wholesome tone for the same kind of output waves. We thus decided to use the assembly language approach for the music synthesis. The output computation in assembly language is looped continuously for 2000 cycles (2000 samples/256 samples per period ≈8 periods) before it exits so that the music keyboard buttons can be sampled again and the corresponding phase increments recomputed.
Waveforms for Musical Instruments
To build up our own musical instruments database, we looked up music literature online and obtained pictures of characteristic waveforms of various instruments. For the clarinet, flute, and trombone, we were able to find actual ratios of their various harmonics. By experimenting with the actual ratios and by trial and error using Matlab for other instruments, we came up with harmonic equations that produce waveforms resembling the characteristic waveforms of various musical instruments. We then proceeded to test the synthesized sounds in our program. After much fine-tuning in the lab, we were able to build up a decent collection of waveform equations that give fairly characteristic musical instruments sounds.
Scheme for Playing Chords
We make use of a direct summation of the digital output of each simultaneously-played note before outputting to the 8-bit DAC. The following diagram illustrates this summation scheme:
Modulating the Envelope for Various Instruments
Different musical instruments have distinct attack and evolution. Brass instruments have a large maximum amplitude attack that builds up over time. It can then fade off (giving the sonorous effect) or be held at constant volume for a period of time. Percussion and plucked string instruments sounds are relatively short-lived since they decay quickly exponentially after the initial impact. Since our music synthesis code is written in assembly language, we use the scheme of dividing by two (right shift by 1) multiple times to approximate the exponential decay.
Displaying Music Stave and Notes on TV
Compared to the challenging code for music synthesis, the code for the TV display was relatively easy to write. Using the existing infrastructure provided by Professor Land for the TV code in lab 4, it was easy to create functions that draw the music staff, music notes, flats and sharps, treble and base clefs on the screen. All we had to do was to figure out the coordinates of the various items.
Implementing the TV Games
The program for the TV games is based on generating a random number between 1 and 30, each of which is assigned a unique note with a sharp, flat or no accidentals. The random number is generated by running timer 0 at a fast speed and setting it to clear on compare-match with number 29. At a fixed time interval for each speed level, the note(s) assigned to the particular random number generated during that time is displayed on the stave. The program then detects the pushbuttons to see if the user plays the correct keys during the time from this moment until the next random note(s) is displayed, while making sure that multiple presses of the same correct note(s) do not score multiple times. In particular, for the game “Music Test 2”, the program is written such that playing only one note of the chord does not earn the player any point. Both notes of the chord have to be played together in order to score.
Since the timing intervals are set up such that one frame = 1/60 of a second, it is easy to implement the timing of the random notes display as well as the countdown timer for the game (at each speed level) to be over after one full minute.
The pushbuttons used for the music keyboard are simple mechanical devices that connect an individual wire representing each button to a main wire when the button is pushed. Connecting the main wire to ground would allow the button wires to be pulled to ground when the buttons are pushed. Therefore, the MCUs would be able to detect individual button pushes when the corresponding input port pins with internal pull-ups are externally pulled low.
Because we needed to use 2 MCUs, we had to solder our own STK500 boards. Soldering the 40-pin socket and all the i/o port pin connectors onto the solder board and testing that all the leads were well-connected proved to be the most challenging hardware task. All other pins for VCC, ground, AREF, crystal clock and manual reset were wired as described in class. A schematic of the solder board is shown in the Appendix B. The greatest problem that we faced came from the programming port. It took us many painful hours of debugging to finally discover that certain pins on PORT B had been too loosely soldered.
Detailed schematics of the audio and video setups of our project can be found in Appendix B.
We reused the TV code in lab 4 that Professor Land provided.
Things We Tried but Which Did Not Work
We thought of adding an additional memory feature that would allow the sequence of notes played by the user to be recorded and played back upon demand. However, due to limited port pin constraints, we could only implement it via the USART interface and control it using HyperTerm on the PC. We tried to store the identities of notes played in an array, but a huge two-dimensional array would be needed to be able to store chords. Even when experimenting with a one-dimensional array to store single notes, the playback did not sound like what it should have been. Worse still, normal execution of the music synthesis was also affected and the synthesized sound had an unusual tingly noise, similar to what we got when we used interrupts to execute the music synthesis. We thus abandoned the idea of implementing the memory feature.