1 // Copyright (c) 2013- PPSSPP Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0 or later versions.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official git repository and contact information can be found at
16 // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
20 #include "Core/Config.h"
21 #include "Core/HLE/FunctionWrappers.h"
22 #include "Core/HW/SimpleAudioDec.h"
23 #include "Core/HW/MediaEngine.h"
24 #include "Core/HW/BufferQueue.h"
29 #include "libavformat/avformat.h"
30 #include "libswresample/swresample.h"
31 #include "libavutil/samplefmt.h"
36 int SimpleAudio::GetAudioCodecID(int audioType
) {
40 return AV_CODEC_ID_AAC
;
42 return AV_CODEC_ID_ATRAC3
;
43 case PSP_CODEC_AT3PLUS
:
44 return AV_CODEC_ID_ATRAC3P
;
46 return AV_CODEC_ID_MP3
;
48 return AV_CODEC_ID_NONE
;
55 SimpleAudio::SimpleAudio(int audioType
, int sample_rate
, int channels
)
56 : ctxPtr(0xFFFFFFFF), audioType(audioType
), sample_rate_(sample_rate
), channels_(channels
),
57 outSamples(0), srcPos(0), wanted_resample_freq(44100), frame_(0), codec_(0), codecCtx_(0), swrCtx_(0),
58 extradata_(0), codecOpen_(false) {
62 void SimpleAudio::Init() {
64 avcodec_register_all();
68 frame_
= av_frame_alloc();
70 // Get Audio Codec ctx
71 int audioCodecId
= GetAudioCodecID(audioType
);
73 ERROR_LOG(ME
, "This version of FFMPEG does not support Audio codec type: %08x. Update your submodule.", audioType
);
77 codec_
= avcodec_find_decoder((AVCodecID
)audioCodecId
);
79 // Eh, we shouldn't even have managed to compile. But meh.
80 ERROR_LOG(ME
, "This version of FFMPEG does not support AV_CODEC_ctx for audio (%s). Update your submodule.", GetCodecName(audioType
));
83 // Allocate codec context
84 codecCtx_
= avcodec_alloc_context3(codec_
);
86 ERROR_LOG(ME
, "Failed to allocate a codec context");
89 codecCtx_
->channels
= channels_
;
90 codecCtx_
->channel_layout
= channels_
== 2 ? AV_CH_LAYOUT_STEREO
: AV_CH_LAYOUT_MONO
;
91 codecCtx_
->sample_rate
= sample_rate_
;
96 bool SimpleAudio::OpenCodec(int block_align
) {
98 // Some versions of FFmpeg require this set. May be set in SetExtraData(), but optional.
99 // When decoding, we decode by packet, so we know the size.
100 if (codecCtx_
->block_align
== 0) {
101 codecCtx_
->block_align
= block_align
;
104 AVDictionary
*opts
= 0;
105 int retval
= avcodec_open2(codecCtx_
, codec_
, &opts
);
107 ERROR_LOG(ME
, "Failed to open codec: retval = %i", retval
);
117 bool SimpleAudio::ResetCodecCtx(int channels
, int samplerate
) {
120 avcodec_close(codecCtx_
);
123 int audioCodecId
= GetAudioCodecID(audioType
);
124 codec_
= avcodec_find_decoder((AVCodecID
)audioCodecId
);
126 // Eh, we shouldn't even have managed to compile. But meh.
127 ERROR_LOG(ME
, "This version of FFMPEG does not support AV_CODEC_ctx for audio (%s). Update your submodule.", GetCodecName(audioType
));
131 codecCtx_
->channels
= channels
;
132 codecCtx_
->channel_layout
= channels
==2?AV_CH_LAYOUT_STEREO
:AV_CH_LAYOUT_MONO
;
133 codecCtx_
->sample_rate
= samplerate
;
140 void SimpleAudio::SetExtraData(u8
*data
, int size
, int wav_bytes_per_packet
) {
141 delete [] extradata_
;
145 extradata_
= new u8
[size
];
146 memcpy(extradata_
, data
, size
);
151 codecCtx_
->extradata
= extradata_
;
152 codecCtx_
->extradata_size
= size
;
153 codecCtx_
->block_align
= wav_bytes_per_packet
;
159 SimpleAudio::~SimpleAudio() {
164 av_frame_free(&frame_
);
166 avcodec_close(codecCtx_
);
171 delete [] extradata_
;
175 bool SimpleAudio::IsOK() const {
183 bool SimpleAudio::Decode(void *inbuf
, int inbytes
, uint8_t *outbuf
, int *outbytes
) {
190 av_init_packet(&packet
);
191 packet
.data
= static_cast<uint8_t *>(inbuf
);
192 packet
.size
= inbytes
;
195 av_frame_unref(frame_
);
199 int len
= avcodec_decode_audio4(codecCtx_
, frame_
, &got_frame
, &packet
);
201 ERROR_LOG(ME
, "Error decoding Audio frame (%i bytes): %i (%08x)", inbytes
, len
, len
);
205 av_free_packet(&packet
);
207 // get bytes consumed in source
211 // Initializing the sample rate convert. We will use it to convert float output into int.
212 int64_t wanted_channel_layout
= AV_CH_LAYOUT_STEREO
; // we want stereo output layout
213 int64_t dec_channel_layout
= frame_
->channel_layout
; // decoded channel layout
216 swrCtx_
= swr_alloc_set_opts(
218 wanted_channel_layout
,
220 wanted_resample_freq
,
222 codecCtx_
->sample_fmt
,
223 codecCtx_
->sample_rate
,
227 if (!swrCtx_
|| swr_init(swrCtx_
) < 0) {
228 ERROR_LOG(ME
, "swr_init: Failed to initialize the resampling context");
229 avcodec_close(codecCtx_
);
235 // convert audio to AV_SAMPLE_FMT_S16
236 int swrRet
= swr_convert(swrCtx_
, &outbuf
, frame_
->nb_samples
, (const u8
**)frame_
->extended_data
, frame_
->nb_samples
);
238 ERROR_LOG(ME
, "swr_convert: Error while converting: %d", swrRet
);
241 // output samples per frame, we should *2 since we have two channels
242 outSamples
= swrRet
* 2;
244 // each sample occupies 2 bytes
245 *outbytes
= outSamples
* 2;
247 // Save outbuf into pcm audio, you can uncomment this line to save and check the decoded audio into pcm file.
248 // SaveAudio("dump.pcm", outbuf, *outbytes);
252 // Zero bytes output. No need to memset.
258 int SimpleAudio::GetOutSamples() {
262 int SimpleAudio::GetSourcePos() {
266 void AudioClose(SimpleAudio
**ctx
) {
274 static const char *const codecNames
[4] = {
275 "AT3+", "AT3", "MP3", "AAC",
278 const char *GetCodecName(int codec
) {
279 if (codec
>= PSP_CODEC_AT3PLUS
&& codec
<= PSP_CODEC_AAC
) {
280 return codecNames
[codec
- PSP_CODEC_AT3PLUS
];
286 bool IsValidCodec(int codec
){
287 if (codec
>= PSP_CODEC_AT3PLUS
&& codec
<= PSP_CODEC_AAC
) {
294 // sceAu module starts from here
306 SamplingRate
= 44100;
311 SumDecodedSamples
= 0;
321 AudioClose(&decoder
);
326 // return output pcm size, <0 error
327 u32
AuCtx::AuDecode(u32 pcmAddr
)
329 if (!Memory::IsValidAddress(pcmAddr
)){
330 ERROR_LOG(ME
, "%s: output bufferAddress %08x is invalctx", __FUNCTION__
, pcmAddr
);
334 auto outbuf
= Memory::GetPointer(PCMBuf
);
335 memset(outbuf
, 0, PCMBufSize
); // important! empty outbuf to avoid noise
336 u32 outpcmbufsize
= 0;
339 if (g_Config
.bSoundSpeedHack
){
343 // decode frames in sourcebuff and output into PCMBuf (each time, we decode one or two frames)
344 // some games as Miku like one frame each time, some games like DOA like two frames each time
345 while (sourcebuff
.size() > 0 && outpcmbufsize
< PCMBufSize
&& i
< repeat
){
349 decoder
->Decode((void*)sourcebuff
.c_str(), (int)sourcebuff
.size(), outbuf
, &pcmframesize
);
350 if (pcmframesize
== 0){
351 // no output pcm, we are at the end of the stream
355 // if we loop, reset readPos
360 // count total output pcm size
361 outpcmbufsize
+= pcmframesize
;
362 // count total output samples
363 SumDecodedSamples
+= decoder
->GetOutSamples();
364 // get consumed source length
365 int srcPos
= decoder
->GetSourcePos();
366 // remove the consumed source
367 sourcebuff
.erase(0, srcPos
);
368 // reduce the available Aubuff size
369 // (the available buff size is now used to know if we can read again from file and how many to read)
370 AuBufAvailable
-= srcPos
;
371 // move outbuff position to the current end of output
372 outbuf
+= pcmframesize
;
373 // increase FrameNum count
376 Memory::Write_U32(PCMBuf
, pcmAddr
);
377 return outpcmbufsize
;
380 u32
AuCtx::AuGetLoopNum()
385 u32
AuCtx::AuSetLoopNum(int loop
)
391 // return 1 to read more data stream, 0 don't read
392 int AuCtx::AuCheckStreamDataNeeded()
394 // if we have no available Au buffer, and the current read position in source file is not the end of stream, then we can read
395 if (AuBufAvailable
< (int)AuBufSize
&& readPos
< (int)endPos
){
401 // check how many bytes we have read from source file
402 u32
AuCtx::AuNotifyAddStreamData(int size
)
405 int diffsize
= realReadSize
- askedReadSize
;
406 // Notify the real read size
409 AuBufAvailable
+= diffsize
;
412 // append AuBuf into sourcebuff
413 sourcebuff
.append((const char*)Memory::GetPointer(AuBuf
), size
);
415 if (readPos
>= (int)endPos
&& LoopNum
!= 0){
416 // if we need loop, reset readPos
427 // read from stream position srcPos of size bytes into buff
428 // buff, size and srcPos are all pointers
429 u32
AuCtx::AuGetInfoToAddStreamData(u32 buff
, u32 size
, u32 srcPos
)
431 // you can not read beyond file size and the buffer size
432 int readsize
= std::min((int)AuBufSize
- AuBufAvailable
, (int)endPos
- readPos
);
434 // we can recharge AuBuf from its beginning
435 if (Memory::IsValidAddress(buff
))
436 Memory::Write_U32(AuBuf
, buff
);
437 if (Memory::IsValidAddress(size
))
438 Memory::Write_U32(readsize
, size
);
439 if (Memory::IsValidAddress(srcPos
))
440 Memory::Write_U32(readPos
, srcPos
);
442 // preset the readPos and available size, they will be notified later in NotifyAddStreamData.
443 askedReadSize
= readsize
;
444 readPos
+= askedReadSize
;
445 AuBufAvailable
+= askedReadSize
;
450 u32
AuCtx::AuResetPlayPositionByFrame(int position
) {
455 u32
AuCtx::AuResetPlayPosition() {
460 void AuCtx::DoState(PointerWrap
&p
) {
461 auto s
= p
.Section("AuContext", 0, 1);
472 p
.Do(SumDecodedSamples
);
475 p
.Do(MaxOutputSample
);
484 if (p
.mode
== p
.MODE_READ
) {
485 decoder
= new SimpleAudio(audioType
);
486 AuBufAvailable
= 0; // reset to read from file at position readPos