ESP32-C6 low-latency audio decoding
Posted: Tue Aug 05, 2025 4:06 pm
Hello
I'm trying to stream encoded audio to a ESP32-C6, decode it and play it back via I2S.
Currently, I use the OPUS codec in https://github.com/espressif/esp-adf-li ... udio_codec for decoding.
Parameters are Stereo, 48kHz and 5ms samples. The samples are encoded on a x86 machine with libopus.
Unfortunately, the ESP32-C6 struggles with this task. The decoder task, which runs esp_opus_dec_decode(), is taking up nearly all cycles.
It is so bad that the TWDT triggers regularly, which slows down the system even more due to printing to serial.
Are there any ways to optimize this? The network protocol is already optimized quite a bit.
The TWDT messages are gone when running the application on a ESP32-S3.
Unfortunately the ESP32-S3 is not suitable for my application due too big light-sleep current.
The reason for OPUS till now is that is allows for easy synchronization between multiple ESP32 due to the short 5ms samples.
I'm trying to stream encoded audio to a ESP32-C6, decode it and play it back via I2S.
Currently, I use the OPUS codec in https://github.com/espressif/esp-adf-li ... udio_codec for decoding.
Parameters are Stereo, 48kHz and 5ms samples. The samples are encoded on a x86 machine with libopus.
Unfortunately, the ESP32-C6 struggles with this task. The decoder task, which runs esp_opus_dec_decode(), is taking up nearly all cycles.
It is so bad that the TWDT triggers regularly, which slows down the system even more due to printing to serial.
Code: Select all
decoder 131214982 88%
websocket_clien 4967571 3%
IDLE 4259361 2%
tiT 1947887 1%
esp_timer 267326 <1%
wifi 3709050 2%
soundcard 1212308 <1%
sys_evt 1287 <1%
Tmr Svc 8 <1%Code: Select all
E (96837) task_wdt: Task watchdog got triggered. The following tasks/users did not reset the watchdog in time:
E (96837) task_wdt: - IDLE (CPU 0)
E (96837) task_wdt: Tasks currently running:
E (96837) task_wdt: CPU 0: decoder
E (96837) task_wdt: Print CPU 0 (current core) registers
Core 0 register dump:
MEPC : 0x4201584e RA : 0x4201709c SP : 0x4084cee0 GP : 0x4081b924
--- 0x4201584e: deemphasis at celt_decoder.c.obj:?
--- 0x4201709c: celt_decode_with_ec at ??:?
TP : 0x4084d920 T0 : 0x0525e995 T1 : 0x00006ccd T2 : 0xe6530b7e
S0/FP : 0x4084cf30 S1 : 0x4084d720 A0 : 0x40851cac A1 : 0xffc08737
A2 : 0x000003c0 A3 : 0x00000002 A4 : 0x00000001 A5 : 0x002f85ec
A6 : 0x40850064 A7 : 0x00000000 S2 : 0x000000f0 S3 : 0x00000001
S4 : 0x420d28ac S5 : 0x00000054 S6 : 0x4084d658 S7 : 0x4085448c
S8 : 0x40854534 S9 : 0x4084d658 S10 : 0x4084da50 S11 : 0x408544e0
T3 : 0x40853e8c T4 : 0x0b0c0b0f T5 : 0x00001000 T6 : 0x00008000
MSTATUS : 0x00001889 MTVEC : 0x40800001 MCAUSE : 0xdeadc0de MTVAL : 0xdeadc0de
--- 0x40800001: _vector_table at /home/user/esp/esp-idf/components/riscv/vectors_intc.S:54
MHARTID : 0x00000000
Please enable CONFIG_ESP_SYSTEM_USE_FRAME_POINTER option to have a full backtrace.The TWDT messages are gone when running the application on a ESP32-S3.
Unfortunately the ESP32-S3 is not suitable for my application due too big light-sleep current.
The reason for OPUS till now is that is allows for easy synchronization between multiple ESP32 due to the short 5ms samples.