From 7905eb025432a2d46deb6352ea29979c380c1cf9 Mon Sep 17 00:00:00 2001
From: Kelebek1 <eeeedddccc@hotmail.co.uk>
Date: Thu, 8 Jul 2021 14:23:49 +0100
Subject: [PATCH] Replace NaN mix volume samples with silence.

Fixes Xenoblade Chronicles 2 blowing out the audio.
---
 src/audio_core/command_generator.cpp | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp
index 1402ff280..02c6e6f6a 100644
--- a/src/audio_core/command_generator.cpp
+++ b/src/audio_core/command_generator.cpp
@@ -42,6 +42,15 @@ void ApplyMix(std::span<s32> output, std::span<const s32> input, s32 gain, s32 s
 
 s32 ApplyMixRamp(std::span<s32> output, std::span<const s32> input, float gain, float delta,
                  s32 sample_count) {
+    // XC2 passes in NaN mix volumes, causing further issues as we handle everything as s32 rather
+    // than float, so the NaN propogation is lost. As the samples get further modified for
+    // volume etc, they can get out of NaN range, so a later heuristic for catching this is
+    // more difficult. Handle it here by setting these samples to silence.
+    if (std::isnan(gain)) {
+        gain = 0.0f;
+        delta = 0.0f;
+    }
+
     s32 x = 0;
     for (s32 i = 0; i < sample_count; i++) {
         x = static_cast<s32>(static_cast<float>(input[i]) * gain);