bug: initial Opus burst causes ESP32-C3 playback cutoff

Author: yillkidCreated Sep 4, 2026Updated Sep 4, 2026

Description

The WebSocket TTS sender transmits the initial Opus pre-buffer too quickly for some ESP32-C3 clients. On ESP-HI firmware 2.2.6, playback is cut off after roughly one syllable and the device may subsequently reboot.

core/handle/sendAudioHandle.py currently defines:

python
PRE_BUFFER_COUNT = 5

The first five packets bypass rate control. In practice, the first six 60 ms frames were sent within 10 ms:

frame 0:   0 ms
frame 1:   2 ms
frame 2:   4 ms
frame 3:   5 ms
frame 4:   7 ms
frame 5:  10 ms
frame 6:  71 ms

This bursts approximately 360 ms of Opus audio into the device receive buffer almost immediately.

Verified workaround

Changing PRE_BUFFER_COUNT to 0 makes every frame follow the 60 ms rate controller:

frame 0:   0 ms
frame 1:  60 ms
frame 2: 122 ms
frame 3: 181 ms
frame 4: 240 ms
frame 5: 301 ms

After this change, the same ESP-HI device played the complete sentence 你好,很高興認識你 in two consecutive tests without a new OTA request or reboot.

Suggested fix

Make the pre-buffer count configurable, lower it for constrained ESP32-C3 devices, or default WebSocket clients to paced delivery from the first frame.

Environment

  • Server: 0.9.6
  • Device: ESP-HI / ESP32-C3
  • Firmware: esp-hi/2.2.6
  • Transport: WSS, protocol version 1
  • Opus frame duration: 60 ms
  • Output sample rate: 16 kHz

Source: xinnan-tech/xiaozhi-esp32-server