0

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?

5
  • playground.arduino.cc/Code/PCMAudio Commented Jun 2, 2018 at 17:17
  • An Arduino is not an audio player. It won't have enough processing power and/or memry for running an SD card, refreshing an OLED display and playing audio. Use specialized hardware and a decent DAC for audio playback.
    – tttapa
    Commented Jun 2, 2018 at 17:24
  • Or go the cheap route and use an LC filter. This video has good info on both DACs (R2R-style) and PWM+Filter "DACs": youtube.com/watch?v=Y2OPnrgb0pY What's your speaker system? You might need another OpAmp or audio amplifier. Commented Jun 2, 2018 at 19:07
  • tttapa, I've seen a lot of tutorials online. Maybe if I remove the OLED display it might be able to run it but I'm just curious and I want to get to the end of it even if the output isn't want I desire.
    – Sankalp
    Commented Jun 5, 2018 at 13:20
  • Maximilian Gerhardt, LC filter makes sense after I've generated PWM signal. My whole problem is that I'm not able to do that. I just don't know what the interface between PCM WAVE file and PWM is.
    – Sankalp
    Commented Jun 5, 2018 at 13:22

2 Answers 2

1

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.

2
  • Thanks for replying early. Well I was thinking if we can use 16bit PWM for audio output at 44KHz timer interrupt. And to compensate for the low memory holding capacity of the Arduino we can use double buffering from an SD card. OR Adding an external 16bit DAC IC would reduce the complexity because then maybe I don't have to worry about PWM? (I'm not sure about this part.)
    – Sankalp
    Commented Jun 5, 2018 at 13:16
  • See my answer below. PCM can most certainly be converted to PWM and played on most MCUs.
    – Birkensox
    Commented Apr 3, 2023 at 16:29
-1

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.
1
  • Comments have been moved to chat; please do not continue the discussion here. Before posting a comment below this one, please review the purposes of comments. Comments that do not request clarification or suggest improvements usually belong as an answer, on Arduino Meta, or in Arduino Chat. Comments continuing discussion may be removed.
    – Juraj
    Commented Apr 4, 2023 at 4:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.