From 47ad97617eb2f0fabb33bbe3b4d8f1eaf901bdf5 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 22 Jun 2014 09:55:14 -0700 Subject: [PATCH] Play AT3 files in background audio too. Fixes 3rd Birthday and PQ2, at least. --- Core/HW/SimpleAudioDec.cpp | 45 +++++++++++++++++++++++++++----------- Core/HW/SimpleAudioDec.h | 7 ++++++ UI/BackgroundAudio.cpp | 11 +++++++++- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/Core/HW/SimpleAudioDec.cpp b/Core/HW/SimpleAudioDec.cpp index 158ba8ce44..507ae4e834 100644 --- a/Core/HW/SimpleAudioDec.cpp +++ b/Core/HW/SimpleAudioDec.cpp @@ -61,7 +61,7 @@ bool SimpleAudio::GetAudioCodecID(int audioType) { } SimpleAudio::SimpleAudio(int audioType, int sample_rate, int channels) -: ctxPtr(0xFFFFFFFF), audioType(audioType), sample_rate_(sample_rate), channels_(channels), codec_(0), codecCtx_(0), swrCtx_(0), outSamples(0), srcPos(0), wanted_resample_freq(44100) { +: ctxPtr(0xFFFFFFFF), audioType(audioType), sample_rate_(sample_rate), channels_(channels), codec_(0), codecCtx_(0), swrCtx_(0), outSamples(0), srcPos(0), wanted_resample_freq(44100), extradata_(0) { Init(); } @@ -94,16 +94,21 @@ void SimpleAudio::Init() { codecCtx_->channels = channels_; codecCtx_->channel_layout = channels_ == 2 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; codecCtx_->sample_rate = sample_rate_; - // Open codec + OpenCodec(); +#endif // USE_FFMPEG +} + +bool SimpleAudio::OpenCodec() { +#ifdef USE_FFMPEG AVDictionary *opts = 0; + bool result = true; if (avcodec_open2(codecCtx_, codec_, &opts) < 0) { ERROR_LOG(ME, "Failed to open codec"); - av_dict_free(&opts); - return; + result = false; } - av_dict_free(&opts); #endif // USE_FFMPEG + return result; } bool SimpleAudio::ResetCodecCtx(int channels, int samplerate){ @@ -122,19 +127,31 @@ bool SimpleAudio::ResetCodecCtx(int channels, int samplerate){ codecCtx_->channels = channels; codecCtx_->channel_layout = channels==2?AV_CH_LAYOUT_STEREO:AV_CH_LAYOUT_MONO; codecCtx_->sample_rate = samplerate; - // Open codec - AVDictionary *opts = 0; - if (avcodec_open2(codecCtx_, codec_, &opts) < 0) { - ERROR_LOG(ME, "Failed to open codec"); - av_dict_free(&opts); - return false; - } - av_dict_free(&opts); + OpenCodec(); return true; #endif return false; } +void SimpleAudio::SetExtraData(u8 *data, int size, int wav_bytes_per_packet) { + delete [] extradata_; + extradata_ = 0; + + if (data != 0) { + extradata_ = new u8[size]; + memcpy(extradata_, data, size); + } + +#ifdef USE_FFMPEG + if (codecCtx_) { + codecCtx_->extradata = extradata_; + codecCtx_->extradata_size = size; + codecCtx_->block_align = wav_bytes_per_packet; + OpenCodec(); + } +#endif +} + SimpleAudio::~SimpleAudio() { #ifdef USE_FFMPEG if (swrCtx_) @@ -147,6 +164,8 @@ SimpleAudio::~SimpleAudio() { codecCtx_ = 0; codec_ = 0; #endif // USE_FFMPEG + delete [] extradata_; + extradata_ = 0; } bool SimpleAudio::IsOK() const { diff --git a/Core/HW/SimpleAudioDec.h b/Core/HW/SimpleAudioDec.h index 49ecd72cbd..e8f2fb5fe3 100644 --- a/Core/HW/SimpleAudioDec.h +++ b/Core/HW/SimpleAudioDec.h @@ -54,6 +54,9 @@ public: bool ResetCodecCtx(int channels, int samplerate); bool GetAudioCodecID(int audioType); // Get audioCodecId from audioType + // Not save stated, only used by UI. Used for ATRAC3 (non+) files. + void SetExtraData(u8 *data, int size, int wav_bytes_per_packet); + // These two are only here because of save states. int GetAudioType() const { return audioType; } void SetResampleFrequency(int freq) { wanted_resample_freq = freq; } @@ -64,6 +67,7 @@ public: private: void Init(); + bool OpenCodec(); u32 ctxPtr; int audioType; @@ -78,6 +82,9 @@ private: AVCodecContext *codecCtx_; SwrContext *swrCtx_; int audioCodecId; // AV_CODEC_ID_XXX + + // Not savestated, only used by UI. + u8 *extradata_; }; void AudioClose(SimpleAudio **ctx); diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 09cc0e2894..7f39edebe5 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -27,6 +27,7 @@ public: buffer_ = new short[32 * 1024]; int codec = PSP_CODEC_AT3PLUS; + u8 at3_extradata[16]; int num_channels, sample_rate, numFrames, samplesPerSec, avgBytesPerSec, Nothing; if (file_.descend('RIFF')) { @@ -39,10 +40,10 @@ public: codec = PSP_CODEC_AT3PLUS; break; case 0x270: - // Dunno? 3rd Birthday has this. Doesn't seem to work though. codec = PSP_CODEC_AT3; break; default: + ERROR_LOG(HLE, "Unexpected SND0.AT3 format %04x", format); return; } @@ -54,6 +55,11 @@ public: temp = file_.readInt(); raw_bytes_per_frame_ = temp & 0xFFFF; Nothing = temp >> 16; + + if (codec == PSP_CODEC_AT3) { + // The first two bytes are actually not useful part of the extradata. + file_.readData(at3_extradata, 16); + } file_.ascend(); // ILOG("got fmt data: %i", samplesPerSec); } else { @@ -89,6 +95,9 @@ public: } sample_rate = samplesPerSec; decoder_ = new SimpleAudio(codec, sample_rate, num_channels); + if (codec == PSP_CODEC_AT3) { + decoder_->SetExtraData(&at3_extradata[2], 14, raw_bytes_per_frame_); + } ILOG("read ATRAC, frames: %i, rate %i", numFrames, sample_rate); }