This tutorial is about building a DIY audio player using Arduino. Today audio players can commonly be found across many electronic products. Almost every mobile has an audio player. Audio technology gets a drastic improvement with rapid development in silicon technology. Previously audio data was stored on tape devices and CDs. But now, Flash memories are cheaper, store huge amounts of data, consume less power, and are much faster than CDs and tapes. This improvement in technology knockouts the tapes and CD’s out of the market. They are obsolete.
So, let’s go deep and learn about the components and science behind the audio players. The main components of the audio player are
- DAC (Digital to analog converter) – Takes digital data (bitstream) as input and outputs an equivalent analog signal.
- Solid state memory – In which audio data can be stored. Data is stored in the form of bits. Digital audio player means data is in solid state device as digital represents 1’s and 0’s. Sloid state devices can be SD cards, EEPROM and Flash.
- Controller circuit – Reads data from solid state device and input it to DAC.
- Amplifier- Amplifies the signal. Increases the strength of the signal. Digital signal strength is low. It is elevated for the speaker (Depending on speaker characteristics) using an amplifier.
- Speaker – Outputs the audio, which is read from solid state device as bitstream. Inputted to DAC and from DAC output analog signal enters the amplifier and finally the speaker outputs it.
Two ways by which audio files can be played using Arduino.
- PWM (Pulse width modulation) – Arduino does not have a DAC. PWM signal is used as a substitute for DAC by accepting some degradation in performance.
- External DAC – An external DAC interfaced with Arduino for proper audio signal conversion.
PWM audio signal
Arduino has PWM gpio’s. We can easily output an audio signal data stream as a PWM signal. The idea is to output the audio as PWM, which is then fed to a transistor. Transistor, after some gain, inputs the signal to the speaker, and finally, we can hear the audio.
Can we play all the audio files (mp3, wav, mp4, wma, etc.) using Arduino?
The answer is no. We can only play files whose contents are aligned as linear binary data. Arduino can read files. It can’t decode files. So, if the file content is encoded, it can’t be read by Arduino. Also, Arduino is an 8-bit microcontroller. It can read data which is 8-bit wide. By analyzing the above constraints, only wav audio files are found to be suitable for Arduino.
Wav audio files can be sampled between 8KHz to 44.1KHz. Sampling means that particular audio is recorded at this rate. Bit per sample is another characteristic for wave file is 8 and 16. The number of channels is mono (1) or stereo (2). For other parameters, you can see the file format stack. The above three are of our concern.
Arduino Uno’s max clock frequency is 16MHz. To play the .wav file, we must decrease the .wav file sampling rate to 25KHz or lower (considering the Arduino machine cycle is 1). This is to avoid hearing something out of order. We can play the wav file, which is sampled at 44.1KHz, but the Arduino machine cycle is increased in our case. We are fetching data from an SD card. Then the timer is converting the data in PWM form, and at the end, we are outputting it on the PWM pin. This whole process increases the time, and we may not play 44.1KHz sampled audio, especially if the frequencies are higher in audio.
Bit per sample must be 8, and lastly, only mono channel guarantees linear bitstream. Many online tools are available through which you can transform wav file according to the above parameters. After transforming the copy, the transformed the wav file in SD card.
A circuit diagram of the project is given below.
SD card is connected to SPI pins of Arduino. PWM pin 9 is used to output the audio wave. An NPN transistor (BC546) is amplifying the signal and feeding the output to the speaker. The gain of the transistor is 800, and the transition frequency is 150MHz.
Using a dedicated amplifier ic such as LM386 is a good practice. But the gain of the above BC546 transistor is much more than the LM386. For the whole circuit, 5v and 1A power supply is enough.
The project code is above. I used the TMRpcm library in the code. This library fetches the wav file from SD card, transform the bitstream in PWM and output it on Arduino PWM pin. An object of the library is created, and all the library functions are accessed using the object.
Upload the code in Arduino Uno. Upon powerup, the first track will automatically start playing for the second and third track. Open the serial monitor at a 9600 baud rate and send 2 to Arduino to play the second track and 3 for the third track.
Degradation in sound quality:
The audible sound frequency range is between 20Hz to 20KHz.
The sample wav file is at 44.1KHz. Covering all the audible frequencies. But we consider Arduino, which is operating at 16MHz. For data fetching from the SD card, two machine cycles are consumed. For PWM transformation, 2 more machine cycles are consumed. At last, 1 machine cycle is consumed at the output arriving to the speaker. Effectively reducing the frequency, which would result in not playing the 44.1KHz sampled audio file. The time would increase to 60KHz or so. Resulting in delayed audio.
Reducing the wav file sampling rate cuts the larger frequencies, and you could hear the audio in which the loudness is not present.
Let’s DIY the above project: Where to purchase parts?