Play AT3 files in background audio too.

Fixes 3rd Birthday and PQ2, at least.
This commit is contained in:
Unknown W. Brackets 2014-06-22 09:55:14 -07:00
parent 122fa17d74
commit 47ad97617e
3 changed files with 49 additions and 14 deletions

View File

@ -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 {

View File

@ -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);

View File

@ -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);
}