Repository navigation
https stations play. Really play.
Not rewritten to http and hoped for. Not skipped. A real TLS handshake, a
real encrypted stream.
The previous release did what every Cardputer radio does: it took an https://
address, changed it to http://, and tried its luck. That works for most German
stations and for very few Swiss ones. Everything the directory lists as
https-only was simply unreachable — the entire SRG family among them. Radio SRF 3
plays now. In AAC+.
Fitting TLS into a device with no PSRAM was the whole job:
| free heap | largest block | |
|---|---|---|
| at boot | 250,260 | 196,596 |
| running, http station | 129–134 KB | 86,004 |
| with the TLS context held open | 96–101 KB | 55,284 |
| running, https station | 13.8–28.5 KB | 7,668–9,716 |
The lowest free heap seen during an https stream was 5,480 bytes. Nothing
crashed. Nothing is left over either.
Three things got it there: rebuilt ESP-IDF libraries with an asymmetric mbedTLS
buffer (IN 16384, OUT 2048 — measured across 44 real https stations, none of
which ever sent more than 1,568 bytes outbound), one TLS context opened at boot
and never closed, and a patch to the audio library, which opens its own HTTP
client internally and had no way to be handed a TLS one.
A dropout is silence now, not a rattle
You know the sound: the network stutters and the speaker starts rattling — the
same fragment of audio, over and over, until it recovers.
It was never the decoder. The I2S output repeats its last DMA block when nobody
feeds it — 26 ms in a loop — and nobody had ever told it to fall silent instead.
One flag in the channel configuration, left at its default since forever.
On top of that the decoder now pauses below 8 KB of buffer instead of eating
every byte the moment it arrives, and resumes at 24 KB with a real head start.
Before, a single dropout threw the whole 56 KB ring away and the radio spent the
next seconds in a loop of fetch a scrap, play it, run dry.
That second half is Heotsan's idea, described
in issue #3. Thank
you — it was the piece I had looked past twice.
If nothing comes back for eight seconds the footer says Stream stopped - no data and the radio reconnects on its own.
The volume control finally behaves
1.9 dB per press, from the quietest step to full.
It used to be wildly lopsided — measured, not guessed: the first audible press
changed the level by 6.02 dB, the last one by 0.42 dB, and four presses out of
twenty-six did nothing at all.
The cause sat in the audio library, which keeps its gain in a single uint8_t:
64 steps between silence and full, spaced evenly in amplitude while the ear
hears in decibels. Below −36 dB there was nothing but silence, and the last step
before it was a 6 dB cliff. No curve fits into that. The radio no longer uses it
and scales the samples itself.
Everything else
- Charge Mode — a screen for a device on a charger. Stream, watchdog and the
Wi-Fi radio go off, the clock drops to 80 MHz, the charge level stands in
large digits, and the display goes dark after five seconds. - Keyboard shortcuts
v i e w l o sfor the meters, info screen, equalizer,
Wi-Fi, local list, online directory and sleep timer. - No flicker. Menus and overlays used to clear their area and then redraw it;
the panel has no back buffer, so that gap was visible. Everything paints opaque
over its own background now. - Long names scroll — station name, stream title, and the full stream address
on the info screen, with scheme and path. - No thump at station start. 500 ms of silence, then a two-second fade-in.
- The pre-buffer is 56 KB, requested first and filled before the first sample
is played. - An escape hatch for streams the decoder cannot read. An AAC stream that
reached the MP3 decoder used to lock the device up completely. - The battery shows a number, and the system menu scrolls by the pixel.
Fixed: logo downloads waited out their full eight-second deadline every single
time (the data was there after 75 ms), .ico logos were downloaded and then
thrown away, and VU meters drew into open lists.
Smaller, despite all of it
| v3.3.0 | v3.4.0 | |
|---|---|---|
| program | 2,919,043 | 2,892,091 |
| global variables | 102,164 | 90,960 |
| free under M5Launcher | 29 KB | 56 KB |
Before you build it yourself
Flashing the images below needs nothing special. Compiling the source now needs
four patches to ESP8266Audio and rebuilt ESP-IDF libraries, all documented with
before/after copies in
v3.4.0/library-patch/.
Only one of them is enforced by the compiler. Skip the ESP-IDF rebuild and your
build will run, play http stations, and fail every https handshake — the largest
free block will not be big enough. That is the one to read first.
Honest limits
HLS stations are recognised and skipped rather than played as noise. AAC+ plays
its base layer, because SBR wants memory this device does not have. The output
is mono — the Cardputer Adv has a mono codec, at the speaker and at the
headphone jack alike. Arabic, Hebrew and Thai need a text engine that is not
there.
Two things are measured and still unexplained, and are written down rather than
glossed over: why an https open() sometimes takes 43 KB instead of the expected
19–21, and why the memory ceiling drops by about 24 KB once per session and
stays down.
M5Launcher or SD card: Cardputer-WebRadio_v3.4.0.bin
M5Burner or a web flasher: Cardputer-WebRadio_v3.4.0_merged.bin, written to 0x0