diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index caabe6d04b..ec153ba706 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -91,6 +91,7 @@ struct InputBuffer { struct Atrac; int __AtracSetContext(Atrac *atrac); +void _AtracGenarateContext(Atrac *atrac, SceAtracId *context); struct AtracLoopInfo { int cuePointID; @@ -178,9 +179,6 @@ struct Atrac { p.Do(loopEndSample); p.Do(loopNum); - // Is NULL okay for this? - if (p.mode == p.MODE_READ) - decoder_context = 0; p.Do(atracContext); p.DoMarker("Atrac"); @@ -465,6 +463,24 @@ u32 sceAtracGetAtracID(int codecType) return atracID; } +u32 _AtracAddStreamData(int atracID, u8 *buf, u32 bytesToAdd) { + Atrac *atrac = getAtrac(atracID); + if (!atrac) + return 0; + int addbytes = std::min(bytesToAdd, atrac->first.filesize - atrac->first.fileoffset); + memcpy(atrac->data_buf + atrac->first.fileoffset, buf, addbytes); + atrac->first.size += bytesToAdd; + if (atrac->first.size > atrac->first.filesize) + atrac->first.size = atrac->first.filesize; + atrac->first.fileoffset = atrac->first.size; + atrac->first.writableBytes = 0; + if (atrac->atracContext.Valid()) { + // refresh atracContext + _AtracGenarateContext(atrac, atrac->atracContext); + } + return 0; +} + // PSP allow games to add stream data to a temp buf, the buf size is given by "atracBufSize "here. // "first.offset" means how many bytes the temp buf has been written, // and "first.writableBytes" means how many bytes the temp buf is allowed to write @@ -611,6 +627,10 @@ u32 _AtracDecodeData(int atracID, u8* outbuf, u32 *SamplesNum, u32* finish, int *finish = finishFlag; *remains = atrac->getRemainFrames(); } + if (atrac->atracContext.Valid()) { + // refresh atracContext + _AtracGenarateContext(atrac, atrac->atracContext); + } // TODO: Can probably remove this after we validate no wrong ids? } else { memset(outbuf, 0, ATRAC3_MAX_SAMPLES * sizeof(s16) * atrac->atracOutputChannels); @@ -1276,11 +1296,13 @@ int _AtracGetIDByContext(u32 contextAddr) { void _AtracGenarateContext(Atrac *atrac, SceAtracId *context) { context->info.buffer = atrac->first.addr; context->info.bufferByte = atrac->atracBufSize; + context->info.secondBuffer = atrac->second.addr; + context->info.secondBufferByte = atrac->second.size; context->info.codec = atrac->codeType; context->info.loopNum = atrac->loopNum; context->info.loopStart = atrac->loopStartSample > 0 ? atrac->loopStartSample : 0; context->info.loopEnd = atrac->loopEndSample > 0 ? atrac->loopEndSample : 0; - if (atrac->first.size >= atrac->first.fileoffset) { + if (atrac->first.size >= atrac->first.filesize) { // state 2, all data loaded context->info.state = 2; } else if (atrac->loopinfoNum == 0) { @@ -1297,6 +1319,7 @@ void _AtracGenarateContext(Atrac *atrac, SceAtracId *context) { context->info.endSample = atrac->endSample; context->info.dataEnd = atrac->first.filesize; context->info.curOff = atrac->first.size; + context->info.decodePos = atrac->getDecodePosBySample(atrac->currentSample); context->info.streamDataByte = atrac->first.size - atrac->firstSampleoffset; u8* buf = (u8*)context; diff --git a/Core/HLE/sceAtrac.h b/Core/HLE/sceAtrac.h index 71e2b801d9..1775100c64 100644 --- a/Core/HLE/sceAtrac.h +++ b/Core/HLE/sceAtrac.h @@ -66,5 +66,6 @@ typedef struct // provide some decoder interface +u32 _AtracAddStreamData(int atracID, u8 *buf, u32 bytesToAdd); u32 _AtracDecodeData(int atracID, u8* outbuf, u32 *SamplesNum, u32* finish, int *remains); int _AtracGetIDByContext(u32 contextAddr); \ No newline at end of file diff --git a/Core/HLE/sceSas.cpp b/Core/HLE/sceSas.cpp index 798801ea93..19e6fcc6bd 100644 --- a/Core/HLE/sceSas.cpp +++ b/Core/HLE/sceSas.cpp @@ -435,21 +435,25 @@ u32 sceSasSetSteepWave(u32 sasCore, int voice, int unknown) { u32 __sceSasSetVoiceATRAC3(u32 core, int voiceNum, u32 atrac3Context) { INFO_LOG_REPORT(HLE, "__sceSasSetVoiceATRAC3(%08x, %i, %08x)", core, voiceNum, atrac3Context); SasVoice &v = sas->voices[voiceNum]; - u32 prevPcmAddr = v.pcmAddr; v.type = VOICETYPE_ATRAC3; v.loop = false; v.playing = true; v.atrac3.setContext(atrac3Context); + Memory::Write_U32(atrac3Context, core + 56 * voiceNum + 20); return 0; } -u32 __sceSasConcatenateATRAC3(u32 core, int voice, u32 atrac3DataAddr, int atrac3DataLength) { - ERROR_LOG_REPORT(HLE, "UNIMPL __sceSasConcatenateATRAC3(%08x, %i, %08x, %i)", core, voice, atrac3DataAddr, atrac3DataLength); +u32 __sceSasConcatenateATRAC3(u32 core, int voiceNum, u32 atrac3DataAddr, int atrac3DataLength) { + INFO_LOG_REPORT(HLE, "__sceSasConcatenateATRAC3(%08x, %i, %08x, %i)", core, voiceNum, atrac3DataAddr, atrac3DataLength); + SasVoice &v = sas->voices[voiceNum]; + if (Memory::IsValidAddress(atrac3DataAddr)) + v.atrac3.addStreamData(Memory::GetPointer(atrac3DataAddr), atrac3DataLength); return 0; } -u32 __sceSasUnsetATRAC3(u32 core, int voice) { - ERROR_LOG_REPORT(HLE, "UNIMPL __sceSasUnsetATRAC3(%08x, %i)", core, voice); +u32 __sceSasUnsetATRAC3(u32 core, int voiceNum) { + INFO_LOG_REPORT(HLE, "__sceSasUnsetATRAC3(%08x, %i)", core, voiceNum); + Memory::Write_U32(0, core + 56 * voiceNum + 20); return 0; } diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index 88f6181acf..5cfa467412 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -181,6 +181,13 @@ int SasAtrac3::getNextSamples(s16* outbuf, int wantedSamples) { return finish; } +int SasAtrac3::addStreamData(u8* buf, u32 addbytes) { + if (atracID > 0) { + _AtracAddStreamData(atracID, buf, addbytes); + } + return 0; +} + void SasAtrac3::DoState(PointerWrap &p) { p.Do(contextAddr); p.Do(atracID); diff --git a/Core/HW/SasAudio.h b/Core/HW/SasAudio.h index 0026053d87..32bf972762 100644 --- a/Core/HW/SasAudio.h +++ b/Core/HW/SasAudio.h @@ -114,6 +114,7 @@ public: ~SasAtrac3() { if (sampleQueue) delete sampleQueue; } int setContext(u32 context); int getNextSamples(s16* outbuf, int wantedSamples); + int addStreamData(u8* buf, u32 addbytes); void DoState(PointerWrap &p); private: u32 contextAddr;