Skip to content

Commit

Permalink
Merge pull request #20005 from hrydgard/code-lyoko-workaround
Browse files Browse the repository at this point in the history
Atrac3+: Try to work around Code Lyoko issue
  • Loading branch information
hrydgard authored Feb 19, 2025
2 parents 25cc2ba + 4ea7f46 commit bebbdc3
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 7 deletions.
8 changes: 6 additions & 2 deletions Core/HLE/AtracCtx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ void AtracBase::CreateDecoder() {
delete decoder_;
}

// First, init the standalone decoder. Only used for low-level-decode initially, but simple.
// First, init the standalone decoder.
if (track_.codecType == PSP_MODE_AT_3) {
// We don't pull this from the RIFF so that we can support OMA also.
uint8_t extraData[14]{};
Expand Down Expand Up @@ -650,6 +650,10 @@ void Atrac::GetResetBufferInfo(AtracResetBufferInfo *bufferInfo, int sample) {
int Atrac::SetData(u32 buffer, u32 readSize, u32 bufferSize, int outputChannels, int successCode) {
outputChannels_ = outputChannels;

if (outputChannels != track_.channels) {
WARN_LOG(Log::ME, "outputChannels %d doesn't match track_.channels %d", outputChannels, track_.channels);
}

first_.addr = buffer;
first_.size = readSize;

Expand Down Expand Up @@ -696,7 +700,7 @@ int Atrac::SetData(u32 buffer, u32 readSize, u32 bufferSize, int outputChannels,
Memory::Memcpy(dataBuf_, buffer, copybytes, "AtracSetData");
}
CreateDecoder();
return hleLogInfo(Log::ME, successCode, "%s %s audio", codecName, channelName);
return hleLogInfo(Log::ME, successCode, "%s %s (%d channels) audio", codecName, channelName, track_.channels);
}

u32 Atrac::SetSecondBuffer(u32 secondBuffer, u32 secondBufferSize) {
Expand Down
2 changes: 1 addition & 1 deletion Core/HW/Atrac3Standalone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class Atrac3Audio : public AudioDecoder {
}
}
if (inbytes != blockAlign_ && blockAlign_ != 0) {
WARN_LOG(Log::ME, "Atrac3Audio::Decode: Unexpected block align %d (expected %d). %s", inbytes, blockAlign_, at3pCtx_ ? "Atrac3+" : "Atrac3");
WARN_LOG(Log::ME, "Atrac3Audio::Decode: inbytes not matching expected blockalign. Updating blockAlign_. Got %d bytes, expected %d. (%s)", inbytes, blockAlign_, at3pCtx_ ? "Atrac3+" : "Atrac3");
}

blockAlign_ = inbytes;
Expand Down
14 changes: 10 additions & 4 deletions ext/at3_standalone/atrac3plusdec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,14 +323,20 @@ int atrac3p_decode_frame(ATRAC3PContext *ctx, float *out_data[2], int *nb_sample
while (get_bits_left(&ctx->gb) >= 2 &&
(ch_unit_id = get_bits(&ctx->gb, 2)) != CH_UNIT_TERMINATOR) {
if (ch_unit_id == CH_UNIT_EXTENSION) {
avpriv_report_missing_feature("Channel unit extension");
av_log(AV_LOG_ERROR, "Missing atrac3p feature: Channel unit extension");
return AVERROR_PATCHWELCOME;
}
if (ch_block >= ctx->num_channel_blocks ||
ctx->channel_blocks[ch_block] != ch_unit_id) {
av_log(AV_LOG_ERROR,
"Frame data doesn't match channel configuration!");
return AVERROR_INVALIDDATA;
av_log(AV_LOG_WARNING, "Frame data doesn't match channel configuration! ch_block %d >= num_channel_blocks %d", ch_block, ctx->num_channel_blocks);
// This happens in Code Lyoko, see issue #19994.
// The atrac3+ wav header clearly specifies stereo, so we only have one channel block, but here we try to decode a third (and/or fourth) one.
// Maybe the data chunk is just improperly terminated, but it's reported that when ignoring this error previously,
// it didn't sound right. So I'm really not sure what's going on here. Most likely some unknown feature of the Atrac3+ format that we
// failed to parse previously?
//
// return AVERROR_INVALIDDATA; // This soft-locks the game.
return FFMIN(ctx->block_align, indata_size); // We try to stumble along.
}

ctx->ch_units[ch_block].unit_type = ch_unit_id;
Expand Down

0 comments on commit bebbdc3

Please sign in to comment.