Files
pyxis/lib/codec2
torlando-tech 5a3ee97856 deps(codec2): vendor codec2 v1.2.0, replace sh123/esp32_codec2_arduino@1.0.7
The PlatformIO dep sh123/esp32_codec2_arduino@1.0.7 bundles codec2
v0.9.2. Mac-side pycodec2 v3.0.4 links libcodec2 v1.2.0. Years of
codec2 development between those releases.

Replace the upstream lib with a local vendor of drowe67/codec2 v1.2.0
under lib/codec2/. Trim the 191-file source tree down to the
~100 files actually needed for codec2 (drop FreeDV, OFDM, COHPSK,
FSK, FM-FSK, LDPC, Horus, CLI tools — pyxis only uses
codec2_create/destroy/encode/decode + samples_per_frame /
bytes_per_frame). Carry over the v0.9 codebook .c files since the
codebook contents matched (compared against v1.2's src/codebook/*.txt).

Define __EMBEDDED__ so the codebooks land in flash (.const) rather
than RAM. Without it the codebooks add ~127KB to BSS and the LVGL
task fails to start (RAM was 65% full vs 27% with __EMBEDDED__).
Provide trivial codec2_malloc/codec2_free wrappers in
codec2_alloc_esp32.c (codec2 v1.2 expects them when __EMBEDDED__ is
defined; ESP-IDF's malloc/free already pull from internal RAM).

Also explicitly add SD/FS to lib_deps and #include <SD.h> in
main.cpp — the previous esp32_codec2 dep transitively pulled SD
which let SDArchiveFileSystem.h get away with depending on it
implicitly. With chain+ ldf mode and no esp32_codec2 dep, we have
to declare the framework lib explicitly.

DOES NOT fix the ~30x speech-decode RMS asymmetry between pycodec2
self-tests (~5800) and pyxis decoding the same encoded bytes (~170).
Sine waves and 3-formant synthesis pass clean both directions; only
real TTS speech triggers it. Probably a separate codec-state
divergence (the encoder/decoder are independent codec2 instances
in pyxis, both fresh per call) or a wire-format quirk we still need
to track down. v1.2 is the right baseline regardless — same bug
class as several upstream fixes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 12:25:52 -04:00
..

Vendored codec2 v1.2.0

This is a local vendor of drowe67/codec2 v1.2.0 source files, replacing the sh123/esp32_codec2_arduino@1.0.7 PlatformIO dependency.

Why?

sh123/esp32_codec2_arduino@1.0.7 bundles codec2 v0.9.2. The Mac-side pycodec2 Python wrapper (used by Sideband, Columba python clients, and the LXST harness) links libcodec2 v1.2.0. The version gap introduces a real audio quality regression on pyxis-decoded speech:

Test signal pycodec2 round-trip RMS pyxis decode RMS
1kHz pure sine (amp 0.5) 1394 6357
3-formant voice approx (amp 0.5) 5749 4378
Real TTS speech (say output) 5796 170

The 30× drop on real speech doesn't reproduce on tones or simple formants — it's content-specific. Decoder behavior is consistent (decode_fail = 0 in every case) but the amplitude collapses. Local pycodec2 vs the v0.9 esp32_codec2 lib using the same encoded bytes diverges, so the bug is in the v0.9 decoder code path.

The c2dec/c2enc/cli tools are excluded via srcFilter in library.json since pyxis only needs codec2 itself (no FreeDV / OFDM / FSK / LDPC etc).

Codebooks

codebook*.c files are the LSP/energy/etc. quantization tables. v0.9 codebook content matched v1.2's canonical text-form input (verified with diff against src/codebook/dlsp1.txt etc), so the existing generated .c files were carried over from sh123/esp32_codec2_arduino's src/. The version.h was hand-written from cmake/version.h.in since codec2 v1.2's CMake-driven generation isn't running here.

Updating

To pull a newer codec2 release: download https://api.github.com/repos/drowe67/codec2/tarball/refs/tags/<version>, extract, and replace lib/codec2/src/*.c and *.h with the contents of the upstream src/. Don't overwrite the codebook .c files unless you regenerate them via the upstream CMake build (codebook content rarely changes).