Playing audio files in a Pi Pico without a DAC
antirez.com
antirez.com
[1] https://pigweed.googlesource.com/pigweed/kudzu/+/refs/heads/...
[2] https://pigweed.dev/docs/blog/01-kudzu.html
I did end up getting it working, but it was clear that GN/Bazel is the blessed build system and CMake is just an afterthought.
In contrast, I pulled in expected-lite [1] with a single line of CMake's FetchContent, #include'd the header, and it just worked.
We wrote an explainer on facades, did you see that / did it help? I will comb through the docs and make sure any module that uses facades links to the explainer https://pigweed.dev/docs/facades.html
Thank you for trying it out and for the feedback, and sorry again for the pain
For my notes, did you just try it out right now or was this in the past?
[1] Just checked, I no longer have edit access to my previous comment
I looked through what I did and in the end, to bring in pw_result, I had to define a failure handler, pull in three separate cmake files for various definitions, define an ASSERT action (because a result type requires an ASSERT fail, apparently?), and set a backend and a handler for pw_assert. At some point I remember it complaining left and right about not having the right I/O methods for printing, etc. I just wanted to try the result type, and for some reason I needed to define I/O mechanisms for my platform.
Is this the correct procedure? I have no idea, because the cmake documentation had (has?) _zero_ examples. If they existed, I couldn't find them. I eventually got it to compile with the following snippet, but I can hardly believe that this is the "intended" way to do it.
FetchContent_Populate(pigweed)
include(${pigweed_SOURCE_DIR}/pw_build/pigweed.cmake)
include(${pigweed_SOURCE_DIR}/pw_assert/backend.cmake)
include(${pigweed_SOURCE_DIR}/pw_assert_basic/backend.cmake)
add_compile_definitions(PW_ASSERT_BASIC_ACTION=PW_ASSERT_BASIC_ACTION_LOOP)
pw_set_backend(pw_assert.check pw_assert_basic.check_backend)
pw_set_backend(pw_assert.assert pw_assert_basic.basic_handler)
add_subdirectory(${pigweed_SOURCE_DIR} ${pigweed_SOURCE_DIR})I'm off for the night but will follow up here next week
We can also continue discussion on the Discord https://discord.gg/M9NSeTA
* I'm forwarding your feedback to the team.
* I will make sure we follow through on the plan to include CMake examples in our WIP "examples" repo [1] and will make sure pigweed.dev links to those examples consistently.
* Our new module docs guidelines require every module to have a quickstart section that includes how to set up the module in every build system we support, including CMake [2]. That should help a bit but based on your experience it sounds like there's a lot more we need to cover in these quickstart sections.
(I don't want to overcommit on behalf of other teammates but as docs lead these things are safely within my realm to change.)
[1] https://pigweed.dev/seed/0122-code-samples.html#examples-rep...
If you're simply a hobbyist grudgingly writing C/C++ then sure, something like Arduino would be a lot more appealing.
exactly one of those projects use CMake (an open source Qt app that's had a couple million downloads), and the infra for that was pretty finalized by the time i got there. if "comfortable with the basics" means "add a new .c file to the list of stuff to compile", sure, easy. if it includes "detecting the presence of some optional dependency and then conditionally compiling+linking a .so in response" then not at all. more importantly though, a large number of cmake directives i cannot guess their effects except by consulting the manual.
there's a lot of build systems out there. and a lot of technologies tend to come in pairs: a Qt C++ program is likely to use CMake, a GTK C/C++ program is likely to use meson, an SDL C/C++ program is likely to use make. not that there's no variance, but it's weirdly easy to specialize more narrowly than you think.
[1] https://en.wikipedia.org/wiki/Resistor_ladder#R%E2%80%932R_r...
We'd load and reload that floppy over and over again and wonder how it was possible that our computer could do that : )
Then again the following is even more mind blowing coming from an unexpanded C64 (yes, from a real SID!): https://www.youtube.com/watch?v=UYAf_awh5XA.
Yup, an unmodified C64 playing 48 kHz 8-bit audio! It uses a 1 MB EPROM cartridge, which is kinda period correct, because while expensive, it would have been doable 40 years ago. No REU-style DMA tricks or any cheating.
Imagine if you did dithering to produce grayscale images with a black and white screen by just using different sizes of rectangles; you'd have to have a very high resolution screen before you wouldn't be able to see the individual rectangles. That's what pulse width modulation is like. Whereas pulse density modulation, using a sigma-delta modulator, is more like a proper dithering algorithm, where you spread the pixels out evenly across space, you don't just use different size rectangles to represent different shades of gray.
Bresenham's algorithm (which was invented around 1960 to draw straight lines at arbitrary angles on pixellated displays) was groundbreaking because it didn't require any multiply or add operations.
Sigma-Delta is basically the same idea as Bresenham's algorithm in a different kind of space.
In effect, Bresenham ends up performing a division by repeated subtraction. And at every subtraction step, it outputs a pixel.
Video: [1]
Source code: [2]
[1]: https://blog.eldruin.com/ad983x-waveform-generator-dds-drive...
[2]: https://github.com/eldruin/driver-examples/blob/master/stm32...
- A physical speaker already acts as a filter due to inertia
- The PWM frequency and its square harmonics sit far beyond the human hearing range
Most of the digital parts of DAC chips are not there for conversion, but getting data ready for conversion through a reconstruction filter. You don't need that if you're driving a PWM signal through a cap to integrate it.
There are no websites that don't need SSL.
this actually works surprisingly well!
I did the same thing for a device I made based on the Pi Pico[1], where audio is processed every sample and it stores a bunch of wav files in the flash that can be mangled together. the flash is fast enough that you can jump between samples really quickly to get cool "tunneling" effects that are surprisingly good sounding for such a tiny + cheap little chip.
[1]: https://pikocore.com
I did do a delta sigma using the pios but fed via cpu, essentially used just a look up table of amplitudes that fed a bitstream into the pios to get a psuedo 133 MSPs dac.
Accessing address 0xC030 (PEEK(-16336) or STA $C030) would cause the machine's internal speaker to click. I assume it was the result of the voltage to the speaker toggling from digital on to digital off.
POKE(-16336) was quieter. I figured it was because it was implemented as a quick read-then-write instruction sequence, too fast for the speaker diaphragm to move end-to-end (effectively a quieter sound). Assembly behavior was different.
In spite of its simplicity, there were games with amazing PWM sound effects (crude by today's standards, but magical in the early 1980s). The software company Muse even produced a sort of speech synthesizer that played sampled words, like an audio version of a ransom note. It sounded wonderfully awful.
Much like you can't expect a (useful) recording in a speaker review.
It'd be a bit more reasonable here I suppose because it's almost certainly going to be the weakest link, so everything else is to some extent preserving characteristics of it.
Note that Class D amplifiers can use either PDM or PWM, though the former is less common at least partly due to (now expired) patents.
absolutelyharam.jpeg