Skip to content

fix(mp3): skip ID3v2 tags, reset decoder on file switch, increase task stack - #23

Open
Lee-Stone wants to merge 2 commits into
chmorgan:mainfrom
Lee-Stone:main
Open

fix(mp3): skip ID3v2 tags, reset decoder on file switch, increase task stack#23
Lee-Stone wants to merge 2 commits into
chmorgan:mainfrom
Lee-Stone:main

Conversation

@Lee-Stone

Copy link
Copy Markdown

Summary

This PR fixes crashes (TG1WDT reset / double exception) that occur when playing certain MP3 files, especially those with large ID3v2 tags (e.g., embedded album art). The root cause is a combination of three issues that together cause the decoder to enter a tight error loop, starving the system watchdog.

Key Changes

Bug Fixes

  • Skip ID3v2 tag body before decoding (audio_player.cpp): is_mp3() detects ID3v2 headers but does not skip the tag body. Binary data in the tag (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 watchdog.

  • Reset MP3 decoder on file switch (audio_player.cpp): 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. The decoder is now freed and reinitialized (MP3FreeDecoder + MP3InitDecoder) on every new file.

  • Increase audio task stack from 4KB to 6KB (audio_player.cpp): The Helix decoder's internal structure plus the call chain (audio_task → aplay_file → decode_mp3 → MP3Decode) can exceed 4KB of stack on complex MP3 frames, leading to a double exception (_DoubleExceptionVector).

Symptoms Fixed

  • Playing MP3 files with large ID3v2 tags (album art) as the first song after boot → crash
  • Playing certain MP3 files regardless of playback order → crash
  • Switching from a working song to a previously-crashing song → no crash (masked by stale decoder state)

@chmorgan

chmorgan commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Good catch on these issues and thank you for reporting it along with fixes. Can you separate this into three separate commits so each change can be evaluated separately?

Lee-Stone added 2 commits July 6, 2026 17:57
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.
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.
@Lee-Stone
Lee-Stone force-pushed the main branch 2 times, most recently from 0037e7f to 28e05e0 Compare July 6, 2026 10:03
@Lee-Stone

Copy link
Copy Markdown
Author

Thanks for the review! Split into two commits:

  • ebbbdbe — Skip ID3v2 tag body before decoding, so binary data (e.g. album art) isn't mistaken for MPEG frame sync, which caused the decoder to spin in an error loop and starve the watchdog.
  • 28e05e0 — Reset Helix decoder on file switch to clear stale bit reservoir state from the previous file.

Dropped the stack size increase — the tight error loop in fix ebbbdbe was the real cause of the stack overflow, so the existing 4 KB is fine once that's addressed.

Comment thread audio_player.cpp
Comment thread audio_player.cpp
@chmorgan

Copy link
Copy Markdown
Owner

@Lee-Stone I pushed #25, can you take a look? It should address the id3v2 tags issue.

@Lee-Stone

Copy link
Copy Markdown
Author

@Lee-Stone I pushed #25, can you take a look? It should address the id3v2 tags issue.

I tested #25 on my project, and my mp3 files play normally now. Perfect solution!

@chmorgan

Copy link
Copy Markdown
Owner

@Lee-Stone I've merged an alternative id3v2 tag fix, if the stack size and decoder reset are still necessary can you rebase and re-push?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants