mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
add atrac3plus support for sceAtrac
This commit is contained in:
parent
9b0c22f87d
commit
34b4cd29a2
1 changed files with 93 additions and 11 deletions
|
@ -74,6 +74,10 @@ extern "C" {
|
|||
}
|
||||
#endif // USE_FFMPEG
|
||||
|
||||
#ifdef _USE_DSHOW_
|
||||
#include "../HW/audioPlayer.h"
|
||||
#endif // _USE_DSHOW_
|
||||
|
||||
struct InputBuffer {
|
||||
u32 addr;
|
||||
u32 size;
|
||||
|
@ -113,11 +117,21 @@ struct Atrac {
|
|||
}
|
||||
|
||||
~Atrac() {
|
||||
CleanStuff();
|
||||
}
|
||||
|
||||
void CleanStuff() {
|
||||
#ifdef USE_FFMPEG
|
||||
ReleaseFFMPEGContext();
|
||||
#endif // USE_FFMPEG
|
||||
|
||||
#ifdef _USE_DSHOW_
|
||||
deleteAtrac3Audio(atracID);
|
||||
#endif // _USE_DSHOW_
|
||||
|
||||
if (data_buf)
|
||||
delete [] data_buf;
|
||||
data_buf = 0;
|
||||
}
|
||||
|
||||
void DoState(PointerWrap &p) {
|
||||
|
@ -128,6 +142,11 @@ struct Atrac {
|
|||
p.Do(first);
|
||||
p.Do(atracBufSize);
|
||||
p.Do(codeType);
|
||||
|
||||
p.Do(currentSample);
|
||||
p.Do(endSample);
|
||||
p.Do(firstSampleoffset);
|
||||
|
||||
u32 has_data_buf = data_buf != NULL;
|
||||
p.Do(has_data_buf);
|
||||
if (has_data_buf) {
|
||||
|
@ -147,10 +166,6 @@ struct Atrac {
|
|||
p.Do(atracBitrate);
|
||||
p.Do(atracBytesPerFrame);
|
||||
|
||||
p.Do(currentSample);
|
||||
p.Do(endSample);
|
||||
p.Do(firstSampleoffset);
|
||||
|
||||
p.Do(loopinfo);
|
||||
p.Do(loopinfoNum);
|
||||
|
||||
|
@ -261,6 +276,11 @@ void __AtracInit() {
|
|||
avcodec_register_all();
|
||||
av_register_all();
|
||||
#endif // USE_FFMPEG
|
||||
|
||||
#ifdef _USE_DSHOW_
|
||||
initaudioEngine();
|
||||
#endif //_USE_DSHOW_
|
||||
|
||||
}
|
||||
|
||||
void __AtracDoState(PointerWrap &p) {
|
||||
|
@ -275,6 +295,9 @@ void __AtracShutdown() {
|
|||
delete it->second;
|
||||
}
|
||||
atracMap.clear();
|
||||
#ifdef _USE_DSHOW_
|
||||
shutdownEngine();
|
||||
#endif // _USE_DSHOW_
|
||||
}
|
||||
|
||||
Atrac *getAtrac(int atracID) {
|
||||
|
@ -454,6 +477,13 @@ u32 sceAtracAddStreamData(int atracID, u32 bytesToAdd)
|
|||
int addbytes = std::min(bytesToAdd, atrac->first.filesize - atrac->first.fileoffset);
|
||||
Memory::Memcpy(atrac->data_buf + atrac->first.fileoffset, atrac->first.addr + atrac->first.offset, addbytes);
|
||||
}
|
||||
#ifdef _USE_DSHOW_
|
||||
audioEngine *engine = getaudioEngineByID(atracID);
|
||||
if (engine && bytesToAdd > 0) {
|
||||
engine->addStreamData(atrac->first.fileoffset - atrac->firstSampleoffset + 96, Memory::GetPointer(atrac->first.addr + atrac->first.offset),
|
||||
bytesToAdd, atrac->currentSample);
|
||||
}
|
||||
#endif
|
||||
atrac->first.size += bytesToAdd;
|
||||
if (atrac->first.size > atrac->first.filesize)
|
||||
atrac->first.size = atrac->first.filesize;
|
||||
|
@ -469,6 +499,10 @@ u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32 finishF
|
|||
DEBUG_LOG(HLE, "sceAtracDecodeData(%i, %08x, %08x, %08x, %08x)", atracID, outAddr, numSamplesAddr, finishFlagAddr, remainAddr);
|
||||
Atrac *atrac = getAtrac(atracID);
|
||||
|
||||
#ifdef _USE_DSHOW_
|
||||
audioEngine *engine = getaudioEngineByID(atracID);
|
||||
#endif // _USE_DSHOW_
|
||||
|
||||
u32 ret = 0;
|
||||
if (atrac != NULL) {
|
||||
// We already passed the end - return an error (many games check for this.)
|
||||
|
@ -518,6 +552,24 @@ u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32 finishF
|
|||
|
||||
} else
|
||||
#endif // USE_FFMPEG
|
||||
#ifdef _USE_DSHOW_
|
||||
if (engine) {
|
||||
static s16 buf[ATRAC_MAX_SAMPLES * 2];
|
||||
int gotsize = engine->getNextSamples((u8*)buf, ATRAC_MAX_SAMPLES * sizeof(s16) * atrac->atracChannels);
|
||||
numSamples = gotsize / sizeof(s16) / atrac->atracChannels;
|
||||
s16* in = buf;
|
||||
s16* out = (s16*)Memory::GetPointer(outAddr);
|
||||
for (int i = 0; i < numSamples; i++) {
|
||||
s16 sampleL = *in++;
|
||||
s16 sampleR = sampleL;
|
||||
if (atrac->atracChannels == 2)
|
||||
sampleR = *in++;
|
||||
*out++ = sampleL;
|
||||
if (atrac->atracOutputChannels == 2)
|
||||
*out++ = sampleR;
|
||||
}
|
||||
} else
|
||||
#endif // _USE_DSHOW
|
||||
{
|
||||
numSamples = atrac->endSample - atrac->currentSample;
|
||||
if (atrac->currentSample >= atrac->endSample) {
|
||||
|
@ -540,6 +592,10 @@ u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32 finishF
|
|||
int finishFlag = 0;
|
||||
if (atrac->loopNum != 0 && (atrac->currentSample >= atrac->loopEndSample || numSamples == 0)) {
|
||||
atrac->currentSample = atrac->loopStartSample;
|
||||
#ifdef _USE_DSHOW_
|
||||
if (engine)
|
||||
engine->setPlaySample(atrac->currentSample);
|
||||
#endif // _USE_DSHOW
|
||||
if (atrac->loopNum > 0)
|
||||
atrac->loopNum --;
|
||||
} else if (atrac->currentSample >= atrac->endSample || numSamples == 0)
|
||||
|
@ -789,6 +845,13 @@ u32 sceAtracResetPlayPosition(int atracID, int sample, int bytesWrittenFirstBuf,
|
|||
//return -1;
|
||||
} else {
|
||||
atrac->currentSample = sample;
|
||||
#ifdef _USE_DSHOW_
|
||||
audioEngine *engine = getaudioEngineByID(atracID);
|
||||
if (engine != NULL)
|
||||
{
|
||||
engine->setPlaySample(sample);
|
||||
}
|
||||
#endif // _USE_DSHOW_
|
||||
#ifdef USE_FFMPEG
|
||||
if (atrac->codeType == PSP_MODE_AT_3 && atrac->pCodecCtx) {
|
||||
atrac->SeekToSample(sample);
|
||||
|
@ -834,6 +897,17 @@ int64_t _AtracSeekbuffer(void *opaque, int64_t offset, int whence)
|
|||
|
||||
int __AtracSetContext(Atrac *atrac, u32 buffer, u32 bufferSize)
|
||||
{
|
||||
#ifdef _USE_DSHOW_
|
||||
if (atrac->codeType == PSP_MODE_AT_3_PLUS && atrac->atracChannels != 1) {
|
||||
addAtrac3Audio(atrac->data_buf, atrac->first.size, atrac->atracID);
|
||||
if (atrac->currentSample != 0) {
|
||||
audioEngine *engine = getaudioEngineByID(atrac->atracID);
|
||||
if (engine)
|
||||
engine->setPlaySample(atrac->currentSample);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // _USE_DSHOW_
|
||||
#ifdef USE_FFMPEG
|
||||
u8* tempbuf = (u8*)av_malloc(atrac->atracBufSize);
|
||||
|
||||
|
@ -913,22 +987,30 @@ int _AtracSetData(Atrac *atrac, u32 buffer, u32 bufferSize)
|
|||
atrac->first.writableBytes = (u32)std::max((int)bufferSize - (int)atrac->first.size, 0);
|
||||
atrac->first.offset = atrac->first.size;
|
||||
|
||||
// some games may reuse an atracID for playing sound
|
||||
atrac->CleanStuff();
|
||||
|
||||
#ifdef USE_FFMPEG
|
||||
if (atrac->codeType == PSP_MODE_AT_3) {
|
||||
WARN_LOG(HLE, "This is an atrac3 audio");
|
||||
|
||||
// some games may reuse an atracID for playing sound
|
||||
atrac->ReleaseFFMPEGContext();
|
||||
|
||||
if (atrac->data_buf)
|
||||
delete [] atrac->data_buf;
|
||||
|
||||
atrac->data_buf = new u8[atrac->first.filesize];
|
||||
Memory::Memcpy(atrac->data_buf, buffer, std::min(bufferSize, atrac->first.filesize));
|
||||
|
||||
return __AtracSetContext(atrac, buffer, bufferSize);
|
||||
} else if (atrac->codeType == PSP_MODE_AT_3_PLUS)
|
||||
} else if (atrac->codeType == PSP_MODE_AT_3_PLUS) {
|
||||
WARN_LOG(HLE, "This is an atrac3+ audio");
|
||||
#ifdef _USE_DSHOW_
|
||||
if (atrac->atracChannels == 1) {
|
||||
WARN_LOG(HLE, "Unsupported mono atrac3+ audio!");
|
||||
} else {
|
||||
atrac->data_buf = new u8[atrac->first.filesize];
|
||||
Memory::Memcpy(atrac->data_buf, buffer, std::min(bufferSize, atrac->first.filesize));
|
||||
|
||||
return __AtracSetContext(atrac, buffer, bufferSize);
|
||||
}
|
||||
#endif // _USE_DSHOW
|
||||
}
|
||||
#endif // USE_FFMPEG
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue