Playing audio files from a FAT16 or FAT32 formatted SD card, useing only one PIC mcu and supporting the most common bit rates from 8 to 48Khz at 8 or 16 bit.
This project is mostly around the Microchip MDDFS library (Memory Disk Drive File System). It’s a neat pile of C source code that can manage a FAT12, FAT16 or FAT32 file system and interface to a SD or CF memory card or an IDE hard drive. But best of all its free!
Its downside is only the amount of memory it needs. With all of its features enabled it alone takes up a huge 23KB or flash and 1.4KB of RAM. By disabling features the flash usage can drop drastically but will still at least need 1.3KB of RAM with all extra features disabled
It has taken me some time to get it to compile without errors but once I got it compiled I put in a SD card gave it power for a few seconds, try to read the card and wow there was a txt file created on the card. That was almost too easy!
After some fooling around with it I decided to try and play audio directly from the card. First I needed a way to output an analog voltage out of the pic. The easiest method I know is PWM. As you know PWM is used a lot to control DC motors and things like that but if we use a PWM frequency well out of out hearing range it can output an audio signal. Here a dsPIC30F4013 was used. Luckily it has 4 PWM outputs. So I just used one of those and made it run at about 100 KHz. This pic can do 8 bit accuracy at such a high frequency. Then we just use a RC low pass filter to smooth it out in to a nice analog signal.
As for connecting the card to the pic it connects like a standard SPI device using the usual 4 pins. The pin out is easily found on the web.Note that SD cards are NOT 5V!!! They work on 3.3V. First I simply ran the whole thing on 3.3V but then I wanted to run the dsPIC at its highest speed and it can’t do it on only 3.3V. Because of this I put it on 5V but made a simple regulator with a 3.3V Zener diode to supply the SD card also resistors with series capacitors between the dsPIC and the card so the 5V signals can’t hurt the card. We need to use this simple circuit on the SDO, SCK and CS pins. The SDI pin does not need it because that signal is produced by the SD card so it is 3.3V
Next I needed to know how to get audio data from a *.WAV file. Basically in the beginning of the file it’s described what kind of WAV is it (Sample rate, bit depth, number of channels…) and after that it’s what’s called a data chunk. It’s simply the raw audio data in the format specified in the beginning of the file. The raw data here is actual sound values without any compression or encryption or what so ever (This is considering it’s a standard WAV without any codecs). For more in depth info about the WAV format check links.
All that we need now is some kind of link between the raw data from the WAV file to the PWM output. The reading from the SD card wont happened at a constant speed so we need to get a nicely constant stream of data to the output. This is done by a cyclic buffer. This is a kind of buffer that has no beginning or no end, it’s a circle. So what is happening is that the point that reads from it is moving around the circle at exactly the right speed for the WAVs sample rate (For a 22 KHz WAV file this is exactly 22KB/S) and the reading from the card Is done by a second point that moves at a very non constant speed and what it tries to do it catch the reading point, once it has caught up to that point it has to wait for it to read out some data to make space for new data. When there is free space again it tries to fill it again. So now the data is flowing at a good constant speed in to the PWM module nicely.
And now finally the audio is coming out of the PWM pin on the pic. All that’s left now is plug in the audio jack and have a listen.
What is also needed is to have some code to read the description in the beginning. So it knows how and what at speed to play it. This is not all that difficult. It just needs to check on certain spots of the file. For example 22nd byte contains the number of channels there are in the file (1 = mono, 2 = stereo). But problem is my current hardware can only output mono 8 bit audio. If I utilized all 4 PWMs it would be possible to do 16Bit Stereo, but seems like it’s too slow to play that. But its probably my sloppy coding that’s too slow. But I am going to get my hands on a dsPIC33FJ128GP802. It has a faster CPU and a lot more memory and my favorite a built in audio DAC with its own hardware buffer.
As for the user interface I simply used the com port. I have a ready built RS232-TTL cable so it’s just a matter of connecting it to the RX and TX pins. I have used it for debugging purposes but then made it in to a console that can be accessed with any terminal program like Microsoft HyperTerminal, PuTTY etc… A simple LCD could be quickly stuck on and some buttons to make a user interface without a computer.
As for the quality of the sound, it’s surprisingly good. The sound from it is easily better than a cheap PC sound card!
As for improvements there is a lot of room for that. First of all to get it to play the highest quality WAVs also it shouldn’t be that hard to make it record WAVs using the ADC. The later version of it uses a MP3 decoder IC to make it play most mp3 files too.A dsPIC is not fast enough to do mp3 decoding in software.
Supported formats:
8KHz, 11KHz,12KHz, 16KHz, 22KHz,24KHz,32KHz, 44KHz, 48KHz
Stereo or Mono 8Bit or 16Bit




supra56 at gmail dot com Thank u.
Sooo cool. Could we hear a sample? I trust the PWM is at a fixed frequency and you’re modulating the ratio to obtain varying volume? This must be very busy code.
With the pic’s maximum clock of 20MHz (50ns per cycle = 0.2us per instruction), the digital to analog conversion of a single 8-bit value would take at least 256*0.2 = 51.2us. An 8KHz sound file would require the individual samples to be output at a rate of one every 125us. I can see the quick and dirty way of doing this.
I trust that while the supported formats are up to 48KHz @ 16bit, this is purely the input format?
With a 16-bit sample (ignoring the stereo as the two DACs would work in parallel) it would require you have 65536 unique possible voltages each of which would take 13.1ms to produce for a maximum sampling frequency of 76Hz. About the frequency of mains hum!
Anyway, I’d love to see your 8-bit playback code. Did you use a FAT library?
Thanks.
Yes the output is 8bit only, but it sounds pretty good.The PIC runs at 120Mhz and im using microchips free FAT lib. A better solution for this is a 33F pic with a built in DAC it can do great quality and because it has a hardware buffer reduce CPU load a lot too.
I WANT SOFTWARE FOR EXAMPLE SOUND AND CIRCUIT
FIRMWARE: you can get it at the original article at http://www.uchobby.com/index.php/2008/07/21/dspic-wav-player/
At the link: http://www.uchobby.com/Files/dsPicWavePlayer.zip
Can i get schematic, please? I have all parts lists
My Email is supra56 at gmail dot com
Can u email me for schematic, please?
supra56 at gmail dot com
Thank u.
Please mail this project schematic and diagrams and partslist to my mail famesethu@yahoo.co.in
Thanx………
(complete instructions)