diff --git a/Core/HLE/AtracCtx.cpp b/Core/HLE/AtracCtx.cpp index b9849baa32..4a9c8a0e2d 100644 --- a/Core/HLE/AtracCtx.cpp +++ b/Core/HLE/AtracCtx.cpp @@ -959,13 +959,7 @@ u32 Atrac::DecodeData(u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, i if (off < first_.size) { uint8_t *indata = BufferStart() + off; int bytesConsumed = 0; - int outSamples = 0; - if (!decoder_->Decode(indata, track_.bytesPerFrame, &bytesConsumed, outputChannels_, (int16_t *)outbuf, &outSamples)) { - // Decode failed. - *SamplesNum = 0; - *finish = 1; - return ATRAC_ERROR_ALL_DATA_DECODED; - } + int outSamples = track_.SamplesPerFrame(); int outBytes = outSamples * outputChannels_ * sizeof(int16_t); gotFrame = true; @@ -978,6 +972,14 @@ u32 Atrac::DecodeData(u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, i // If we're at the end, clamp to samples we want. It always returns a full chunk. numSamples = std::min(maxSamples, numSamples); + outSamples = numSamples; + if (!decoder_->Decode(indata, track_.bytesPerFrame, &bytesConsumed, outputChannels_, (int16_t *)outbuf, &outSamples)) { + // Decode failed. + *SamplesNum = 0; + *finish = 1; + return ATRAC_ERROR_ALL_DATA_DECODED; + } + if (packetAddr != 0 && MemBlockInfoDetailed()) { char tagData[128]; size_t tagSize = FormatMemWriteTagAt(tagData, sizeof(tagData), "AtracDecode/", packetAddr, track_.bytesPerFrame); diff --git a/Core/HW/Atrac3Standalone.cpp b/Core/HW/Atrac3Standalone.cpp index 6fb5ffc540..b284be90bd 100644 --- a/Core/HW/Atrac3Standalone.cpp +++ b/Core/HW/Atrac3Standalone.cpp @@ -82,6 +82,10 @@ public: *inbytesConsumed = result; } if (outSamples) { + // Allow capping the output samples by setting *outSamples to non-zero. + if (*outSamples != 0) { + nb_samples = std::min(*outSamples, nb_samples); + } *outSamples = nb_samples; } if (nb_samples > 0) { diff --git a/Core/HW/SimpleAudioDec.h b/Core/HW/SimpleAudioDec.h index 34bf3b9342..40d724c565 100644 --- a/Core/HW/SimpleAudioDec.h +++ b/Core/HW/SimpleAudioDec.h @@ -38,6 +38,8 @@ public: // inbytesConsumed can include skipping metadata. // outSamples is in stereo samples. So you have to multiply by 4 for 16-bit stereo audio to get bytes. + // For Atrac3, if *outSamples != 0, it'll cap the number of samples to output. In this case, its value can only shrink. + // TODO: Implement that in the other decoders too, if needed. virtual bool Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, int outputChannels, int16_t *outbuf, int *outSamples) = 0; virtual bool IsOK() const = 0;