We do not want a DAC – ESP32 PDM Audio
So, there’s no DAC on the ESP32-S3.
You’ll suppose this is able to be a little bit of a downer if if you wish to get audio out and use an analog amplifier.
But it surely’s really surprisingly straightforward to output Pulse Density Modulated audio utilizing Sigma Delta Modulation on the ESP32 and you may get well the audio sign by low cross filtering it – an RC filter could be enough for this. And that’s what I’m utilizing within the video.
Although the Espressif docs do recommend a a lot better energetic filter.
It’s fairly fascinating to take a look at a PDM sign and look at it within the frequency area. Right here’s a bit of audio together with it’s spectrogram:
And right here’s a simulated PDM model of the unique audio. The pattern fee of the PDM knowledge is simply over 1MHz and I’m displaying the spectrogram from 0 to 500KHz
The PDM knowledge simply goes from -1 to 1 and modifications density relying on the worth of the unique sign.
If we simply take a look at the decrease 8KHz of the spectrum then we are able to see what appears like our unique sign.
So to get well the unique audio we simply apply a low cross filter – and hey presto, we have now our unique audio sign again!
So the way to can we do that on the ESP32?
There’s a few choices accessible to us.
The example code from Espressif suggests utilizing a timer to output every pattern utilizing the sigmadelta_set_duty (you could possibly additionally simply use plain previous PWM as nicely). This does work for audio knowledge, and I’ve obtained some easy sample code that can do it, nevertheless it’s not very environment friendly – we’re continually interrupted by a timer to ship out the subsequent pattern. There’s additionally various code required if you wish to stream samples out from another supply.
A a lot better method is to make use of the I2S peripheral which may additionally output PDM knowledge. There are two annoying issues with this that are highlighted within the timing diagram from the docs.
The primary problem is that it at all times desires to output a left and proper channel. This can be a bit awkward if we simply wish to feed the PDM sign straight into an analog audio amplifier or headphones. However we are able to get round this by simply outputting the identical worth for each the left and proper channels.
The second problem is that it at all times desires to output a clock sign – we don’t actually need this. My workaround for this was to only assign the clock to IO45 or IO46 – on the S3 you’ll be able to’t actually use these pins for a lot as they’re strapping pins and it’s finest to only depart them alone. However you need to use them for outputs as soon as the ESP32 has began up.
There are “correct” PDM amplifier ICs that can take this sign – for instance the MAX98358 or the SSM2537.
This all works surprisingly nicely, you’ll be able to drive headphones immediately from the PDM sign and most analog amplifiers will take the mixed stereo PDM sign and may have a low sufficient bandwidth that they’ll simply work.
You possibly can even simply drive a speaker with a very easy half or full bridge and get cheap audio out (although it might be fairly noisy).
Have a watch of the video and let me know what you suppose.