From db929ea042c72b3fda26f6f78cd7948c3f785f13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 10 Apr 2024 13:45:45 +0200 Subject: [PATCH] Use minimp3 for in-game mp3 decoding. Doesn't solve any issues it seems, but works like before. --- Core/HW/SimpleAudioDec.cpp | 66 +++++++++++++++++++++++++++++++------- Core/HW/SimpleAudioDec.h | 6 ++-- libretro/Makefile.common | 3 ++ 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/Core/HW/SimpleAudioDec.cpp b/Core/HW/SimpleAudioDec.cpp index f5732af453..af5613db61 100644 --- a/Core/HW/SimpleAudioDec.cpp +++ b/Core/HW/SimpleAudioDec.cpp @@ -26,6 +26,8 @@ #include "Core/HW/MediaEngine.h" #include "Core/HW/BufferQueue.h" +#include "ext/minimp3/minimp3.h" + #ifdef USE_FFMPEG extern "C" { @@ -49,6 +51,44 @@ extern "C" { #endif // USE_FFMPEG +// minimp3-based decoder. +class MiniMp3Audio : public AudioDecoder { +public: + MiniMp3Audio() { + mp3dec_init(&mp3_); + } + ~MiniMp3Audio() {} + + bool Decode(const uint8_t* inbuf, int inbytes, uint8_t *outbuf, int *outbytes) override { + mp3dec_frame_info_t info{}; + int samplesWritten = mp3dec_decode_frame(&mp3_, inbuf, inbytes, (mp3d_sample_t *)outbuf, &info); + srcPos_ = info.frame_bytes; + *outbytes = samplesWritten * sizeof(mp3d_sample_t) * info.channels; + outSamples_ = samplesWritten * info.channels; + return true; + } + + bool IsOK() const override { return true; } + int GetOutSamples() const override { + return outSamples_; + } + int GetSourcePos() const override { + return srcPos_; + } + + void SetChannels(int channels) override { + // Hmm. ignore for now. + } + + PSPAudioType GetAudioType() const override { return PSP_CODEC_MP3; } + +private: + // We use the lowest-level API. + mp3dec_t mp3_{}; + int outSamples_ = 0; + int srcPos_ = 0; +}; + // FFMPEG-based decoder. TODO: Replace with individual codecs. class SimpleAudio : public AudioDecoder { public: @@ -56,7 +96,13 @@ public: ~SimpleAudio(); bool Decode(const uint8_t* inbuf, int inbytes, uint8_t *outbuf, int *outbytes) override; - bool IsOK() const override; + bool IsOK() const override { +#ifdef USE_FFMPEG + return codec_ != 0; +#else + return 0; +#endif + } int GetOutSamples() const override { return outSamples; @@ -67,11 +113,10 @@ public: // Not save stated, only used by UI. Used for ATRAC3 (non+) files. void SetExtraData(const uint8_t *data, int size, int wav_bytes_per_packet) override; - void SetChannels(int channels) override; // These two are only here because of save states. - PSPAudioType GetAudioType() const { return audioType; } + PSPAudioType GetAudioType() const override { return audioType; } private: bool OpenCodec(int block_align); @@ -95,7 +140,12 @@ private: // TODO: This should also be able to create other types of decoders. AudioDecoder *CreateAudioDecoder(PSPAudioType audioType, int sampleRateHz, int channels) { - return new SimpleAudio(audioType, sampleRateHz, channels); + switch (audioType) { + case PSP_CODEC_MP3: + return new MiniMp3Audio(); + default: + return new SimpleAudio(audioType, sampleRateHz, channels); + } } static int GetAudioCodecID(int audioType) { @@ -230,14 +280,6 @@ SimpleAudio::~SimpleAudio() { #endif // USE_FFMPEG } -bool SimpleAudio::IsOK() const { -#ifdef USE_FFMPEG - return codec_ != 0; -#else - return 0; -#endif -} - // Decodes a single input frame. bool SimpleAudio::Decode(const uint8_t *inbuf, int inbytes, uint8_t *outbuf, int *outbytes) { #ifdef USE_FFMPEG diff --git a/Core/HW/SimpleAudioDec.h b/Core/HW/SimpleAudioDec.h index dd18ee60c2..e4c2cf0116 100644 --- a/Core/HW/SimpleAudioDec.h +++ b/Core/HW/SimpleAudioDec.h @@ -37,15 +37,17 @@ class AudioDecoder { public: virtual ~AudioDecoder() {} + virtual PSPAudioType GetAudioType() const = 0; + virtual bool Decode(const uint8_t* inbuf, int inbytes, uint8_t *outbuf, int *outbytes) = 0; virtual bool IsOK() const = 0; + // These two are only ever called after Decode, so can initialize on first. virtual int GetOutSamples() const = 0; virtual int GetSourcePos() const = 0; - virtual PSPAudioType GetAudioType() const = 0; virtual void SetChannels(int channels) = 0; - virtual void SetExtraData(const uint8_t *data, int size, int wav_bytes_per_packet) = 0; + virtual void SetExtraData(const uint8_t *data, int size, int wav_bytes_per_packet) {} // Just metadata. void SetCtxPtr(uint32_t ptr) { ctxPtr = ptr; } diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 117846e66e..d698f90632 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -171,6 +171,9 @@ endif SOURCES_C += $(LIBRETRODIR)/ext/glew/glew.c +SOURCES_C += \ + $(EXTDIR)/minimp3/minimp3.cpp + SOURCES_C += \ $(EXTDIR)/libkirk/AES.c \ $(EXTDIR)/libkirk/amctrl.c \