[HN Gopher] We don't need a DAC on the ESP32-S3
       ___________________________________________________________________
        
       We don't need a DAC on the ESP32-S3
        
       Author : iamflimflam1
       Score  : 107 points
       Date   : 2024-01-05 17:03 UTC (5 hours ago)
        
 (HTM) web link (atomic14.substack.com)
 (TXT) w3m dump (atomic14.substack.com)
        
       | phkahler wrote:
       | Very compact (if cryptic) code to smoothly blink an LED using PDM
       | here:
       | 
       | https://gist.github.com/phkahler/1ddddb79fc57072c4269fdd6716...
       | 
       | I just drop that in my 20khz isr and point to the GPIO with the
       | LED.
        
         | tverbeure wrote:
         | I threw that code in a small program. The output of that code
         | seems too regular for it to be PDM, but then I don't really
         | understand the code.
         | 
         | 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
         | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
         | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
         | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
         | 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1
         | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1
         | 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1
         | 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1
         | 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1
         | 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1
         | 0 1 1 1 0 1 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1
         | 1 0 1 1 1 0 1 1 0 1 1 1 0 1 1 0 1 1 1 0 1 1 0 1 1 1 0 1 1 0 1 1
         | 0 1 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 0 1
         | 1 0 1 1 0 1 1 0 1 1 0 1 0 1 1 0 1 1 0 1 0 1 1 0 1 0 1 1 0 1 0 1
         | 1 0 1 0 1 1 0 1 0 1 0 1 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 1 0 1 0
         | 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
         | 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1
         | 0 1 0 0 1 0 1 0 1 0 0 1 0 1 0 1 0 0 1 0 1 0 0 1 0 1 0 0 1 0 1 0
         | 0 1 0 0 1 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0
         | 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 0
         | 1 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 1
         | 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0
         | 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0
         | 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0
         | 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
         | 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
         | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
         | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
         | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
         | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
         | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
         | 1 0 0 0 0 0 0 0
        
           | iamflimflam1 wrote:
           | I got ChatGPT to read the data, low pass filter and then
           | downsample it.                 1.0035971164599362
           | 0.9085335060080786       0.9035432831636958
           | 0.7979082616868238       0.7167128607342428
           | 0.5957569676023409       0.49808942875852646
           | 0.4009797804151446       0.3308973662512045
           | 0.1857546947996519       0.07410762115348818
           | 
           | Here's a plot of the original data and low pass filtered:
           | https://imgur.com/a/kCxA7XK
        
             | tverbeure wrote:
             | Nice! I guess I'm just bad at judging what's PDM and what's
             | not. :-)
        
               | iamflimflam1 wrote:
               | I think there are all sorts of modulation schemes that
               | can be used to generate a PDM like signal. The good ones
               | do a lot of clever things to do noise shaping and make
               | sure it's all up the high frequencies so gets filtered
               | out.
        
           | phkahler wrote:
           | X simply increments with time as a 16 bit signed value so it
           | wraps. Consider it signed value q15 so range is +/-1. Y is
           | then (1-x^2)^2 which approximates a sine wave for brightness
           | (0 to 1). The accumulator "a" gets this added on, but it's as
           | 12 bit accumulator and the overflow/carry bit goes to the
           | led. The carry is cleared on the following iteration. By the
           | mask just before adding in y again. The rate of overflows
           | determines the brightness.
           | 
           | All in constant execution time too!
        
           | londons_explore wrote:
           | For something that looks to a human like smooth blinking, you
           | really need to have a sine wave, and it needs to be gamma
           | corrected... There might be some easy way to do that, but I
           | always just use a linearly interpolated 8 stage lookup
           | table...
        
       | moefh wrote:
       | That's really nice!
       | 
       | Here's a blog post[1] showing how to do something very similar
       | with the Raspberry Pi Pico, which also doesn't have a DAC. I
       | wrote a very simple 4-channel MOD player[2] for the Pico using
       | his sound output code.
       | 
       | [1] https://gregchadwick.co.uk/blog/playing-with-the-pico-pt3/
       | 
       | [2] https://github.com/moefh/pico-mod-player
        
       | MrBuddyCasino wrote:
       | Nice! If I remember correctly, PDM output was uncharted territory
       | on the original ESP32 for several years, despite there even being
       | a low-pass filter suggestion in the docs.
        
       | rzzzt wrote:
       | This is a DAC. The low-pass filter is an integrator in disguise.
        
         | nimish wrote:
         | It's how every sigma-delta DAC works, basically. Less snappy
         | headline though.
        
         | myself248 wrote:
         | This was so obvious before even clicking, I couldn't imagine
         | that level of trolling on HN, I had to click in to see what
         | they were actually doing.
         | 
         | Nope, that's what they're actually doing. Congrats, you've
         | built a very simple external DAC.
         | 
         | Low-effort clickbait? Or an innocent misunderstanding by
         | someone who thinks DACs have to be expensive?
        
           | baby_souffle wrote:
           | > Low-effort clickbait? Or an innocent misunderstanding by
           | someone who thinks DACs have to be expensive?
           | 
           | Probably the latter. Things like Arduino and cheap ESP
           | modules from china have made electronics vastly more
           | accessible than they were previously. Given that, it makes
           | sense that somebody wouldn't really understand _how_ a DAC
           | works but would understand what one does, what it's used for
           | and that the datasheet for $currentModule says there is none
           | present.
        
           | rzzzt wrote:
           | I have no problem with the article, wouldn't say that it's
           | clickbait either. Just saw a DAC >:)
        
           | jerf wrote:
           | The ready availability of Arduinos and similar technology has
           | brought a lot of people into that scene who are not aware of
           | what all is available to them, what all the bits and bobs
           | are, and what you can bash together with a few resistors and
           | capacitors hooked up correctly.
           | 
           | People like me. I think I can call myself tolerably good at
           | programming, but I can easily tell I'm much more newb at EE
           | and I can really only operate with things that have clearly
           | defined outputs that match up to some other input. Where you
           | may see trivial conversions you could bash together in your
           | sleep, I see an output that doesn't match the input and don't
           | immediately know where to go with that.
           | 
           | In my case, I'm able to follow the post just fine, but if I
           | had to put that circuit together from scratch from first
           | principles I'd be looking at weeks of learning more about EE.
           | And as a result, as I am blundering about an unfamiliar
           | landscape in some personal projects I've got going on, I
           | appreciate posts like this.
        
         | dragontamer wrote:
         | I think a 1st order RC filter is simple enough that you could
         | argue that "you don't need a DAC" and is what I expected.
         | 
         | But when I opened up the post and saw a 2nd order (probably)
         | Sallen-key (or is this a MFB? I always get my topologies
         | confused...) with a full-bore OpAmp and capacitors up the
         | wazoo... erm... yeah, they're basically hand-building a DAC at
         | this point.
         | 
         | ---------------
         | 
         | A lot of stuff is wishy-washy definitions anyway. What's the
         | difference from an analog-comparator and a ADC anyway? An
         | analog-comparator is just a 1-bit ADC after all.
         | 
         | So a lot of "what is a DAC" exactly is up to opinion around the
         | edges. But if you've got op-amps and signal conditioning,
         | you're getting pretty darn close to "proper DAC" except you
         | know, not as good (ie: cheap, fast, or simple) as a proper
         | professional solution.
         | 
         | -------
         | 
         | EDIT: Reread blogpost. It looks like the RC-filter is in fact,
         | being used. The Espressif docs __suggest__ the OpAmp based 2nd-
         | order filter, but the blogpost is strictly with the simple 1st
         | order RC-filter.
         | 
         | So yeah, I'd say that RC-filter is "not a DAC", due to being
         | too simple. (It functions as a DAC in this case, but we got to
         | draw the line somewhere).
        
         | andrewaylett wrote:
         | "We don't need _dedicated hardware that 's marketed as_ a DAC
         | on the ESP-32-S3"?
        
       | mardifoufs wrote:
       | Stupid question: why did espressif leave out the DAC for the S3?
       | I thought it was the new "default" base esp32. I know they had
       | issues with the analog converters in general but this is
       | surprising to me!
        
         | iamflimflam1 wrote:
         | The rumour is that the DAC took up a lot of die space and there
         | wasn't enough room.
         | 
         | For most use cases PWM or PDM is sufficient. For more complex
         | cases you are probably looking for some very specific
         | performance characteristics and an external IC probably makes
         | more sense.
        
         | Nihilartikel wrote:
         | I'd love to have a dac built in, but it strikes me as being a
         | bit like the old tv-vcr combos.
         | 
         | If the built in vcr stinks or doesn't quite meet expectations
         | you're either stuck with its subpar performance, or with the
         | sunk cost of an unused or unusable feature.
         | 
         | Many people might want an audio quality dac.. but 8 bit? 16?
         | 24? Or maybe 4 bit is fine but you need 12 of them... Best to
         | just have good peripheral support.
        
       | the__alchemist wrote:
       | Interesting! On STM32 etc, the DAC is considered a hacky way of
       | doing audio compared to the SAI peripheral; here without even a
       | DAC, they are making it work.
        
         | nomel wrote:
         | They've directly implemented a classic design of a DAC by using
         | an external component. You can buy DACs that are exactly this.
         | You can also implement a DAC with digital IO and some
         | resistors. But, having things integrated is nice, and often
         | cheaper. :)
        
       | Retr0id wrote:
       | Just for fun, I tried turning a CP2102 USB UART adapter into a
       | PDM DAC, using the raw output of the serial bitstream. It sounds
       | "not good", but honestly not that bad either. Here's a sample
       | from it: https://retr0.id/media/5c4c16ac-
       | bc6d-4bf0-9159-73bbe4fcfb02/...
       | 
       | The only external components were a simple passive RC filter.
        
         | markrages wrote:
         | I did this a while back:
         | 
         | https://hackaday.com/2005/10/25/audio-output-from-a-serial-p...
         | 
         | (Looks like somebody mirrored it to github at
         | https://github.com/koniu/ttyplay)
        
         | nyanpasu64 wrote:
         | It sounds "fluttering" as if there's periodic pauses in the
         | bitstream being sent.
        
       | raverbashing wrote:
       | Well yeah you don't need a DAC but that will eat a lot of CPU
       | cycles
        
         | crote wrote:
         | Usually there are plenty of free unused CPU cycles. External
         | hardware, on the other hand, is expensive. So why not save some
         | money and use the CPU?
         | 
         | Besides, I don't think it actually uses substantially more CPU
         | than an external DAC. You'd be feeding a DMA buffer into the
         | I2S peripheral either way. If you precompute the PDM waveform
         | from the audio sample it's essentially free. Using a LUT or
         | even computing it realtime should only take a dozen or so
         | cycles per sample, at 44.1kHz.
         | 
         | Considering that the ESP32-S3 has two cores running at 240MHz,
         | even taking an excessive 500 cycles per sample would only be a
         | 5% CPU load.
        
           | dekhn wrote:
           | To me the value of the ESP32 has always been the peripherals
           | that substitute for pure CPU usage (although, it's certainly
           | nice that it has the CPU cycles to do interesting things).
        
             | iamflimflam1 wrote:
             | You feed in the PCM samples, the I2S peripheral handles the
             | PDM in hardware. So no CPU should be used.
        
               | dekhn wrote:
               | Read the comment I'm replying to.
        
           | raverbashing wrote:
           | You can't do much lookup with sigma-delta modulation but
           | 
           | > has two cores running at 240MHz
           | 
           | Yeah ok that is manageable.
        
       | jdfellow wrote:
       | Isn't Delta-Sigma and PDM exactly how DSD works? In fact, I think
       | Sony originally came up with DSD as an intermediate
       | representation of PCM in one of their DACs and then Sony &
       | Phillips got the harebrained idea to use it in SACD. That is to
       | say, a simple DAC for DSD is just a capacitor functioning as a
       | low-pass filter, without any other components.
        
         | nomel wrote:
         | Hardware is getting more and more esoteric, so the delight and
         | surprise should be expected, and encouraged. :)
         | 
         | I would claim that 70% of software engineers would love taking
         | an electronics course. It's like programing, with electrons.
         | 
         | I suspect the next link in the cycle will be how you can make
         | music on an old AM radio, if you attach a length of
         | unterminated wire instead of a cap!
        
           | JohnFen wrote:
           | > I would claim that 70% of software engineers would love
           | taking an electronics course. It's like programing, with
           | electrons.
           | 
           | I very much think all software engineers _should_ take an
           | electronics course. At least an introductory one. Knowing how
           | things work will improve your code, and will give you an
           | alternate way of thinking about programming problems.
           | 
           | But I'll admit my bias: I came to programming by way of a
           | digital electronics course as a child. Since I was a child of
           | a poor family, I couldn't afford to actually do electronics
           | projects at home, though (this was well before everything got
           | so inexpensive), and shifted to programming because you could
           | do that for free if you had access to a computer.
        
         | bob1029 wrote:
         | I spent an entire summer circa 2010 trying to rip the decrypted
         | DSD signal off an SACD player via an FPGA. I figured the simple
         | on/off levels would be easy to grab but I had not much success
         | beyond being able to visualize it on a scope. Was trying to get
         | at the high resolution, multichannel tracks for a Lord of the
         | Rings soundtrack.
        
           | dfox wrote:
           | I spent somewhat inordinate amount of time around 2010 by
           | designing a Class D PA amplifier that used DSD-like bitstream
           | internally. The idea was to convert analog input signal into
           | this bitstream by what amounted to somewhat convoluted sigma-
           | delta ADC, process that with FIR filter in digital hardware
           | and drive MOSFET H-bridge with that. The thing ended up
           | ridiculously complicated (with somewhat impressive amount of
           | SRAMs) and totally non-practical (through hole 74HCT and
           | GALs, which worked out to something like 15 3U eurocards). I
           | never got to complete the board layouts, much less building
           | it, which is probably a good thing.
        
             | amluto wrote:
             | As I understand it, the really nice modern class D
             | amplifiers use feedback internally, which more or less
             | eliminates using a pre-computed DSD-like bitstream as a
             | good option.
             | 
             | On the other hand, FPGAs and really fast microcontrollers
             | are a thing now, so you could probably get a chip with a
             | nice internal ADC, digitize the output voltage, and use an
             | actual computer program to drive the H bridges, thus making
             | an extremely non-cost-effective class D amplifier :)
        
       | mwbajor wrote:
       | I did not read the article in-depth but class D audio amplifiers
       | use variable pulse widths and then filter it before the speaker.
       | Aside from very good efficiency you also remove the need for a
       | transformer using this method hence why its used.
        
         | hdhfjkrkrme wrote:
         | As a down side they are extremely difficult to design for good
         | quality output. Basically impossible for an amateur.
        
           | dekhn wrote:
           | ladyada made a board design that incorporates a class-D
           | amplifier chip, it's open source:
           | https://www.adafruit.com/product/1752
           | https://github.com/adafruit/Adafruit-MAX9744-Amplifier-PCB
           | 
           | I'm not sure which is the hard part you're referring to-
           | implementing the amplifier itself, or the board around it. I
           | don't think an amateur would want to build their own class-D
           | from raw components except for pedagogical purposes.
           | 
           | (i've been pretty happy with the results, I used the board to
           | drive a couple speakers and the amplifier is not the first
           | thing I'd fix to improve the audio quality.
        
       | kstrauser wrote:
       | Is that how for instance the old Technics MASH DACs worked?
        
       | riedel wrote:
       | I looked at the schematics of the PDM amplifier chips linke and I
       | am puzzled why they put a DAC in front of a class d amp. Can you
       | just digitally amplify the PDM out and then do the low pass
       | trick. I thought that was all the class-d amps are doing.
        
         | iamflimflam1 wrote:
         | Reading up on the ICs the value they add is in the clever
         | modulation schemes they use to avoid needing filters on the
         | output and EMI.
         | 
         | I guess you can't really trust the raw PDM output from an MCU
         | which might not be very well designed or shaped.
         | 
         | Maybe better to convert back to analog and then apply whatever
         | secret sauce you have to make the class D amplifier work really
         | well.
        
       | DrNosferatu wrote:
       | Didn't "Mean Streets" for DOS use a similar technique to output
       | digitized speech through the PC speaker?
        
         | wiz21c wrote:
         | Apple 2 speaker can be made to work like that too...
        
           | zwieback wrote:
           | brings back memories of playing Castle Wolfenstein on my
           | Apple ][
        
             | dekhn wrote:
             | Schweinhundt!
             | 
             | I went back and played it on my Apple //e, it holds up
             | pretty well. The source code for the sequel was released by
             | the authors widow, around 2004.
             | https://archive.org/details/BeyondCastleWolfenstein_source
             | 
             | Oh, now I see it's just decompiled, not the original
             | source. But you'd still be able to find the data and code
             | for the audio.
        
       | Nihilartikel wrote:
       | I had really good success abusing the PWM pins on AVR
       | microcontrollers into acting as 8-bit DACs. Hooking up earbud
       | headphones or a tiny powered speaker was all that was needed for
       | decent (for 8 bit) fidelity. No low pass necessary since the PWM
       | artifacts were at the upper edge of audibility.
       | 
       | Those micros were much weaker than the ESP, so the audio was all
       | synthesized with a roughly nintendo-parity waveform selection
       | rather than samples. In fact the earliest version was on an
       | attiny85 which had no hardware multiplication, so.. lots of fixed
       | point arithmetic and lookup tables were involved.
       | 
       | My pet project was DuinoTune, which would convert tracker-music
       | into ready-to-compile code.
       | 
       | https://www.youtube.com/watch?v=rFqvPWnolfY
       | 
       | https://www.youtube.com/watch?v=G3baH5iTcFM
       | 
       | https://github.com/blakelivingston/DuinoTune
        
         | ChainOfFools wrote:
         | > I had really good success abusing the PWM pins on AVR
         | microcontrollers into acting as 8-bit DACs.
         | 
         | This sounds like tricks demo scene coders use to coax sampled
         | audio out of unlikely things like apple IIs and XT-era
         | hardware.
        
           | Nihilartikel wrote:
           | It's not very far off to digital audio over PC speaker I'm
           | sure! The AtTiny85 had a great setup for it though, a high
           | speed PWM clock which gives you a 250khz carrier, so just use
           | another hardware timer interrupt every 20khz or so to
           | calculate the waveform and change the PWM duty cycle and boom
           | - music on a pin!
        
       | JohnFen wrote:
       | I've done such things when using microcontrollers that lacked a
       | DAC. In my projects, I try hard to use the smallest/wimpiest
       | microcontrollers that can do the job I need done, and for some
       | applications, making do without a DAC is a good tradeoff for me.
       | 
       | However, having an actual on-board DAC is best in general. You
       | get better results and a lower parts count.
        
       ___________________________________________________________________
       (page generated 2024-01-05 23:00 UTC)