I am trying to create a C program to play a wav file on command on the Raspberry Pi Pico through a GPIO pin using PWM. I've got the wav file in a C array (which I'm trying to read). Is this the correct method?
1 Answers
is this the correct method to approach it?
Who knows? You have left an awful lot of information out.
If the wav file is hard coded in a C array, it would be simpler to pre-process the file off line and generate a raw PCM sample array at whatever sample width and rate the PWM driver can support. That way all you need do is send the PCM values to your PWM driver at regular intervals. I suggest that for that you consider using DMA to drive the PWM. You can then point the DMA controller at the sample array, and just let it go
If in the other hand you might read wav files from an SD card, and want to play arbitrary user supplied files, then off-line pre-processing may not be convenient. In that case you need a WAV file library to extract the PCM samples and transform them into a sample size and rate that your PWM can cope with, (WAV supports multiple encoding and sample rates). The samples might then be passed to the DMA/PWM driver in blocks extracted sequentially.
The complicated part in the second case is parsing the WAV file, for which you may need a library.
The pre-processing method can be done with a tool such as Audacity, to output raw PCM binary data, which can then be translated to a C code array with a tool such as SRecord.
The pre-processed audio approach has the advantage of only needing to support a single sample size and rate. I suggest start with that, and develop the audio driver (PWM/DMA) before worrying about direct WAV file replay, which only really makes sense if you have dynamic runtime selection of files.
Either way, get your audio driver working first with a simple arithmetically generated test waveform - say a square or since at 1KHz - something that is easily tested tor accuracy, and is audibly obvious when it is wrong.
Then add replay if a real recorded audio signal from preprepared audio PCM.
I would suggest you don't need direct WAV playback unless you have removable file storage on which load arbitrary files. Even then you might choose to pre-process them for simplicity.
If you do choose to use WAV files directly, then something like TinyWav may be suitable. It can extract PCM blocks that can them be passed to your audio driver.
The quality of audio over PWM will depend greatly in the sample rate and resolution you are able to achieve. There is a necessary trade-off between PWM clock, PWM frequency, and PWM resolution, and the external analogue signal reconstruction (low pass filter) will also have a significant impact.
An alternative would be to us an external DAC or audio CODEC. The interface to these if not directly supported could be realised using the PIO. For example Audio CODECs typically have I2C control interfaces and I2S audio interfaces.
Construction of a PWM/DMA audio driver is discussed here. It pretty much covers all the issues I mentioned above, and is specifically for the RPi Pico. Seems like a good starting point.

- 88,407
- 13
- 85
- 165