diff options
| author | duck912 <350528965+Duck912@users.noreply.github.com> | 2026-10-31 01:45:56 -0400 |
|---|---|---|
| committer | Duck912 <350528965+Duck912@users.noreply.github.com> | 2026-11-01 14:58:49 -0500 |
| commit | e6c0a42d11f15e623c399d14454e5ae8e1a72942 (patch) | |
| tree | 1a27d42db74ef26cf1efaea2a92538874a020c87 /src | |
| parent | 681d50cd9cadf0b2205311dc20c84a9e774898d9 (diff) | |
audio_core: accept the Switch 2 audio renderer revision
Switch 2 titles send revision 16 with the 'REv' magic and use the
voice crossfade fields. Without them GetWorkBufferSize failed with
0xc0299 and Fire Emblem: Fortune's Weave aborted (2153-1537). Ported
from the Eden NS2 tree, keeping Eglantine's lenient revision compare.
Assisted-by: Claude Opus 5.5 (debugging, porting and drafting)
Signed-off-by: duck912 <350528965+Duck912@users.noreply.github.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio_core/common/feature_support.h | 28 | ||||
| -rw-r--r-- | src/audio_core/renderer/behavior/behavior_info.cpp | 8 | ||||
| -rw-r--r-- | src/audio_core/renderer/behavior/behavior_info.h | 1 | ||||
| -rw-r--r-- | src/audio_core/renderer/behavior/info_updater.cpp | 9 |
4 files changed, 35 insertions, 11 deletions
diff --git a/src/audio_core/common/feature_support.h b/src/audio_core/common/feature_support.h index 4585be45ef..d6571c0661 100644 --- a/src/audio_core/common/feature_support.h +++ b/src/audio_core/common/feature_support.h @@ -17,6 +17,16 @@ namespace AudioCore { constexpr u32 CurrentRevision = 15; +constexpr u32 NativeCurrentRevision = 16; + +constexpr bool IsNativeRevision(u32 revision) { + return (revision & 0xffffff) == Common::MakeMagic('R', 'E', 'v', '\0'); +} + +constexpr u32 EncodeRevision(u32 revision, bool native) { + return Common::MakeMagic('R', 'E', native ? 'v' : 'V', + static_cast<char>('0' + revision)); +} enum class SupportTags { CommandProcessingTimeEstimatorVersion4, @@ -57,12 +67,15 @@ enum class SupportTags { }; constexpr u32 GetRevisionNum(u32 user_revision) { - if (user_revision >= 0x100) { - user_revision -= Common::MakeMagic('R', 'E', 'V', '0'); - user_revision >>= 24; + if (user_revision < 0x100) { + return user_revision; } - - return user_revision; + if (!IsNativeRevision(user_revision) && + (user_revision & 0xffffff) != Common::MakeMagic('R', 'E', 'V', '\0')) { + return ~u32{0}; + } + const u32 encoded = user_revision >> 24; + return encoded >= '0' ? encoded - '0' : ~u32{0}; }; constexpr bool CheckFeatureSupported(SupportTags tag, u32 user_revision) { @@ -108,11 +121,12 @@ constexpr bool CheckFeatureSupported(SupportTags tag, u32 user_revision) { return false; } user_revision = GetRevisionNum(user_revision); - return (*feature).second <= user_revision; + return user_revision != ~u32{0} && (*feature).second <= user_revision; } constexpr bool CheckValidRevision(u32 user_revision) { - return GetRevisionNum(user_revision) <= CurrentRevision; + return GetRevisionNum(user_revision) <= + (IsNativeRevision(user_revision) ? NativeCurrentRevision : CurrentRevision); }; } // namespace AudioCore diff --git a/src/audio_core/renderer/behavior/behavior_info.cpp b/src/audio_core/renderer/behavior/behavior_info.cpp index 63b80c503a..983cfd5b85 100644 --- a/src/audio_core/renderer/behavior/behavior_info.cpp +++ b/src/audio_core/renderer/behavior/behavior_info.cpp @@ -16,8 +16,7 @@ u32 BehaviorInfo::GetProcessRevisionNum() const { } u32 BehaviorInfo::GetProcessRevision() const { - return Common::MakeMagic('R', 'E', 'V', - static_cast<char>(static_cast<u8>('0') + process_revision)); + return EncodeRevision(process_revision, native_platform); } u32 BehaviorInfo::GetUserRevisionNum() const { @@ -25,11 +24,12 @@ u32 BehaviorInfo::GetUserRevisionNum() const { } u32 BehaviorInfo::GetUserRevision() const { - return Common::MakeMagic('R', 'E', 'V', - static_cast<char>(static_cast<u8>('0') + user_revision)); + return EncodeRevision(user_revision, native_platform); } void BehaviorInfo::SetUserLibRevision(const u32 user_revision_) { + native_platform = IsNativeRevision(user_revision_); + process_revision = native_platform ? NativeCurrentRevision : CurrentRevision; user_revision = GetRevisionNum(user_revision_); } diff --git a/src/audio_core/renderer/behavior/behavior_info.h b/src/audio_core/renderer/behavior/behavior_info.h index 757f163c5a..318d4e1ff4 100644 --- a/src/audio_core/renderer/behavior/behavior_info.h +++ b/src/audio_core/renderer/behavior/behavior_info.h @@ -400,6 +400,7 @@ public: u32 process_revision; /// User version u32 user_revision{}; + bool native_platform{}; /// Behaviour flags Flags flags{}; /// Errors generated and reported during Update diff --git a/src/audio_core/renderer/behavior/info_updater.cpp b/src/audio_core/renderer/behavior/info_updater.cpp index ca3eaece94..a8fbcf9730 100644 --- a/src/audio_core/renderer/behavior/info_updater.cpp +++ b/src/audio_core/renderer/behavior/info_updater.cpp @@ -122,12 +122,21 @@ Result InfoUpdater::UpdateVoices(VoiceContext& voice_context, u8 flush_wave_buffer_count; u16 reserved2; VoiceInfo::Flags flags; + u8 reserved_after_flags; SrcQuality src_quality; + u8 crossfade_curve; u32 external_ctx; u32 external_ctx_size; u32 reserved3[2]; }; + static_assert(sizeof(VoiceInParameterV2) == 0x188); + static_assert(offsetof(VoiceInParameterV2, crossfade_curve) == 0x177); const auto* vin = reinterpret_cast<const VoiceInParameterV2*>(input + i * in_stride); + if (behaviour.GetUserRevisionNum() >= 16 && vin->in_use && vin->crossfade_curve != 0) { + LOG_ERROR(Service_Audio, "Unsupported voice biquad crossfade curve {}", + vin->crossfade_curve); + return Service::Audio::ResultInvalidUpdateInfo; + } local_in.id = vin->id; local_in.node_id = vin->node_id; local_in.is_new = vin->is_new; |
