f8f8a80a21
New ASSET_LOADER_TYPE_MP3 (hand-rolled MPEG-1/2/2.5 Layer III header parser - no third-party dependency needed just for metadata, since PSP's hardware path doesn't need one at all) plus a shared audiostreammp3.c stream layer mirroring audiostreampcm.c's shape. Generalized the stream dispatch (hoisted sampleRate/channels onto audiostream_t, added audioStreamGetTotalFrames()/Seek()/Read()) so all three platform audio backends keep working unchanged, just calling the generic names instead of PCM-specific ones. Two decoder backends behind one interface: PSP uses the real sceMp3 hardware decoder (firmware-offloaded, lazily initialized on first use); Linux and Dolphin share one minimp3-based software decoder (public domain, vendored via CMake FetchContent) - libogc's own MP3Player wraps libmad (GPL) and drives its own output pipeline, not a fit for the ansnd-based architecture already in place, so skipped in favor of the shared minimp3 path. Fixed three real bugs found via hardware/runtime testing along the way: - LAME's Xing header counts its own placeholder frame in the declared total, which made playback stall permanently one frame short of the declared end (looked like "never loops") - fixed by subtracting it. - sceMp3Decode() can return more PCM than one MPEG frame's worth in a single call (PSP's pcmBuf is provisioned for 2x), overflowing the shared per-frame decode buffer with no bound check - very intermittent corruption/clicking on real hardware. Widened the buffer to the real worst case and added an assertion. - sceMp3ResetPlayPosition()'s exact internal reset semantics aren't documented precisely enough to trust for looping - occasionally disagreed with the fresh stream position fed right after, clicking at the loop boundary about 1 in 3-4 loops. Rewind now fully tears down and recreates the decoder instead, the same path already proven correct at first Init. Also widened the PSP ring buffer to absorb that now-heavier operation, capping each top-up call's own work so the bigger buffer doesn't turn into one long blocking decode burst instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
29 lines
804 B
CMake
29 lines
804 B
CMake
# Copyright (c) 2026 Dominic Masters
|
|
#
|
|
# This software is released under the MIT License.
|
|
# https://opensource.org/licenses/MIT
|
|
|
|
# minimp3 has no tagged releases - pinned to a specific commit instead of a
|
|
# branch for reproducibility.
|
|
include(FetchContent)
|
|
FetchContent_Declare(
|
|
minimp3
|
|
GIT_REPOSITORY https://github.com/lieff/minimp3.git
|
|
GIT_TAG ea99364f61c14656440e8d77e9c233ccf3124633
|
|
)
|
|
|
|
FetchContent_MakeAvailable(minimp3)
|
|
|
|
set(MINIMP3_INCLUDE_DIR "${minimp3_SOURCE_DIR}")
|
|
set(MINIMP3_HEADER "${minimp3_SOURCE_DIR}/minimp3.h")
|
|
|
|
if(EXISTS "${MINIMP3_HEADER}")
|
|
add_library(minimp3 INTERFACE)
|
|
target_include_directories(minimp3 INTERFACE "${MINIMP3_INCLUDE_DIR}")
|
|
set(minimp3_FOUND TRUE)
|
|
else()
|
|
set(minimp3_FOUND FALSE)
|
|
endif()
|
|
|
|
mark_as_advanced(MINIMP3_INCLUDE_DIR MINIMP3_HEADER)
|