From dd29365970e06a1e40b06714a8fed0fcfffbbd1d Mon Sep 17 00:00:00 2001 From: Gliniak Date: Mon, 1 Dec 2025 23:57:53 +0100 Subject: [PATCH] [APU] Switched to New XMA decoder as default - Added codepath for "consume only" pass. This should resolve constant clicking in Source engine games. - Added smaller performance improvements to decoder --- src/xenia/apu/xma_context.h | 6 ++++++ src/xenia/apu/xma_context_new.cc | 12 +++++++++++- src/xenia/apu/xma_context_new.h | 3 ++- src/xenia/apu/xma_decoder.cc | 4 +++- src/xenia/base/cvar.h | 2 +- 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/xenia/apu/xma_context.h b/src/xenia/apu/xma_context.h index d52f68897..d7dfa39c8 100644 --- a/src/xenia/apu/xma_context.h +++ b/src/xenia/apu/xma_context.h @@ -146,6 +146,12 @@ struct XMA_CONTEXT_DATA { const uint32_t GetCurrentInputBufferPacketCount() const { return GetInputBufferPacketCount(current_buffer); } + const bool IsStreamingContext() const { + return (input_buffer_0_packet_count | input_buffer_1_packet_count) == 1; + } + const bool IsConsumeOnlyContext() const { + return (input_buffer_0_packet_count | input_buffer_1_packet_count) == 0; + } }; static_assert_size(XMA_CONTEXT_DATA, 64); diff --git a/src/xenia/apu/xma_context_new.cc b/src/xenia/apu/xma_context_new.cc index 4d7034c6c..6dad9704c 100644 --- a/src/xenia/apu/xma_context_new.cc +++ b/src/xenia/apu/xma_context_new.cc @@ -128,6 +128,15 @@ bool XmaContextNew::Work() { RingBuffer output_rb = PrepareOutputRingBuffer(&data); + if (data.IsConsumeOnlyContext()) { + Consume(&output_rb, &data); + if (data.output_buffer_read_offset == data.output_buffer_write_offset) { + Clear(); + } + data.Store(context_ptr); + return true; + } + const int32_t minimum_subframe_decode_count = (data.subframe_decode_count * 2) - 1; @@ -257,7 +266,8 @@ void XmaContextNew::SwapInputBuffer(XMA_CONTEXT_DATA* data) { data->input_buffer_read_offset = kBitsPerPacketHeader; } -void XmaContextNew::Consume(RingBuffer* output_rb, XMA_CONTEXT_DATA* data) { +void XmaContextNew::Consume(RingBuffer* XE_RESTRICT output_rb, + const XMA_CONTEXT_DATA* const XE_RESTRICT data) { if (!current_frame_remaining_subframes_) { return; } diff --git a/src/xenia/apu/xma_context_new.h b/src/xenia/apu/xma_context_new.h index 1d86c7af4..985b2ca9a 100644 --- a/src/xenia/apu/xma_context_new.h +++ b/src/xenia/apu/xma_context_new.h @@ -106,7 +106,8 @@ class XmaContextNew : public XmaContext { static uint32_t GetCurrentInputBufferSize(XMA_CONTEXT_DATA* data); void Decode(XMA_CONTEXT_DATA* data); - void Consume(RingBuffer* output_rb, XMA_CONTEXT_DATA* data); + void Consume(RingBuffer* XE_RESTRICT output_rb, + const XMA_CONTEXT_DATA* const XE_RESTRICT data); void UpdateLoopStatus(XMA_CONTEXT_DATA* data); int PrepareDecoder(int sample_rate, bool is_two_channel); diff --git a/src/xenia/apu/xma_decoder.cc b/src/xenia/apu/xma_decoder.cc index 07ff4c659..114885edd 100644 --- a/src/xenia/apu/xma_decoder.cc +++ b/src/xenia/apu/xma_decoder.cc @@ -54,7 +54,7 @@ extern "C" { DEFINE_bool(ffmpeg_verbose, false, "Verbose FFmpeg output (debug and above)", "APU"); -DEFINE_bool(use_new_decoder, false, +DEFINE_bool(use_new_decoder, true, "Enables usage of new experimental XMA audio decoder.", "APU"); DEFINE_bool(use_dedicated_xma_thread, true, @@ -62,6 +62,8 @@ DEFINE_bool(use_dedicated_xma_thread, true, "better results, but decrease performance a bit.", "APU"); +UPDATE_from_bool(use_new_decoder, 2025, 12, 01, 23, false); + namespace xe { namespace apu { diff --git a/src/xenia/base/cvar.h b/src/xenia/base/cvar.h index 6b139bda7..3c9581ba7 100644 --- a/src/xenia/base/cvar.h +++ b/src/xenia/base/cvar.h @@ -511,7 +511,7 @@ class IConfigVarUpdate { // If you're reviewing a pull request with a change here, check if 1) has been // done by the submitter before merging. static constexpr uint32_t kLastCommittedUpdateDate = - MakeConfigVarUpdateDate(2024, 9, 23, 9); + MakeConfigVarUpdateDate(2025, 12, 1, 23); virtual ~IConfigVarUpdate() = default;