system performs accurately under the following constraints. The keys must be pressed one a time without
extreme pressure or speed. These limits
account for the fact that the midi protocol allows many different
functionalities whose implementations vary from keyboard to keyboard and
instrument to instrument. Implementing
these functions require a thorough knowledge of the
system is affordable and easy to use since it uses plug and play technology,
i.e. things don’t need to be configured or installed. However, it can be improved by sending the
Inputting a clean signal to the UART
We first used a 4N35 optoisolator manufactured by Fairchild. We found that using a resistor value of 2kΩ for R2 - the resistor at the input of the UART- we were unable to get a voltage level greater than 2.5V at the UART input. While, when we used a 280Ω, the voltage level was close to 5V but the signal was very distorted. We found that using a different optoisolator, in particular HP6N138, with a R2 resistor value of 2 kΩ fixed the clean input signal problem.
Reinitializing the note_counter properly is critical to determining the note type since this variable keeps track of the duration of a note. The variable should be reset to 0 when a note starts playing and, once the contents have been stored, when a note stops playing.
Function calls are expensive operations since they require stack space, a limited resource. We ran into many problems all based on the stack space limit. The biggest problem was auto scrolling. We initially wrote an auto scrolling function which was called in draw_note( ). Using this function caused many random visual artifacts on the TV screen. This problem was fixed once we just inserted auto scrolling code wherever we needed to auto scroll.
We encountered a second instance of a stack limit problem when clearing the screen. We have a clear_screen( ) function which draws an empty sheet music by first clearing the screen and then redrawing the staffs and G-clefs. We found that we can call this function in initialize( ) but not in other functions since it would cause visual artifacts on the screen. This was because the function was too slow to call when the television refresh code was running. Cycling through the entire screen array was too expensive. Also, calling video_line() several times in order to draw staff lines took quite a bit of time. This is because using this routine requires a function call to video_line() which subsequently calls video_pt(). Nested function calls are very time and stack expensive. We fixed this problem by in-lining code to clear the screen and by optimizing our screen clearing code. Optimizations included direct memory copies when possible as opposed to call to the note drawing functions.