diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/ASnd.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/ASnd.cpp index bb255dfb5b..ad694e162c 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/ASnd.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/ASnd.cpp @@ -57,13 +57,15 @@ constexpr u32 SAMPLE_RATE = 48000; bool ASndUCode::SwapLeftRight() const { - return m_crc == HASH_DESERT_BUS_2011 || m_crc == HASH_DESERT_BUS_2012; + return m_crc == HASH_2008 || m_crc == HASH_2009 || m_crc == HASH_2011 || m_crc == HASH_2020 || + m_crc == HASH_2020_PAD; } bool ASndUCode::UseNewFlagMasks() const { return m_crc == HASH_2011 || m_crc == HASH_2020 || m_crc == HASH_2020_PAD || - m_crc == HASH_DESERT_BUS_2011 || m_crc == HASH_DESERT_BUS_2012; + m_crc == HASH_DESERT_BUS_2011 || m_crc == HASH_DESERT_BUS_2012 || m_crc == HASH_2024 || + m_crc == HASH_2024_PAD; } ASndUCode::ASndUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc) @@ -398,11 +400,12 @@ void ASndUCode::DoMixing(u32 return_mail) } // Both paths jmpr $AR3, which is an index into sample_selector - auto [new_r, new_l] = (this->*sample_function)(); + auto [new_l, new_r] = (this->*sample_function)(); if (SwapLeftRight()) { - // The Desert Bus versions swapped the left and right input channels so that left - // comes first, and then right. Before, right came before left. + // Most versions of the ASnd ucode have the right channel come before the left channel. + // The Desert Bus and 2024 versions swapped the left and right input channels so that left + // comes first, and then right, matching mp3/ogg files. std::swap(new_r, new_l); } // out_samp: "multiply sample x volume" - left is put in $ax0.h, right is put in $ax1.h diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/ASnd.h b/Source/Core/Core/HW/DSPHLE/UCodes/ASnd.h index 51524ad7ef..159471d416 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/ASnd.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/ASnd.h @@ -53,12 +53,23 @@ public: static constexpr u32 HASH_2020_PAD = 0xbad876ef; // Variant used in Desert Bus v1.04 - this is based off of the code in libogc (as it existed in // 2011, even though that code only became used in 2020), but the left and right channels are - // swapped. Padded to 0x0620 bytes. + // swapped (with the left channel coming before the right channel, which is the the conventional + // behavior). Padded to 0x0620 bytes. static constexpr u32 HASH_DESERT_BUS_2011 = 0xfa9c576f; // Variant used in Desert Bus v1.05 - this is the same as the previous version, except 4 junk // instructions were added to the start, which do not change behavior in any way. Padded to 0x0620 // bytes. static constexpr u32 HASH_DESERT_BUS_2012 = 0x614dd145; + // March 22, 2024 version (0x0606 bytes) - libogc fixed left and right channels being reversed, + // which apparently has been the case from the start but was not obvious in earlier testing + // because of the oggplayer sample using a mono sound file. + // https://github.com/devkitPro/libogc/commit/a0b4b5680944ee7c2ae1b7af63a721623c1a6b69 + static constexpr u32 HASH_2024 = 0x5dbf8bf1; + // March 22, 2024 version (padded to 0x0620 bytes) - same as above, but padded as it's used by + // libogc2 and libogc-rice. + // https://github.com/extremscorner/libogc2/commit/f3fd10635d4b3fbc6ee03cec335eeb2a2237fd56 + // https://github.com/extremscorner/libogc-rice/commit/5ebbf8b96d7433bc2af9e882f730e67a5eb20f00 + static constexpr u32 HASH_2024_PAD = 0x373a950e; private: void DMAInVoiceData(); diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.cpp index 206624313e..7617c0088b 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.cpp @@ -293,6 +293,8 @@ std::unique_ptr UCodeFactory(u32 crc, DSPHLE* dsphle, bool wii) case ASndUCode::HASH_2020_PAD: case ASndUCode::HASH_DESERT_BUS_2011: case ASndUCode::HASH_DESERT_BUS_2012: + case ASndUCode::HASH_2024: + case ASndUCode::HASH_2024_PAD: INFO_LOG_FMT(DSPHLE, "CRC {:08x}: ASnd chosen (Homebrew)", crc); return std::make_unique(dsphle, crc);