Playing Audio On The Pi Pico With No DAC To Speak Of

Normally, if you want to play music or other audio on a microcontroller, you need to get yourself a DAC. Or at least, that’s the easiest way to go about it and the one most likely to get you good, intelligible audio. You don’t have to go that way, though, as [antirez] demonstrates.

[antirez] decided to do this with a Pi Pico, but it’s applicable to other microcontrollers too. It’s all done with a single pin and a PWM output. The PWM output is set to a very high frequency beyond human hearing. In this case, it was 100 KHz. Then, the duty cycle of the PWM is changed to essentially output various average voltage levels at the pin. Vary the output voltage as per your desired sound file by using each sample to vary the duty cycle of the PWM. Voila! You can output whatever sound you want on that pin! [antirez] steps through the basics of doing this, including processing simple WAV files into a raw format that can be dumped into MicroPython code.

There’s no sound sample on the project page, and we’d have to assume it sounds pretty crunchy when hooked up to a speaker. And yet, it could prove a useful technique if you’re designing your own audio greeting cards or something, so keep that in mind!

24 thoughts on “Playing Audio On The Pi Pico With No DAC To Speak Of

  1. It is called “Delta-Sigma Modulation” and is a very common trick to get a Analog signal out of a digital device. All you need is to plop a RC/LC afterwards and you get a proper voltage signal out of it. I use it all the time when dealing with current controlled devices.

    Generally the idea is to crank up the switching frequency as high as you can. The higher the frequency, the easier it is for a filter to get rid of the switching noise. With commercial Delta-sigma DACs for audio reaching into the multiple megahertz.

    Filter and buffer with an active opamp and you will likely find this giving an ok, albeit probably hissy signal.

      1. I interpret a first order 1-bit delta-sigma as being a pulse density modulation. One state means +1 and another state means -1. If you have digital (PCM) samples in your software, then you keep a running error of how you’re doing, and add +1 or -1 for each sample depending on if you’re below or above that error. The output is a binary stream that you can feed into an analog low-pass filter to recover the intended stream. so a circuit consisting of a few op-amps is sufficient to do the job of filtering and scaling your digital output into a useful analog output.

  2. This existed back on the esp8366, really nothing new. I used it in a project. I seem to recall you had to do some pre processing on the sound file, but it was so long ago I really do not recall the fine points, outside of it worked well enough to warrant not getting a dedicated sound player.

      1. Absolutely. I’ve used almost the same techniques from the 80s and 90s with microcontrollers without DACs. Old PCs are actually a great salvage source for speakers and transistors ideal for this method with Arduino.

      2. Yes. I did the same on my Apple //e in the early eighties. The best I could do was, I believe, an 80 microsecond inner loop, so the sampling frequency was in the audible range, 12.5 kHz. Not great. But now I’m an old man and I bet I couldn’t hear it anyway!

  3. Lame, the audio doesn’t stream from redis streams. Maker clearly knows nothing about high-bandwidth architectures and datastructures.

    :D :p

    In case my joke is too dumb, antirez is Salvatore Sanfilippo, the author of redis. I had to double check, but were there really going to be two antirez’s? ;) He’s a true engineering hero, to me.

      1. hahaha fun fact! fourier invented his transform because he had come up with a formula for how the temperature would equalize along a rod if the temperature gradient started out as a single sine wave, and he wanted to prove that therefore he’d solved the whole problem for any arbitrary temperature distribution. imo one of the crazier stories in physics.

  4. I did the same thing with an Arduino 15 years ago. SDCard ->Arduino Nano -> PWM pin -> low pass filter -> 741 -> audio amp -> Speaker. I was running the PWM at 44khz which twice the sample rate of the wave files I used for input. I stuffed all that in to a jewelry/music box for my wife. She loves it and it still works to this day…

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.