Skip to main content

Let's Write the Program!

We have completed all the necessary parts required for developing the Software. From understanding SD-Cards as Storage Medium to choosing the right Audio Format to deal with, we have travelled a long way together in our quest to develop our own Music Player. From this post, we will start the last part of this project i.e the software development.
Let's divide the software into smaller pieces of code and we will then take a bottom-up approach to develop a finished piece of a efficient and user-friendly software. First, we will start with writing the parser of WAV file in C for our PC and then we will move to our embedded platform.
The Input to our WAV parser is a .wav file and it will show the header information as the output. We will create a structure and store the header info in it. The code will open the .wav file, parse it up to the "data" tag in the header and then map the structure from the start of the metadata and hence fill the corresponding values.
From the last post, we can understand the structure of the header and hence write the required code. The structure is named head and is as follows: -

typedef struct{
char fileformat[4];
int file_size;
char subformat[4];
char subformat_id[4];
int chunk_bits;      // 16 or 18 or 40 due to pcm it is 16 here
short int audio_format;    // Little or big endian
short int num_channels;      // 2 here for left and right
int sample_rate; //  Sample_rate denotes the sampling rate.
int byte_rate;            //  Bytes  per second
short int bytes_per_frame;
short int bits_per_sample; 
char data_id[4];                        // "data" written in ascii
int data_size;
}head;

Now we need to open the .wav file using standard file i/o functions along with declaring a pointer to the head structure. Using malloc we provide the required memory to the structure pointer we declared and then by fread() we can map the file onto the memory pointed by the structure pointer. Here we will use the sizeof() operator to define how many bytes we need to map. If these operations are completed successfully then we will have all the required information in the head pointer and now we just need to print the stored information.
The complete code is available on my Github repository. The code can be used to output the header of any .wav file available on the local directory of the project and also contains a sample wave file "blue.wav". The input to the console must contain the full name of the file as "file.wav". Now we can start writing the code for our embedded platform. The above structure can directly be copied into the stm32 code and we will use the file i/o options provided by the Fatfs module instead of the standard functions as we are using the sd card to store our music file. After we are done with opening the file we move to the next part and start reading the content of the file up to the "data" keyword, and then read 4 bytes of data and now our pointer is at the very start of the raw data section of the music file.
Now we will use the PWM functionalities of our hardware timers and provide each byte to the timer which will output the digital data in the form of a Pulse width modulated wave. This method can be used as DAC but is quite noisy and hence we will use an actual DAC in the future versions of this project.

Every RAW audio file has several parameters such as its sample rate, bit depth etc. The sample rate is very crucial as we need to provide the PWM with the same frequency as the sampling frequency as to have a reconstruction of the audio. Here we use the Timer interrupt capabilities to provide accurate timings. In our case, the recorded audio has a sampling frequency of 44100 Hz and hence we will configure our timer to provide an interrupt at the same rate. We can not use the timer API's inside our Interrupt Service routine so we will use a variable to check whether an interrupt was there and hence we can now output the sound using a Gpio and connect the speaker's Aux to GND and the Gpio.
The final code is available on the GitHub page and the breadboard circuit will look similar to this.


So, now we need to compile and flash the code into our MCU and if everything goes as expected then we will be able to hear the music with some noise. In the future, we will use DAC instead of PWM and make a PCB for our Music Player along with integrating a TFT lcd for user interface. Till then, Enjoy the MUSIC!.

Comments

Popular posts from this blog

Let's Build a Music Player!

Digital Music Player's are one of the many sensational devices that were developed in the 20th century. They have been around for a while now and have become a part of our life. In the last few years, they have been integrated within Smart Phones and hence, have reached the masses. Now, Let us try to dive into knowing how these devices work and I guarantee that we all would be fascinated by the kind of engineering which goes into making these magic boxes. There are various topics which must be covered in order to build our own music player and so there will be several blogs to build a SOUND foundation. Now let us make a list of the required components and then we will walk through each of them in the upcoming blogs. There are 3 basic parts which are required to build a device which can output Audio:- Storage Medium. Micro-controller. Audio Output device. We will store the required music file onto a storage medium as the onboard memory on a microcontroller is low...

SD-CARD

This Post marks the beginning of our quest to develop a simple Music player. SD stands for Secure digital and these small devices have been around for a while now. They contain flash memory and a memory controller which is given instruction by the main MCU. So our main objective here is to understand how sd cards work and how to interface them with a microcontroller. As to understand the working of SD card we need to dive into the world of transistors and bits! The Sd card contains solid-state memory also known as the flash memory which is a type of EEPROM i.e  Electronically Erasable Programmable Read Only Memory .  Flash memory stores information in an array of memory cells made from  floating-gate transistors . These transistors are used in different topologies as to store each bit. We will not program each bit individually as it will be time-consuming as well as an inefficient way to store the data. As to move to a higher level of abstraction, we need a way to ...

Automated Outdoor Lighting

This Project enables a person to make any Outdoor Lighting Automated i.e to switch On/Off according to the sunlight outside. If it is dark outside then the light will turn On and if it is daytime then it will automatically switch Off. This can be very useful for all Outdoor Lighting of various commercial buildings as well as for residential buildings. This can also be implemented in Vehicles which will automatically turn their lights On.  Our aim can be achieved by designing a proper transistor circuit and using a relay with it to control the high voltage network. T he Requirements Are: 1:- Bipolar Transistor(Bc 547) 2:-5/6v Spdt Relay 3:-Resistors(Around 4.5k And 3k Ohm) 4:-Light Dependent Resistor 5:-5v Power Supply 6:-Pcb For Soldering Things Together 7:-Multimeter          CIRCUIT AND EXPLANATION The project involves the use of a transistor as a switch to make the outdoor light on/off. As we know that transistor can be used in three diffe...