aboutsummaryrefslogtreecommitdiff
path: root/src/audio_core
diff options
context:
space:
mode:
authorcrueter <crueter@eden-emu.dev>2025-07-27 19:46:54 +0200
committercrueter <crueter@eden-emu.dev>2025-07-27 19:46:54 +0200
commit0b29fb7c8ad3f83bf59233311498fdbfc74cd680 (patch)
tree5f18286b964c95b302656cdd770cdc19f0ea354f /src/audio_core
parentb2914247c3f6bff2b2aa0f17d46f7b197ab1821d (diff)
[audio_core] Revert EA3835 audio sink changes (#136)
Fixes diablo/totk audio stutters Signed-off-by: crueter <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/136
Diffstat (limited to 'src/audio_core')
-rw-r--r--src/audio_core/sink/cubeb_sink.cpp46
-rw-r--r--src/audio_core/sink/cubeb_sink.h13
-rw-r--r--src/audio_core/sink/sdl2_sink.cpp8
-rw-r--r--src/audio_core/sink/sdl2_sink.h13
-rw-r--r--src/audio_core/sink/sink_details.cpp43
5 files changed, 114 insertions, 9 deletions
diff --git a/src/audio_core/sink/cubeb_sink.cpp b/src/audio_core/sink/cubeb_sink.cpp
index 7f4b1c365a..a33162b806 100644
--- a/src/audio_core/sink/cubeb_sink.cpp
+++ b/src/audio_core/sink/cubeb_sink.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -334,6 +337,48 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
return device_list;
}
+/* REVERSION TO 3833 - function GetCubebLatency REINTRODUCED FROM 3833 - DIABLO 3 FIX */
+u32 GetCubebLatency() {
+ cubeb* ctx;
+
+#ifdef _WIN32
+ auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
+#endif
+
+ // Init cubeb
+ if (cubeb_init(&ctx, "yuzu Latency Getter", nullptr) != CUBEB_OK) {
+ LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
+ // Return a large latency so we choose SDL instead.
+ return 10000u;
+ }
+
+#ifdef _WIN32
+ if (SUCCEEDED(com_init_result)) {
+ CoUninitialize();
+ }
+#endif
+
+ // Get min latency
+ cubeb_stream_params params{};
+ params.rate = TargetSampleRate;
+ params.channels = 2;
+ params.format = CUBEB_SAMPLE_S16LE;
+ params.prefs = CUBEB_STREAM_PREF_NONE;
+ params.layout = CUBEB_LAYOUT_STEREO;
+
+ u32 latency{0};
+ const auto latency_error = cubeb_get_min_latency(ctx, &params, &latency);
+ if (latency_error != CUBEB_OK) {
+ LOG_CRITICAL(Audio_Sink, "Error getting minimum latency, error: {}", latency_error);
+ latency = TargetSampleCount * 2;
+ }
+ latency = std::max(latency, TargetSampleCount * 2);
+ cubeb_destroy(ctx);
+ return latency;
+}
+
+// REVERTED back to 3833 - Below namespace section and function IsCubebSuitable() removed, reverting to GetCubebLatency() above. - DIABLO 3 FIX
+/*
namespace {
static long TmpDataCallback(cubeb_stream*, void*, const void*, void*, long) {
return TargetSampleCount;
@@ -400,5 +445,6 @@ bool IsCubebSuitable() {
return true;
#endif
}
+*/
} // namespace AudioCore::Sink
diff --git a/src/audio_core/sink/cubeb_sink.h b/src/audio_core/sink/cubeb_sink.h
index f49a6fdaa7..6dc7d3d296 100644
--- a/src/audio_core/sink/cubeb_sink.h
+++ b/src/audio_core/sink/cubeb_sink.h
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -96,12 +99,20 @@ private:
*/
std::vector<std::string> ListCubebSinkDevices(bool capture);
+// REVERSION - function GetCubebLatency() reintroduced from EA-3833 - DIABLO 3 FIX
+/**
+ * Get the reported latency for this sink.
+ *
+ * @return Minimum latency for this sink.
+ */
+u32 GetCubebLatency();
+
/**
* Check if this backend is suitable for use.
* Checks if enabled, its latency, whether it opens successfully, etc.
*
* @return True is this backend is suitable, false otherwise.
*/
-bool IsCubebSuitable();
+// bool IsCubebSuitable(); // REVERTED BACK TO GetCubebLatency() FROM 3833
} // namespace AudioCore::Sink
diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp
index ffdd77042e..25ed58620e 100644
--- a/src/audio_core/sink/sdl2_sink.cpp
+++ b/src/audio_core/sink/sdl2_sink.cpp
@@ -234,6 +234,13 @@ std::vector<std::string> ListSDLSinkDevices(bool capture) {
return device_list;
}
+/* REVERSION to 3833 - function GetSDLLatency() REINTRODUCED FROM 3833 - DIABLO 3 FIX */
+u32 GetSDLLatency() {
+ return TargetSampleCount * 2;
+}
+
+// REVERTED back to 3833 - Below function IsSDLSuitable() removed, reverting to GetSDLLatency() above. - DIABLO 3 FIX
+/*
bool IsSDLSuitable() {
#if !defined(HAVE_SDL2)
return false;
@@ -271,5 +278,6 @@ bool IsSDLSuitable() {
return true;
#endif
}
+*/
} // namespace AudioCore::Sink
diff --git a/src/audio_core/sink/sdl2_sink.h b/src/audio_core/sink/sdl2_sink.h
index 9211d2e978..19ea32595f 100644
--- a/src/audio_core/sink/sdl2_sink.h
+++ b/src/audio_core/sink/sdl2_sink.h
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -87,12 +90,20 @@ private:
*/
std::vector<std::string> ListSDLSinkDevices(bool capture);
+// REVERSION - function GetSDLLatency() reintroduced from EA-3833 - DIABLO 3 FIX
/**
+ * Get the reported latency for this sink.
+ *
+ * @return Minimum latency for this sink.
+ */
+u32 GetSDLLatency();
+
+/** REVERTED back to 3833 - Below function IsSDLSuitable() removed, reverting to GetSDLLatency() above. - DIABLO 3 FIX
* Check if this backend is suitable for use.
* Checks if enabled, its latency, whether it opens successfully, etc.
*
* @return True is this backend is suitable, false otherwise.
*/
-bool IsSDLSuitable();
+//bool IsSDLSuitable(); // REVERTED for GetSDLLatency() from EA-3833
} // namespace AudioCore::Sink
diff --git a/src/audio_core/sink/sink_details.cpp b/src/audio_core/sink/sink_details.cpp
index 449af659d0..70bf75018b 100644
--- a/src/audio_core/sink/sink_details.cpp
+++ b/src/audio_core/sink/sink_details.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -25,7 +28,8 @@ namespace {
struct SinkDetails {
using FactoryFn = std::unique_ptr<Sink> (*)(std::string_view);
using ListDevicesFn = std::vector<std::string> (*)(bool);
- using SuitableFn = bool (*)();
+ using LatencyFn = u32 (*)(); // REINTRODUCED FROM 3833 - DIABLO 3 FIX
+ // using SuitableFn = bool (*)(); // REVERTED FOR ABOVE - DIABLO 3 FIX
/// Name for this sink.
Settings::AudioEngine id;
@@ -33,10 +37,18 @@ struct SinkDetails {
FactoryFn factory;
/// A method to call to list available devices.
ListDevicesFn list_devices;
+ /// Method to get the latency of this backend - REINTRODUCED FROM 3833 - DIABLO 3 FIX
+ LatencyFn latency;
/// Check whether this backend is suitable to be used.
- SuitableFn is_suitable;
+ /// SuitableFn is_suitable; // REVERTED FOR LatencyFn latency ABOVE - DIABLO 3 FIX
};
+// NOTE TO PROBABLY FIX LATER FOR ANDROID - the return value "0u" for the first HAVE_OBOE
+// section below was just copied from the null section so there's a somewhat valid value
+// being returned, since the previous "true" value probably isn't compatible with the
+// previous EA-3833 code. (HAVE_OBOE was introduced in a later release.) Eventually need
+// to change "0u" for something else directly from the oboe_sink.cpp functions.
+
// sink_details is ordered in terms of desirability, with the best choice at the top.
constexpr SinkDetails sink_details[] = {
#ifdef HAVE_OBOE
@@ -46,7 +58,7 @@ constexpr SinkDetails sink_details[] = {
return std::make_unique<OboeSink>();
},
[](bool capture) { return std::vector<std::string>{"Default"}; },
- []() { return true; },
+ []() { return 0u; },
},
#endif
#ifdef HAVE_CUBEB
@@ -56,7 +68,7 @@ constexpr SinkDetails sink_details[] = {
return std::make_unique<CubebSink>(device_id);
},
&ListCubebSinkDevices,
- &IsCubebSuitable,
+ &GetCubebLatency,
},
#endif
#ifdef HAVE_SDL2
@@ -66,7 +78,7 @@ constexpr SinkDetails sink_details[] = {
return std::make_unique<SDLSink>(device_id);
},
&ListSDLSinkDevices,
- &IsSDLSuitable,
+ &GetSDLLatency,
},
#endif
SinkDetails{
@@ -75,7 +87,7 @@ constexpr SinkDetails sink_details[] = {
return std::make_unique<NullSink>(device_id);
},
[](bool capture) { return std::vector<std::string>{"null"}; },
- []() { return true; },
+ []() { return 0u; },
},
};
@@ -88,6 +100,8 @@ const SinkDetails& GetOutputSinkDetails(Settings::AudioEngine sink_id) {
auto iter = find_backend(sink_id);
if (sink_id == Settings::AudioEngine::Auto) {
+ // REVERTED TO 3833 BELOW - DIABLO 3 FIX
+ /*
// Auto-select a backend. Use the sink details ordering, preferring cubeb first, checking
// that the backend is available and suitable to use.
for (auto& details : sink_details) {
@@ -96,14 +110,29 @@ const SinkDetails& GetOutputSinkDetails(Settings::AudioEngine sink_id) {
break;
}
}
+ */ // END REVERTED CODE - DIABLO 3 FIX
+
+ // BEGIN REINTRODUCED FROM 3833 - REPLACED CODE BLOCK ABOVE - DIABLO 3 FIX
+ // Auto-select a backend. Prefer CubeB, but it may report a large minimum latency which
+ // causes audio issues, in that case go with SDL.
+#if defined(HAVE_CUBEB) && defined(HAVE_SDL2)
+ iter = find_backend(Settings::AudioEngine::Cubeb);
+ if (iter->latency() > TargetSampleCount * 3) {
+ iter = find_backend(Settings::AudioEngine::Sdl2);
+ }
+#else
+ iter = std::begin(sink_details);
+#endif
+ // END REINTRODUCED SECTION FROM 3833 - DIABLO 3 FIX
LOG_INFO(Service_Audio, "Auto-selecting the {} backend",
Settings::CanonicalizeEnum(iter->id));
+ /* BEGIN REMOVED - REVERTING BACK TO 3833, this didn't exist at all. - DIABLO 3 FIX
} else {
if (iter != std::end(sink_details) && !iter->is_suitable()) {
LOG_ERROR(Service_Audio, "Selected backend {} is not suitable, falling back to null",
Settings::CanonicalizeEnum(iter->id));
iter = find_backend(Settings::AudioEngine::Null);
- }
+ } */ // END REMOVED REVERT - DIABLO 3 FIX
}
if (iter == std::end(sink_details)) {