“In our final project, we have built a multi-functional car controlled by a web application on the PC, which allows users to drive the car as well as play music from the interface on the website.
Driving Mode: Move toward one specific direction
Speaker Mode: Read .WAV files stored in the SD card and play it through speakers, as well as showcase the amplitude of the audio on the TFT display
Piano Mode: Play certain notes of one piano and display which key being pressed on the TFT
In general, we applied what we have learned in this course into this project and integrating many functions together was quite fun and a good learning experience.
Our group decided to pursue this subject as our final project because we can not only leverage what we have learned through this semester, such as generating PWM to run motors by output compare units, playing music through DAC, serial communication through UART, concurrent programming and etc, but also learn a lot of new concepts such as file system, operations on shared SPI channels, waveform audio file format and some modern front-end technologies.
The audio format to be played is .WAV and it stores data in “chunks”. There are two sections in the .WAV files: the header and the data. The header is the beginning of a WAV(RIFF) file. The header is used to provide specifications on the file type, sample rate, sample size and bit size of the file, as well as its overall length. The header of a WAV(RIFF) file is 44 bytes long. The data section is the individual samples. An individual sample is the bit size times the number of channels.
In the header section, for example, bytes from 40 to 43 give the actual filesize. So the filesize is given as
(byte43 << 24) | (byte42 << 16) | (byte41 << 8) | byte40
The Timer3 interrupt is enabled to transmit audio data to the DAC based on the sample rate of the music, and it is also easy to get the sample rate of the music given by
( byte24 | (byte25 << 8)) & (0xffff)
As for the data section, for 16-bit PCM files, the data is stored as 16-bit Signed samples, whereas for 8-bit PCM files, the data is stored as 8-bit Unsigned samples. The way the audio data is origanized is shown below. Considering the MCP4822 has 12-bit resolution, the audio samples are converted to 12-bit values along with channel specifications for the DAC. For mono files, both channels play the same value. As for 8-bit samples, the 12-bit data is obtained by bit-shifting left 4 times. For 16-bit samples, the 12-bit data is obtained by combining the 8 bits of the higher byte with the 4 bits of the lower byte.”