|Testing and Design|
The tradeoffs in this project are mainly between speed and quality. In order to produce the best sounds possible we needed to use values with the highest resolution (i.e. floats) so that the envelope and waveform shapes are well defined. However, floating point arithmetic is extremely slow, and consumes too many cycles to fit within the wave generation interrupt used to update the PWM. Hence, in order to speed up the code we had to settle for less precise methods of modifying the amplitude of the waveforms. We first constructed most of the synthesizer using only shifts to raise and lower the amplitude, but we found that having only 8 steps and uneven division between the steps greatly limited our ability to create good quality sounds. To solve this problem we ended up switching to 8:8 floating point arithmetic, which provided to be an excellent compromise between the speed requirements of the PWM and the precision requirements for a good sound wave.
Other tradeoffs we made included running the PWM update interrupt with a prescalar of 8(the PWM stayed at full speed) in order to increase amount of operations we can perform between updates. Again, this lowered the quality of our sound, but it allowed us to fit in all the code required to properly update the PWM. Also, we had to limit the amount of polyphony we could use(down to 8), and the quality of our lowpass filter(down to pole) so that everything can fit.
The majority of the tasks we couldn’t accomplish were involved with the time limitation. We were unable to fit the code for the high pass filter into the wave generation interrupt and we were limited to 8 polyphony for the same reason. We also considered doing Karplus- Strong to simulate the plucked string sound, but the design for that algorithm was entirely different from the subtractor. It used a delay line to modify it’s frequency along with a feedback loop, hence our wave envelope modulation methods wouldn’t work with it. In the end, we decided that it would more efficient to just increase the quality and functionality of our subtractor than to try and implement an entirely separate algorithm just to create one extra sound.
Speed was one of the major concerns while designing this project. If the code is running too slowly to complete before the PWM update interrupt is turned on again, then the interrupt is delayed in executing. This causes the sound wave produced to be at a much lower frequency, since the updates are happening at a slower rate. Since the main function of a synthesizer is to create the correct waveform, it was of utmost importance that we kept track of how many cycles all the operations we added in took. To speed up the wave generation we used 8:8 fixed point math instead of floats, and limited the number.
The main accuracy we have to consider is how closely the produced wave meets the parameters we set for the synthesizer. We checked to see that the ADSR matched up with the parameters and that the frequency matched the pitch we were trying to play. Both of this was done with an oscilloscope. To check the ADSR, we measured how long each parameter took to complete using cursors. And to the check the wave frequency we used the measure function. The ADSR measured almost identically to our settings and the frequency error can be observed in the following table:
We suspect part of the error has to do with our oscilloscopes limitation in catching complete waves. Also as you can see the error range increases as we raise or lower the frequence away from A4. This makes since since we use A4 as the starting point, hence as you move away the arthemetic gets less and less exact as you multiply/divide it by the twelthroot(2).
There was very few safety considerations involved with out project since it only produces music. We used opto-isolators to prevent large currents from reaching the user, and also to prevent damage to the midi controller in case the MCU is shorted out or vice-verse. Outside of that, as long as we kept the speaker volume at a decent level there are nearly no risk involved with using our project.
To help the user navigate through the settings for the synthesizer we used an LCD to display all the settings. The ADSR are controlled by 4 potentiometer knobs that can be turned. The other functions are accessed via a menu controlled by 3 buttons that cycle through the following hierarchy: