STM32F429 Scream receiver
Nucleo STM32F429ZI is one of the cheapest ARM boards with Ethernet, currently priced at $23 on ST site, closely matched (+VAT) by my local distributors. In this application it is used as audio receiver for Scream (https://github.com/duncanthrax/scream) - free virtual sound card for Windows working over Ethernet.
To generate actual audio signal internal DACs are used in stereo mode. Left channel is routed to PA4 (DAC_OUT1) pin, right channel to PA5 (DAC_OUT2) pin. Amplitude of generated signal is close to typical "line in/out" levels, so it can be connected directly to e.g. typical active PC speakers. DAC outputs can also drive headphones with 1kOhm resistors in series without the need for separate amplifier.
Receiver accepts stereo stream with 48kHz sampling (this sampling rate can be exactly matched with timer triggering DACs, so at least there is no systematic error of this sort). Make sure 48kHz sampling is set in Windows audio device configuration (default for Scream would probably be 44.1kHz), resampling is not implemented.
STM32F429 DACs are 12-bit only and I haven't used dithering or oversampling, but audio quality is good. This is nothing like noisy DAC built into ESP32 or PWM from ESP8266. Teoretically 12 bit resolution gives 72 dB signal/noise ratio and this is similar to best compact cassette systems with Dolby S and also better than many good quality FM radio tuners. 12 bits may be good enough for most purposes (see https://www.audiocheck.net/blindtests_16vs8bit.php).
Firmware is configured to use DHCP mode, but if DHCP fails few times it switches to static IP (see main.h). First half of the MAC is set to fixed 02:00:00, second half is semi-random, based on hash (crc32 actually) of STM32 chip unique ID.Device is listening on port 4010 and joins multicast group 188.8.131.52 matching default Scream settings, so it should work without any need for configuration.
Jitter buffer size is set in source code to 7 Scream frames with initial buffer fill ("prefetch") set to 5 frames. As each frame has 1152 bytes of data, this translates to 6 ms of delay per frame (stereo, 2 bytes per sample, 48 kHz sampling) and up to 42 ms (typically: 30 ms) of total delay. This does not seem to be noticeable in typical use. For reference, this is the same delay as sound travel time through the air over 12 meters.
Firmware is built with EmBitz 1.11 (Windows) - probably the most lightweight ARM IDE + toolchain set there is. Just 50MB download, no fiddling with setup, ~700MB after installing (mostly toolchain), working out of the box with STLink built into nucleo board (* for newer STLink firmware version you may need to download/configure new version of OpenOCD).
Source and binary
- fixed wrong sample value being passed to FIFO if previous number of samples was uneven (thanks to Pat Rogers)