Audio stuff: Cleanup, delete dead code

This commit is contained in:
Henrik Rydgard 2014-06-22 14:01:23 +02:00
parent 9fc37cac7d
commit 1d0cc3417c
9 changed files with 175 additions and 274 deletions

View File

@ -76,7 +76,7 @@ void __AudioCodecShutdown() {
}
int sceAudiocodecInit(u32 ctxPtr, int codec) {
if (isValidCodec(codec)) {
if (IsValidCodec(codec)) {
// Create audio decoder for given audio codec and push it into AudioList
if (removeDecoder(ctxPtr)) {
WARN_LOG_REPORT(HLE, "sceAudiocodecInit(%08x, %d): replacing existing context", ctxPtr, codec);
@ -97,7 +97,7 @@ int sceAudiocodecDecode(u32 ctxPtr, int codec) {
return -1;
}
if (isValidCodec(codec)){
if (IsValidCodec(codec)){
// Use SimpleAudioDec to decode audio
auto ctx = PSPPointer<AudioCodecContext>::Create(ctxPtr); // On stack, no need to allocate.
int outbytes = 0;
@ -196,8 +196,8 @@ void __sceAudiocodecDoState(PointerWrap &p){
int i = 0;
for (auto it = audioList.begin(), end = audioList.end(); it != end; it++) {
const SimpleAudio *decoder = it->second;
codec_[i] = decoder->audioType;
ctxPtr_[i] = decoder->ctxPtr;
codec_[i] = decoder->GetAudioType();
ctxPtr_[i] = decoder->GetCtxPtr();
i++;
}
p.DoArray(codec_, count);

View File

@ -17,8 +17,7 @@
#pragma once
typedef struct
{
typedef struct {
s32_le unk0;
s32_le unk4;
s32_le err; // 8
@ -56,7 +55,7 @@ typedef struct
u8 unk[20];
} SceAudiocodecCodec;
void __AudioCodecInit();
void __AudioCodecShutdown();
void __AudioCodecInit();
void __AudioCodecShutdown();
void Register_sceAudiocodec();
void __sceAudiocodecDoState(PointerWrap &p);

View File

@ -320,8 +320,8 @@ int sceMp3Init(u32 mp3) {
}
// Parse the Mp3 header
bool isID3 = false;
int header = __ParseMp3Header(ctx, &isID3);
bool hasID3Tag = false;
int header = __ParseMp3Header(ctx, &hasID3Tag);
int layer = (header >> 17) & 0x3;
ctx->Version = ((header >> 19) & 0x3);
ctx->SamplingRate = __CalculateMp3SampleRates((header >> 10) & 0x3, ctx->Version);
@ -331,25 +331,18 @@ int sceMp3Init(u32 mp3) {
INFO_LOG(ME, "sceMp3Init(): channels=%i, samplerate=%iHz, bitrate=%ikbps", ctx->Channels, ctx->SamplingRate, ctx->BitRate);
// Read information from source via ffmpeg and re-create codec context
// This is an automatic method without knowledge in audio file format
// ctx->AuCreateCodecContextFromSource();
// INFO_LOG(ME, "sceMp3Init() ffmpeg: channels=%i, samplerate=%iHz, bitrate=%ikbps", ctx->Channels, ctx->SamplingRate, ctx->BitRate);
// for mp3, if required freq is 48000, reset resampling Frequency to 48000 seems get better sound quality (e.g. Miku Custom BGM)
if (ctx->freq == 48000){
if (ctx->freq == 48000) {
ctx->decoder->setResampleFrequency(ctx->freq);
}
// For mp3 file, if ID3 tag is detected, we must move startPos to 0x400 (stream start position), remove 0x400 bytes of the sourcebuff, and reduce the available buffer size by 0x400
// this is very important for ID3 tag mp3, since our universal audio decoder is for decoding stream part only.
if (isID3){
if (hasID3Tag) {
// if get ID3 tage, we will decode from 0x400
ctx->startPos = 0x400;
ctx->sourcebuff.erase(0, 0x400);
ctx->AuBufAvailable -= 0x400;
}
else{
ctx->EatSourceBuff(0x400);
} else {
// if no ID3 tag, we will decode from the begining of the file
ctx->startPos = 0;
}
@ -369,8 +362,7 @@ int sceMp3GetLoopNum(u32 mp3) {
return ctx->AuGetLoopNum();
}
int sceMp3GetMaxOutputSample(u32 mp3)
{
int sceMp3GetMaxOutputSample(u32 mp3) {
DEBUG_LOG(ME, "sceMp3GetMaxOutputSample(%08x)", mp3);
AuCtx *ctx = getMp3Ctx(mp3);
if (!ctx) {
@ -404,6 +396,7 @@ int sceMp3SetLoopNum(u32 mp3, int loop) {
return ctx->AuSetLoopNum(loop);
}
int sceMp3GetMp3ChannelNum(u32 mp3) {
INFO_LOG(ME, "sceMp3GetMp3ChannelNum(%08X)", mp3);
@ -415,6 +408,7 @@ int sceMp3GetMp3ChannelNum(u32 mp3) {
return ctx->AuGetChannelNum();
}
int sceMp3GetBitRate(u32 mp3) {
INFO_LOG(ME, "sceMp3GetBitRate(%08X)", mp3);
@ -426,6 +420,7 @@ int sceMp3GetBitRate(u32 mp3) {
return ctx->AuGetBitRate();
}
int sceMp3GetSamplingRate(u32 mp3) {
INFO_LOG(ME, "sceMp3GetSamplingRate(%08X)", mp3);
@ -551,7 +546,7 @@ u32 sceMp3LowLevelDecode(u32 mp3, u32 sourceAddr, u32 sourceBytesConsumedAddr, u
}
if (!Memory::IsValidAddress(sourceAddr) || !Memory::IsValidAddress(sourceBytesConsumedAddr) ||
!Memory::IsValidAddress(samplesAddr) || !Memory::IsValidAddress(sampleBytesAddr)){
!Memory::IsValidAddress(samplesAddr) || !Memory::IsValidAddress(sampleBytesAddr)) {
ERROR_LOG(ME, "sceMp3LowLevelDecode(%08x, %08x, %08x, %08x, %08x) : invalid address in args", mp3, sourceAddr, sourceBytesConsumedAddr, samplesAddr, sampleBytesAddr);
return -1;
}
@ -560,7 +555,7 @@ u32 sceMp3LowLevelDecode(u32 mp3, u32 sourceAddr, u32 sourceBytesConsumedAddr, u
auto outbuff = Memory::GetPointer(samplesAddr);
int outpcmbytes = 0;
ctx->decoder->Decode((void*)inbuff,4096,outbuff,&outpcmbytes);
ctx->decoder->Decode((void*)inbuff, 4096, outbuff, &outpcmbytes);
Memory::Write_U32(ctx->decoder->getSourcePos(), sourceBytesConsumedAddr);
Memory::Write_U32(outpcmbytes, sampleBytesAddr);

View File

@ -225,7 +225,8 @@ u32 sceAacInit(u32 id)
ERROR_LOG(ME, "sceAacInit() AAC Invalid id address %08x", id);
return ERROR_AAC_INVALID_ADDRESS;
}
AuCtx *aac = new AuCtx;
AuCtx *aac = new AuCtx();
aac->startPos = Memory::Read_U64(id); // Audio stream start position.
aac->endPos = Memory::Read_U32(id + 8); // Audio stream end position.
aac->AuBuf = Memory::Read_U32(id + 16); // Input AAC data buffer.
@ -258,11 +259,7 @@ u32 sceAacInit(u32 id)
aac->startPos, aac->endPos, aac->AuBuf, aac->AuBufSize, aac->PCMBuf, aac->PCMBufSize, aac->freq);
aac->Channels = 2;
aac->SumDecodedSamples = 0;
aac->MaxOutputSample = aac->PCMBufSize / 4;
aac->LoopNum = -1;
aac->AuBufAvailable = 0;
aac->MaxOutputSample = 0;
aac->readPos = aac->startPos;
aac->audioType = PSP_CODEC_AAC;

View File

@ -93,10 +93,13 @@ static std::list<u32> pmp_ContextList; //list of pmp media contexts
static bool pmp_oldStateLoaded = false; // for dostate
#ifdef USE_FFMPEG
static AVPixelFormat pmp_want_pix_fmt;
extern "C" {
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
static AVPixelFormat pmp_want_pix_fmt;
#endif
struct SceMpegLLI

View File

@ -31,7 +31,7 @@
#include "Core/HW/SimpleAudioDec.h"
class PointerWrap;
struct SimpleAudio;
class SimpleAudio;
#ifdef USE_FFMPEG
struct SwsContext;

View File

@ -34,7 +34,6 @@ extern "C" {
bool SimpleAudio::GetAudioCodecID(int audioType) {
#ifdef USE_FFMPEG
switch (audioType) {
case PSP_CODEC_AAC:
audioCodecId = AV_CODEC_ID_AAC;
@ -154,6 +153,14 @@ SimpleAudio::~SimpleAudio() {
#endif // USE_FFMPEG
}
bool SimpleAudio::IsOK() const {
#ifdef USE_FFMPEG
return codec_ != 0;
#else
return 0;
#endif
}
void SaveAudio(const char filename[], uint8_t *outbuf, int size){
FILE * pf;
pf = fopen(filename, "ab+");
@ -252,7 +259,20 @@ void AudioClose(SimpleAudio **ctx) {
#endif // USE_FFMPEG
}
bool isValidCodec(int codec){
static const char *const codecNames[4] = {
"AT3+", "AT3", "MP3", "AAC",
};
const char *GetCodecName(int codec) {
if (codec >= PSP_CODEC_AT3PLUS && codec <= PSP_CODEC_AAC) {
return codecNames[codec - PSP_CODEC_AT3PLUS];
} else {
return "(unk)";
}
};
bool IsValidCodec(int codec){
if (codec >= PSP_CODEC_AT3PLUS && codec <= PSP_CODEC_AAC) {
return true;
}
@ -262,6 +282,36 @@ bool isValidCodec(int codec){
// sceAu module starts from here
AuCtx::AuCtx() {
decoder = NULL;
startPos = 0;
endPos = 0;
LoopNum = -1;
AuBuf = 0;
AuBufSize = 2048;
PCMBuf = 0;
PCMBufSize = 2048;
AuBufAvailable = 0;
SamplingRate = 44100;
freq = SamplingRate;
BitRate = 0;
Channels = 2;
Version = 0;
SumDecodedSamples = 0;
MaxOutputSample = 0;
askedReadSize = 0;
realReadSize = 0;
audioType = 0;
FrameNum = 0;
};
AuCtx::~AuCtx(){
if (decoder){
AudioClose(&decoder);
decoder = NULL;
}
};
// return output pcm size, <0 error
u32 AuCtx::AuDecode(u32 pcmAddr)
{
@ -367,10 +417,10 @@ u32 AuCtx::AuNotifyAddStreamData(int size)
// buff, size and srcPos are all pointers
u32 AuCtx::AuGetInfoToAddStreamData(u32 buff, u32 size, u32 srcPos)
{
// you can not read beyond file size and the buffersize
// you can not read beyond file size and the buffer size
int readsize = std::min((int)AuBufSize - AuBufAvailable, (int)endPos - readPos);
// we can recharge AuBuf from its begining
// we can recharge AuBuf from its beginning
if (Memory::IsValidAddress(buff))
Memory::Write_U32(AuBuf, buff);
if (Memory::IsValidAddress(size))
@ -386,125 +436,42 @@ u32 AuCtx::AuGetInfoToAddStreamData(u32 buff, u32 size, u32 srcPos)
return 0;
}
u32 AuCtx::AuGetMaxOutputSample()
{
return MaxOutputSample;
}
u32 AuCtx::AuGetSumDecodedSample()
{
return SumDecodedSamples;
}
u32 AuCtx::AuResetPlayPosition()
{
readPos = startPos;
return 0;
}
int AuCtx::AuGetChannelNum(){
return Channels;
}
int AuCtx::AuGetBitRate(){
return BitRate;
}
int AuCtx::AuGetSamplingRate(){
return SamplingRate;
}
u32 AuCtx::AuResetPlayPositionByFrame(int position){
u32 AuCtx::AuResetPlayPositionByFrame(int position) {
readPos = position;
return 0;
}
int AuCtx::AuGetVersion(){
return Version;
u32 AuCtx::AuResetPlayPosition() {
readPos = startPos;
return 0;
}
int AuCtx::AuGetFrameNum(){
return FrameNum;
}
static int _Readbuffer(void *opaque, uint8_t *buf, int buf_size) {
auto ctx = (AuCtx *)opaque;
int toread = std::min((int)ctx->AuBufSize, buf_size);
memcpy(buf, Memory::GetPointer(ctx->AuBuf), toread);
return toread;
}
static void closeAvioCtxandFormatCtx(AVIOContext* pAVIOCtx, AVFormatContext* pFormatCtx){
if (pAVIOCtx && pAVIOCtx->buffer)
av_free(pAVIOCtx->buffer);
if (pAVIOCtx)
av_free(pAVIOCtx);
if (pFormatCtx)
avformat_close_input(&pFormatCtx);
}
// you need at least have initialized AuBuf, AuBufSize and decoder
bool AuCtx::AuCreateCodecContextFromSource(){
u8* tempbuf = (u8*)av_malloc(AuBufSize);
auto pFormatCtx = avformat_alloc_context();
auto pAVIOCtx = avio_alloc_context(tempbuf, AuBufSize, 0, (void*)this, _Readbuffer, NULL, NULL);
pFormatCtx->pb = pAVIOCtx;
int ret;
// Load audio buffer
if ((ret = avformat_open_input((AVFormatContext**)&pFormatCtx, NULL, NULL, NULL)) != 0) {
ERROR_LOG(ME, "avformat_open_input: Cannot open input %d", ret);
closeAvioCtxandFormatCtx(pAVIOCtx,pFormatCtx);
return false;
}
if ((ret = avformat_find_stream_info(pFormatCtx, NULL)) < 0) {
ERROR_LOG(ME, "avformat_find_stream_info: Cannot find stream information %d", ret);
closeAvioCtxandFormatCtx(pAVIOCtx, pFormatCtx);
return false;
}
// reset decoder context
if (decoder->codecCtx_){
avcodec_close(decoder->codecCtx_);
av_free(decoder->codecCtx_);
}
decoder->codecCtx_ = pFormatCtx->streams[ret]->codec;
if (decoder->codec_){
decoder->codec_ = 0;
}
// select the audio stream
ret = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_AUDIO, -1, -1, &decoder->codec_, 0);
if (ret < 0) {
if (ret == AVERROR_DECODER_NOT_FOUND) {
ERROR_LOG(HLE, "av_find_best_stream: No appropriate decoder found");
}
else {
ERROR_LOG(HLE, "av_find_best_stream: Cannot find an audio stream in the input file %d", ret);
}
closeAvioCtxandFormatCtx(pAVIOCtx, pFormatCtx);
return false;
}
// close and free AVIO and AVFormat
// closeAvioCtxandFormatCtx(pAVIOCtx, pFormatCtx);
// open codec
if ((ret = avcodec_open2(decoder->codecCtx_, decoder->codec_, NULL)) < 0) {
avcodec_close(decoder->codecCtx_);
av_free(decoder->codecCtx_);
decoder->codecCtx_ = 0;
decoder->codec_ = 0;
ERROR_LOG(ME, "avcodec_open2: Cannot open audio decoder %d", ret);
return false;
}
// set audio informations
SamplingRate = decoder->codecCtx_->sample_rate;
Channels = decoder->codecCtx_->channels;
BitRate = decoder->codecCtx_->bit_rate/1000;
freq = SamplingRate;
return true;
void AuCtx::DoState(PointerWrap &p) {
auto s = p.Section("AuContext", 0, 1);
if (!s)
return;
p.Do(startPos);
p.Do(endPos);
p.Do(AuBuf);
p.Do(AuBufSize);
p.Do(PCMBuf);
p.Do(PCMBufSize);
p.Do(freq);
p.Do(SumDecodedSamples);
p.Do(LoopNum);
p.Do(Channels);
p.Do(MaxOutputSample);
p.Do(readPos);
p.Do(audioType);
p.Do(BitRate);
p.Do(SamplingRate);
p.Do(askedReadSize);
p.Do(realReadSize);
p.Do(FrameNum);
if (p.mode == p.MODE_READ) {
decoder = new SimpleAudio(audioType);
AuBufAvailable = 0; // reset to read from file at position readPos
}
}

View File

@ -23,19 +23,14 @@
#include "Core/HW/MediaEngine.h"
#include "Core/HLE/sceAudio.h"
#ifdef USE_FFMPEG
struct AVFrame;
struct AVCodec;
struct AVCodecContext;
struct SwrContext;
enum AVCodecID;
extern "C" {
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>
#include <libavutil/samplefmt.h>
}
#endif // USE_FFMPEG
// Wraps FFMPEG in a nice interface that's drop-in compatible with
// the old one. Decodes packet by packet - does NOT demux. That's done by
// MpegDemux. Only decodes Atrac3+, not regular Atrac3.
// Wraps FFMPEG for audio decoding in a nice interface.
// Decodes packet by packet - does NOT demux.
// Based on http://ffmpeg.org/doxygen/trunk/doc_2examples_2decoding_encoding_8c-example.html#_a13
@ -44,18 +39,34 @@ extern "C" {
// However, it will be maintained as a part of FFMPEG so that's the way we'll go
// for simplicity and sanity.
struct SimpleAudio {
// audioType
enum {
PSP_CODEC_AT3PLUS = 0x00001000,
PSP_CODEC_AT3 = 0x00001001,
PSP_CODEC_MP3 = 0x00001002,
PSP_CODEC_AAC = 0x00001003,
};
class SimpleAudio {
public:
SimpleAudio(int audioType);
SimpleAudio(u32 ctxPtr, int audioType);
~SimpleAudio();
bool Decode(void* inbuf, int inbytes, uint8_t *outbuf, int *outbytes);
bool IsOK() const { return codec_ != 0; }
bool IsOK() const;
int getOutSamples();
int getSourcePos();
bool ResetCodecCtx(int channels, int samplerate);
void setResampleFrequency(int freq);
bool GetAudioCodecID(int audioType); // Get audioCodecId from audioType
// These two are only here because of save states.
int GetAudioType() const { return audioType; }
u32 GetCtxPtr() const { return ctxPtr; }
private:
void Init();
u32 ctxPtr;
int audioType;
@ -69,41 +80,45 @@ public:
AVCodecContext *codecCtx_;
SwrContext *swrCtx_;
AVCodecID audioCodecId; // AV_CODEC_ID_XXX
bool GetAudioCodecID(int audioType); // Get audioCodecId from audioType
#endif // USE_FFMPEG
private:
void Init();
};
// audioType
enum {
PSP_CODEC_AT3PLUS = 0x00001000,
PSP_CODEC_AT3 = 0x00001001,
PSP_CODEC_MP3 = 0x00001002,
PSP_CODEC_AAC = 0x00001003,
};
static const char *const codecNames[4] = {
"AT3+", "AT3", "MP3", "AAC",
};
void AudioClose(SimpleAudio **ctx);
static inline const char *GetCodecName(int codec) {
if (codec >= PSP_CODEC_AT3PLUS && codec <= PSP_CODEC_AAC) {
return codecNames[codec - PSP_CODEC_AT3PLUS];
}
else {
return "(unk)";
}
};
bool isValidCodec(int codec);
const char *GetCodecName(int codec); // audioType
bool IsValidCodec(int codec);
class AuCtx{
class AuCtx {
public:
// Au source informations
AuCtx();
~AuCtx();
u32 AuDecode(u32 pcmAddr);
u32 AuExit();
u32 AuNotifyAddStreamData(int size);
int AuCheckStreamDataNeeded();
u32 AuResetPlayPosition();
u32 AuResetPlayPositionByFrame(int position);
u32 AuSetLoopNum(int loop);
u32 AuGetLoopNum();
u32 AuGetInfoToAddStreamData(u32 buff, u32 size, u32 srcPos);
u32 AuGetMaxOutputSample() const { return MaxOutputSample; }
u32 AuGetSumDecodedSample() const { return SumDecodedSamples; }
int AuGetChannelNum() const { return Channels; }
int AuGetBitRate() const { return BitRate; }
int AuGetSamplingRate() const { return SamplingRate; }
int AuGetVersion() const { return Version; }
int AuGetFrameNum() const { return FrameNum; }
void DoState(PointerWrap &p);
void EatSourceBuff(int amount) {
sourcebuff.erase(0, amount);
AuBufAvailable -= amount;
}
// Au source information. Written to from for example sceAacInit so public for now.
u64 startPos;
u64 endPos;
u32 AuBuf;
@ -116,12 +131,12 @@ public:
int Channels;
int Version;
// audio settings
// State variables. These should be relatively easy to move into private.
u32 SumDecodedSamples;
int LoopNum;
u32 MaxOutputSample;
int FrameNum; // number of decoded frame
// Au decoder
SimpleAudio *decoder;
@ -133,84 +148,9 @@ public:
int readPos; // read position in audio source file
int askedReadSize; // the size of data requied to be read from file by the game
int realReadSize; // the really read size from file
private:
std::string sourcebuff; // source buffer
AuCtx(){
decoder = NULL;
startPos = 0;
endPos = 0;
LoopNum = -1;
AuBuf = 0;
AuBufSize = 2048;
PCMBuf = 0;
PCMBufSize = 2048;
AuBufAvailable = 0;
SamplingRate = 44100;
freq = SamplingRate;
BitRate = 0;
Channels = 2;
Version = 0;
SumDecodedSamples = 0;
MaxOutputSample = 0;
askedReadSize = 0;
realReadSize = 0;
audioType = 0;
FrameNum = 0;
};
~AuCtx(){
if (decoder){
AudioClose(&decoder);
decoder = NULL;
}
};
u32 AuExit();
u32 AuDecode(u32 pcmAddr);
u32 AuGetLoopNum();
u32 AuSetLoopNum(int loop);
int AuCheckStreamDataNeeded();
u32 AuNotifyAddStreamData(int size);
u32 AuGetInfoToAddStreamData(u32 buff, u32 size, u32 srcPos);
u32 AuGetMaxOutputSample();
u32 AuGetSumDecodedSample();
u32 AuResetPlayPosition();
int AuGetChannelNum();
int AuGetBitRate();
int AuGetSamplingRate();
u32 AuResetPlayPositionByFrame(int position);
int AuGetVersion();
int AuGetFrameNum();
bool AuCreateCodecContextFromSource();
void DoState(PointerWrap &p) {
auto s = p.Section("AuContext", 0, 1);
if (!s)
return;
p.Do(startPos);
p.Do(endPos);
p.Do(AuBuf);
p.Do(AuBufSize);
p.Do(PCMBuf);
p.Do(PCMBufSize);
p.Do(freq);
p.Do(SumDecodedSamples);
p.Do(LoopNum);
p.Do(Channels);
p.Do(MaxOutputSample);
p.Do(readPos);
p.Do(audioType);
p.Do(BitRate);
p.Do(SamplingRate);
p.Do(askedReadSize);
p.Do(realReadSize);
p.Do(FrameNum);
if (p.mode == p.MODE_READ){
decoder = new SimpleAudio(audioType);
AuBufAvailable = 0; // reset to read from file at position readPos
}
};
};

View File

@ -105,7 +105,7 @@ bool IsAudioInitialised() {
}
void Audio_Init() {
if(mixer == NULL) {
if (mixer == NULL) {
mixer = new PSPMixer();
host->InitSound(mixer);
}