Skip to content

Commit 9953786

Browse files
authored
Merge pull request #19026 from hrydgard/minimp3-decoder
Decode MP3 without using ffmpeg
2 parents 423e3d3 + db929ea commit 9953786

File tree

5 files changed

+67
-33
lines changed

5 files changed

+67
-33
lines changed

Core/HLE/sceMp3.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ static int sceMp3GetLoopNum(u32 mp3) {
511511
return hleLogError(ME, ERROR_MP3_UNRESERVED_HANDLE, "incorrect handle type");
512512
}
513513

514-
return hleLogSuccessI(ME, ctx->AuGetLoopNum());
514+
return hleLogSuccessI(ME, ctx->LoopNum);
515515
}
516516

517517
static int sceMp3GetMaxOutputSample(u32 mp3) {
@@ -555,7 +555,8 @@ static int sceMp3SetLoopNum(u32 mp3, int loop) {
555555
if (loop < 0)
556556
loop = -1;
557557

558-
return hleLogSuccessI(ME, ctx->AuSetLoopNum(loop));
558+
ctx->LoopNum = loop;
559+
return hleLogSuccessI(ME, 0);
559560
}
560561

561562
static int sceMp3GetMp3ChannelNum(u32 mp3) {

Core/HLE/sceMp4.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ static u32 sceAacGetLoopNum(u32 id)
301301
ERROR_LOG(ME, "%s: bad aac id %08x", __FUNCTION__, id);
302302
return -1;
303303
}
304-
return ctx->AuGetLoopNum();
304+
return ctx->LoopNum;
305305
}
306306

307307
static u32 sceAacSetLoopNum(u32 id, int loop)
@@ -313,7 +313,8 @@ static u32 sceAacSetLoopNum(u32 id, int loop)
313313
return -1;
314314
}
315315

316-
return ctx->AuSetLoopNum(loop);
316+
ctx->LoopNum = loop;
317+
return 0;
317318
}
318319

319320
static int sceAacCheckStreamDataNeeded(u32 id)

Core/HW/SimpleAudioDec.cpp

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "Core/HW/MediaEngine.h"
2727
#include "Core/HW/BufferQueue.h"
2828

29+
#include "ext/minimp3/minimp3.h"
30+
2931
#ifdef USE_FFMPEG
3032

3133
extern "C" {
@@ -49,14 +51,58 @@ extern "C" {
4951

5052
#endif // USE_FFMPEG
5153

54+
// minimp3-based decoder.
55+
class MiniMp3Audio : public AudioDecoder {
56+
public:
57+
MiniMp3Audio() {
58+
mp3dec_init(&mp3_);
59+
}
60+
~MiniMp3Audio() {}
61+
62+
bool Decode(const uint8_t* inbuf, int inbytes, uint8_t *outbuf, int *outbytes) override {
63+
mp3dec_frame_info_t info{};
64+
int samplesWritten = mp3dec_decode_frame(&mp3_, inbuf, inbytes, (mp3d_sample_t *)outbuf, &info);
65+
srcPos_ = info.frame_bytes;
66+
*outbytes = samplesWritten * sizeof(mp3d_sample_t) * info.channels;
67+
outSamples_ = samplesWritten * info.channels;
68+
return true;
69+
}
70+
71+
bool IsOK() const override { return true; }
72+
int GetOutSamples() const override {
73+
return outSamples_;
74+
}
75+
int GetSourcePos() const override {
76+
return srcPos_;
77+
}
78+
79+
void SetChannels(int channels) override {
80+
// Hmm. ignore for now.
81+
}
82+
83+
PSPAudioType GetAudioType() const override { return PSP_CODEC_MP3; }
84+
85+
private:
86+
// We use the lowest-level API.
87+
mp3dec_t mp3_{};
88+
int outSamples_ = 0;
89+
int srcPos_ = 0;
90+
};
91+
5292
// FFMPEG-based decoder. TODO: Replace with individual codecs.
5393
class SimpleAudio : public AudioDecoder {
5494
public:
5595
SimpleAudio(PSPAudioType audioType, int sampleRateHz = 44100, int channels = 2);
5696
~SimpleAudio();
5797

5898
bool Decode(const uint8_t* inbuf, int inbytes, uint8_t *outbuf, int *outbytes) override;
59-
bool IsOK() const override;
99+
bool IsOK() const override {
100+
#ifdef USE_FFMPEG
101+
return codec_ != 0;
102+
#else
103+
return 0;
104+
#endif
105+
}
60106

61107
int GetOutSamples() const override {
62108
return outSamples;
@@ -67,11 +113,10 @@ class SimpleAudio : public AudioDecoder {
67113

68114
// Not save stated, only used by UI. Used for ATRAC3 (non+) files.
69115
void SetExtraData(const uint8_t *data, int size, int wav_bytes_per_packet) override;
70-
71116
void SetChannels(int channels) override;
72117

73118
// These two are only here because of save states.
74-
PSPAudioType GetAudioType() const { return audioType; }
119+
PSPAudioType GetAudioType() const override { return audioType; }
75120

76121
private:
77122
bool OpenCodec(int block_align);
@@ -95,7 +140,12 @@ class SimpleAudio : public AudioDecoder {
95140

96141
// TODO: This should also be able to create other types of decoders.
97142
AudioDecoder *CreateAudioDecoder(PSPAudioType audioType, int sampleRateHz, int channels) {
98-
return new SimpleAudio(audioType, sampleRateHz, channels);
143+
switch (audioType) {
144+
case PSP_CODEC_MP3:
145+
return new MiniMp3Audio();
146+
default:
147+
return new SimpleAudio(audioType, sampleRateHz, channels);
148+
}
99149
}
100150

101151
static int GetAudioCodecID(int audioType) {
@@ -230,14 +280,6 @@ SimpleAudio::~SimpleAudio() {
230280
#endif // USE_FFMPEG
231281
}
232282

233-
bool SimpleAudio::IsOK() const {
234-
#ifdef USE_FFMPEG
235-
return codec_ != 0;
236-
#else
237-
return 0;
238-
#endif
239-
}
240-
241283
// Decodes a single input frame.
242284
bool SimpleAudio::Decode(const uint8_t *inbuf, int inbytes, uint8_t *outbuf, int *outbytes) {
243285
#ifdef USE_FFMPEG
@@ -458,17 +500,6 @@ u32 AuCtx::AuDecode(u32 pcmAddr) {
458500
return outpcmbufsize;
459501
}
460502

461-
u32 AuCtx::AuGetLoopNum()
462-
{
463-
return LoopNum;
464-
}
465-
466-
u32 AuCtx::AuSetLoopNum(int loop)
467-
{
468-
LoopNum = loop;
469-
return 0;
470-
}
471-
472503
// return 1 to read more data stream, 0 don't read
473504
int AuCtx::AuCheckStreamDataNeeded() {
474505
// If we would ask for bytes, then some are needed.

Core/HW/SimpleAudioDec.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,17 @@ class AudioDecoder {
3737
public:
3838
virtual ~AudioDecoder() {}
3939

40+
virtual PSPAudioType GetAudioType() const = 0;
41+
4042
virtual bool Decode(const uint8_t* inbuf, int inbytes, uint8_t *outbuf, int *outbytes) = 0;
4143
virtual bool IsOK() const = 0;
4244

45+
// These two are only ever called after Decode, so can initialize on first.
4346
virtual int GetOutSamples() const = 0;
4447
virtual int GetSourcePos() const = 0;
45-
virtual PSPAudioType GetAudioType() const = 0;
4648

4749
virtual void SetChannels(int channels) = 0;
48-
virtual void SetExtraData(const uint8_t *data, int size, int wav_bytes_per_packet) = 0;
50+
virtual void SetExtraData(const uint8_t *data, int size, int wav_bytes_per_packet) {}
4951

5052
// Just metadata.
5153
void SetCtxPtr(uint32_t ptr) { ctxPtr = ptr; }
@@ -73,10 +75,6 @@ class AuCtx {
7375
int AuStreamWorkareaSize();
7476
u32 AuResetPlayPosition();
7577
u32 AuResetPlayPositionByFrame(int position);
76-
77-
u32 AuSetLoopNum(int loop);
78-
u32 AuGetLoopNum();
79-
8078
u32 AuGetInfoToAddStreamData(u32 bufPtr, u32 sizePtr, u32 srcPosPtr);
8179

8280
void SetReadPos(int pos) { readPos = pos; }

libretro/Makefile.common

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ endif
171171

172172
SOURCES_C += $(LIBRETRODIR)/ext/glew/glew.c
173173

174+
SOURCES_C += \
175+
$(EXTDIR)/minimp3/minimp3.cpp
176+
174177
SOURCES_C += \
175178
$(EXTDIR)/libkirk/AES.c \
176179
$(EXTDIR)/libkirk/amctrl.c \

0 commit comments

Comments
 (0)