Music Synthesizer
Joshua Wong
Fei Wihardjo
CS122A
The music synthesizer plays musical notes up to 3 octaves from low A to high A. The synthesizer allows user to either (1) play a song from the list of pre-programmed songs in the song library or (2) create a new song into the synthesizer by entering the appropriate notes using the attached keypad.
Upon start up, the user will be prompted with the greeting: "WELCOME TO MUSIC SYNTHESIZER ..." followed by the main menu:
OPTIONS:Option "1: Create Song" allows the user to create a new song and play back the newly created song.
1: Create Song
2: Play Song Library
3: Press * to Quit
Enter Option:
Options:Selection "1: Enter Note" will further guide the user to enter the note(s) using the keypad.
1: Enter Note
2: Play Back Song
3: Clear Hist
Enter Option:
Option "2: Play Song Library" allows the user to select from a selection of pre-programmed song. There are currently four (4) songs available in the song library that the user can choose from.Selection "2: Play Back Song" will play back the newly created song or note(s).Enter Octave (1,2,3):"1" corresponds to the lowest octave, "2" to the middle octave and "3" to the highest octave. Then the user must further specify if the note to be entered is a sharp or a natural note.Sharp(Y/N)?Answering "Y" means the note to be entered is intended to be a sharp note; "N" will indicate a natural note. The user will then be prompted to enter the note:Enter Note:Selection "3: Clear Hist" clears the playback buffer so that the user can create a different song.
Option "3: Press * to Quit" allows the user to exit the music synthesizer. The LCD will display "End."Options:After the user selects an option, the LCD will display "Playing Song..." while the synthesizer is playing the selected song.
1: Nowhere Man
2: Fur Elise
3: Air
4: Silent Night
Enter Option:
Note: the user will get "Invalid Input" prompt for any unacceptable input.
Hardware
We use an XS40 board, an 8051 chip, a keypad and an LCD. The
keypad is the input device that accept the user entry and the LCD
is the monitor display to interact with the user. We connect the
keypad to port 1 of the 8051 and the LCD to port 2 and port 3 (pins 0-1)
of the 8051. We use port 0 (pins 1-6) of the 8051 to communicate
to/from the XS40 board of user input/selection. We synthesize the musical
notes by generating square waves on one of the output pins of the XS40
board. We use 12 MHz clock as the reference frequency and design
a divider process to generate frequencies of the musical scale, i.e. from
440Hz to 1760Hz (low A to high A). The processor will write to the
memory mapped register a number between 0 and 35 that corresponds to to
the notes A, B, C, ..., G# for 3 octaves.
Software
There are 6 bits connecting the 8051 and the 8031 to interact with
each other. The software on the 8051 interacts with the user and
conveys the user request/input to the 8031, while the software on the 8031
executes the request and returns the status after the execution.
Note: We will refer to the 6 bits as "Select" from here on.
The playback was implemented by taking in the octave, optional sharp, and the letter of the note, and storing the note's converted signal into a playback buffer. Upon playback, an encoding to signal the start of the playback is sent to the FPGA board, and the signal for the subsequent notes are sent over the 6 bit bus, where as each note has a unique 6 bit encoding.
The 8051 follows the following logic. A finite state machine was create to implement the transitions for the various menu options. Since we interfaced two 8051's, the transitions from state to state were implement through an artificial clock cycle delay. (refer to 8051.doc for the state diagram and calc.c for the actual code):
Inactive: Select = "111111"Get "Menu"
if Menu == CreateSong
{Get "NoteOption"}
if NoteOption == Enter Note
{while (buffer not full and !Quit)}
{Get Octave}
Get SharpNoteIndicator
Get Note (see NoteEncoding.doc for the bit patterns corresponding to the musical note A - G#)
else if NoteOption == PlayBack
{Select = "000111"}
while (!EndOfPlayBackBuffer)
{Select = Note}
Select = "111111"
else if NoteOption == ClearHistory
{ClearPlayBackBuffer}
else If Menu == Enter Song
{Get SongOption}
if (SongOption == NowhereMan) Select = "000001"
else if (SongOption == FurElise) Select = "000010"
else if (SongOption == Air) Select = "000011"
else if (SongOption == SilentNight) Select = "000100"Wait until Select = "000000"
else If Menu == Quit
{End}
On the 8031, we download the following logic (refer to 8031.doc
for the state diagram and main.c for actual
code):
Inactive: Select = "111111"while (1)
{if (Select = "000111")}
{Get Select = Note}
Play Note
else if (Select = "111000")
{Get Select}
if (Select == "000001") PlayNowhereMan
else if (Select == "000010") PlayFurElise
else if (Select == "000011") PlayAir
else if (Select == "000100") PlaySilentNight
Set Select = "000000"
1. calc.c
2. io.c
3. io.h
4. main.c
5. wrled.vhd
6. ctrup.vhd
7. play.vhd
8. xs40.vhd
9. final2.ucf
10. NoteEncoding.doc