I'm a beginner and I've been developing my own library for a wave player. so far I have the SD card installed and OLED and rotary encoder all connected. I've successfully read the wave chunk and it's data(16bit and 44.1KHz). My question is that the data in wave file is PCM and I wish to play is using 16bit PWM and so how do I convert PCM to PWM?
2 Answers
There is no such thing as a PCM file. PCM is completely erroneously used to describe an uncompressed digital audio file. What it actually means is "A file which contains data that can be fed directly to a PCM device without any form of intermediate conversion".
What you have in a "PCM" WAV file is just raw sample data. After your header (usually 44 bytes) you just have 16-bit values representing your sample points, with the two channels interleaved one after the other.
Since PCM is a linear audio representation, the sample data it expects is a simple linear representation of the audio (unlike µLaw or A-law) and with no compression (such as MP3 or FLAC). And that is the exact same data that PWM expects since it too is a simple linear output.
However, none of that matters, because the Arduino simply isn't powerful enough to play your file. Maybe a smaller one (8kHz, mono, 8-bit) would be playable, but not yours. The numbers just don't add up.
There is a PCMAudio example available, but it only works from audio embedded within your program.
There is also a TMRpcm library available which plays from SD card, but is limited to 8-bit mono, though it can supposedly do up to 32kHz sample rate (though I wouldn't want to try doing anything else at all at that rate).
You would be better off using a system more geared towards audio - something with an I2S CODEC chip attached would be the best solution.
- 105,851
- 5
- 82
- 139
You should use an MCU with PWM generators to do that.
The problem with PWM is that the max resolution is quite low (10-bit) so you are effectively limited to 8-bit PCM.
- Use a DSP editor like Audacity to export a 16KHz unsigned 8-bit WAV.
- Import the WAV file as an array of unsigned char.
- Set your PWM freq to the resonant freq of your speaker (eg. 31250Hz)
- Set your PWM timer to fire at 16KHz and set the PWM duty cycle to the next array value.
I use 16KHz sample rate because:
- Reduced memory footprint
- Fewer timer interrupts
- PWM's limited resolution does not seem to benefit from anything above 16KHz
- I use piezo speakers directly wired to PWM pins in H-bridge.
- A separate amp module might benefit from higher sample rates.
- 99
- 3