From ebbbdbe1bffdff32289c49b65d4d20213d4d6e7a Mon Sep 17 00:00:00 2001 From: Lee-Stone <2103539430@qq.com> Date: Mon, 6 Jul 2026 17:57:46 +0800 Subject: [PATCH 1/2] Skip ID3v2 tag body before MP3 decoding Binary data in ID3v2 tags (e.g., album art images) contains byte sequences that match MPEG frame sync words, causing MP3Decode to repeatedly return error -3 in a tight loop that starves the idle task and triggers the TG1WDT reset. This fix reads the ID3v2 header, calculates the tag size from the synchsafe integer, and fseeks past the tag body before decoding. --- audio_player.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/audio_player.cpp b/audio_player.cpp index 770de73..23ad75a 100644 --- a/audio_player.cpp +++ b/audio_player.cpp @@ -250,6 +250,18 @@ static esp_err_t aplay_file(audio_instance_t *i, FILE *fp) { if(is_mp3(fp)) { file_type = FILE_TYPE_MP3; LOGI_1("file is mp3"); + + // Skip ID3v2 tag body (is_mp3 already rewound, so we read from offset 0) + uint8_t head[10]; + if (fread(head, 1, 10, fp) == 10 && memcmp(head, "ID3", 3) == 0) { + uint32_t tag_size = ((uint32_t)head[6] << 21) | + ((uint32_t)head[7] << 14) | + ((uint32_t)head[8] << 7) | + (uint32_t)head[9]; + fseek(fp, tag_size, SEEK_CUR); + } else { + rewind(fp); + } // initialize mp3_instance i->mp3_data.bytes_in_data_buf = 0; From 28e05e0d73ab657e31b307979db042da5b3b47a2 Mon Sep 17 00:00:00 2001 From: Lee-Stone <2103539430@qq.com> Date: Mon, 6 Jul 2026 17:58:13 +0800 Subject: [PATCH 2/2] Reset MP3 decoder on file switch When switching between files, the Helix MP3 decoder's internal mainBuf[1940] bit reservoir retains stale data from the previous file. This corrupts the first frames of the new file and can cause unpredictable decode behavior. Free and reinitialize the decoder (MP3FreeDecoder + MP3InitDecoder) on every new file to ensure clean decoder state. --- audio_player.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/audio_player.cpp b/audio_player.cpp index 23ad75a..39c4312 100644 --- a/audio_player.cpp +++ b/audio_player.cpp @@ -263,6 +263,12 @@ static esp_err_t aplay_file(audio_instance_t *i, FILE *fp) { rewind(fp); } + // Reset decoder: clear bit reservoir state from previous file + if (i->mp3_decoder) { + MP3FreeDecoder(i->mp3_decoder); + } + i->mp3_decoder = MP3InitDecoder(); + // initialize mp3_instance i->mp3_data.bytes_in_data_buf = 0; i->mp3_data.read_ptr = i->mp3_data.data_buf;