From f421453bf9e91e5439b4083e82731cbcd5bde809 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 3 Oct 2014 21:32:07 -0700 Subject: [PATCH] Align samples even after a loop. This corrects the amount of audio after certain loops, but it doesn't seem to output the right data when this happens. Possibly, seeking isn't doing the right thing and resetting state that shouldn't be reset when a loop happens. Not sure... but it was already wrong before, this just reads the right amount of it. --- Core/HLE/sceAtrac.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index f41e3715b3..e56dd5a730 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -683,6 +683,12 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3 // It seems like the PSP aligns the sample position to 0x800...? int offsetSamples = atrac->firstSampleoffset + firstOffsetExtra; int skipSamples = atrac->currentSample == 0 ? offsetSamples : 0; + u32 maxSamples = atrac->endSample - atrac->currentSample; + u32 unalignedSamples = (offsetSamples + atrac->currentSample) % atracSamplesPerFrame; + if (unalignedSamples != 0) { + // We're off alignment, possibly due to a loop. Force it back on. + maxSamples = atracSamplesPerFrame - unalignedSamples; + } #ifdef USE_FFMPEG if (!atrac->failedDecode && (atrac->codecType == PSP_MODE_AT_3 || atrac->codecType == PSP_MODE_AT_3_PLUS) && atrac->pCodecCtx) { @@ -710,7 +716,7 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3 numSamples = atrac->pFrame->nb_samples - skipped; // If we're at the end, clamp to samples we want. It always returns a full chunk. - numSamples = std::min((u32)atrac->endSample - (u32)atrac->currentSample, numSamples); + numSamples = std::min(maxSamples, numSamples); if (skipped > 0 && numSamples == 0) { // Wait for the next one. @@ -749,7 +755,7 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3 if (res != ATDECODE_GOTFRAME && atrac->currentSample < atrac->endSample) { // Never got a frame. We may have dropped a GHA frame or otherwise have a bug. // For now, let's try to provide an extra "frame" if possible so games don't infinite loop. - numSamples = std::min((u32)atrac->endSample - (u32)atrac->currentSample, atracSamplesPerFrame); + numSamples = std::min(maxSamples, atracSamplesPerFrame); u32 outBytes = numSamples * atrac->atracOutputChannels * sizeof(s16); memset(outbuf, 0, outBytes); CBreakPoints::ExecMemCheck(outbufPtr, true, outBytes, currentMIPS->pc); @@ -1012,6 +1018,11 @@ u32 sceAtracGetNextSample(int atracID, u32 outNAddr) { if (atrac->currentSample == 0 && firstSamples != 0) { numSamples = firstSamples; } + u32 unalignedSamples = (skipSamples + atrac->currentSample) % atracSamplesPerFrame; + if (unalignedSamples != 0) { + // We're off alignment, possibly due to a loop. Force it back on. + numSamples = atracSamplesPerFrame - unalignedSamples; + } if (numSamples > atracSamplesPerFrame) numSamples = atracSamplesPerFrame; if (Memory::IsValidAddress(outNAddr))