mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #19026 from hrydgard/minimp3-decoder
Decode MP3 without using ffmpeg
This commit is contained in:
commit
9953786156
5 changed files with 67 additions and 33 deletions
|
@ -511,7 +511,7 @@ static int sceMp3GetLoopNum(u32 mp3) {
|
|||
return hleLogError(ME, ERROR_MP3_UNRESERVED_HANDLE, "incorrect handle type");
|
||||
}
|
||||
|
||||
return hleLogSuccessI(ME, ctx->AuGetLoopNum());
|
||||
return hleLogSuccessI(ME, ctx->LoopNum);
|
||||
}
|
||||
|
||||
static int sceMp3GetMaxOutputSample(u32 mp3) {
|
||||
|
@ -555,7 +555,8 @@ static int sceMp3SetLoopNum(u32 mp3, int loop) {
|
|||
if (loop < 0)
|
||||
loop = -1;
|
||||
|
||||
return hleLogSuccessI(ME, ctx->AuSetLoopNum(loop));
|
||||
ctx->LoopNum = loop;
|
||||
return hleLogSuccessI(ME, 0);
|
||||
}
|
||||
|
||||
static int sceMp3GetMp3ChannelNum(u32 mp3) {
|
||||
|
|
|
@ -301,7 +301,7 @@ static u32 sceAacGetLoopNum(u32 id)
|
|||
ERROR_LOG(ME, "%s: bad aac id %08x", __FUNCTION__, id);
|
||||
return -1;
|
||||
}
|
||||
return ctx->AuGetLoopNum();
|
||||
return ctx->LoopNum;
|
||||
}
|
||||
|
||||
static u32 sceAacSetLoopNum(u32 id, int loop)
|
||||
|
@ -313,7 +313,8 @@ static u32 sceAacSetLoopNum(u32 id, int loop)
|
|||
return -1;
|
||||
}
|
||||
|
||||
return ctx->AuSetLoopNum(loop);
|
||||
ctx->LoopNum = loop;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sceAacCheckStreamDataNeeded(u32 id)
|
||||
|
|
|
@ -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
|
||||
|
@ -458,17 +500,6 @@ u32 AuCtx::AuDecode(u32 pcmAddr) {
|
|||
return outpcmbufsize;
|
||||
}
|
||||
|
||||
u32 AuCtx::AuGetLoopNum()
|
||||
{
|
||||
return LoopNum;
|
||||
}
|
||||
|
||||
u32 AuCtx::AuSetLoopNum(int loop)
|
||||
{
|
||||
LoopNum = loop;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// return 1 to read more data stream, 0 don't read
|
||||
int AuCtx::AuCheckStreamDataNeeded() {
|
||||
// If we would ask for bytes, then some are needed.
|
||||
|
|
|
@ -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; }
|
||||
|
@ -73,10 +75,6 @@ public:
|
|||
int AuStreamWorkareaSize();
|
||||
u32 AuResetPlayPosition();
|
||||
u32 AuResetPlayPositionByFrame(int position);
|
||||
|
||||
u32 AuSetLoopNum(int loop);
|
||||
u32 AuGetLoopNum();
|
||||
|
||||
u32 AuGetInfoToAddStreamData(u32 bufPtr, u32 sizePtr, u32 srcPosPtr);
|
||||
|
||||
void SetReadPos(int pos) { readPos = pos; }
|
||||
|
|
|
@ -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 \
|
||||
|
|
Loading…
Add table
Reference in a new issue