diff options
Diffstat (limited to 'src/audio_core')
| -rw-r--r-- | src/audio_core/renderer/command/effect/biquad_filter.cpp | 38 | ||||
| -rw-r--r-- | src/audio_core/renderer/voice/voice_state.h | 8 | ||||
| -rw-r--r-- | src/audio_core/sink/cubeb_sink.cpp | 20 |
3 files changed, 39 insertions, 27 deletions
diff --git a/src/audio_core/renderer/command/effect/biquad_filter.cpp b/src/audio_core/renderer/command/effect/biquad_filter.cpp index edb30ce72..dea6423dc 100644 --- a/src/audio_core/renderer/command/effect/biquad_filter.cpp +++ b/src/audio_core/renderer/command/effect/biquad_filter.cpp @@ -4,6 +4,7 @@ #include "audio_core/renderer/adsp/command_list_processor.h" #include "audio_core/renderer/command/effect/biquad_filter.h" #include "audio_core/renderer/voice/voice_state.h" +#include "common/bit_cast.h" namespace AudioCore::AudioRenderer { /** @@ -19,21 +20,21 @@ namespace AudioCore::AudioRenderer { void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input, std::array<s16, 3>& b_, std::array<s16, 2>& a_, VoiceState::BiquadFilterState& state, const u32 sample_count) { - constexpr s64 min{std::numeric_limits<s32>::min()}; - constexpr s64 max{std::numeric_limits<s32>::max()}; + constexpr f64 min{std::numeric_limits<s32>::min()}; + constexpr f64 max{std::numeric_limits<s32>::max()}; std::array<f64, 3> b{Common::FixedPoint<50, 14>::from_base(b_[0]).to_double(), Common::FixedPoint<50, 14>::from_base(b_[1]).to_double(), Common::FixedPoint<50, 14>::from_base(b_[2]).to_double()}; std::array<f64, 2> a{Common::FixedPoint<50, 14>::from_base(a_[0]).to_double(), Common::FixedPoint<50, 14>::from_base(a_[1]).to_double()}; - std::array<f64, 4> s{state.s0.to_double(), state.s1.to_double(), state.s2.to_double(), - state.s3.to_double()}; + std::array<f64, 4> s{Common::BitCast<f64>(state.s0), Common::BitCast<f64>(state.s1), + Common::BitCast<f64>(state.s2), Common::BitCast<f64>(state.s3)}; for (u32 i = 0; i < sample_count; i++) { f64 in_sample{static_cast<f64>(input[i])}; auto sample{in_sample * b[0] + s[0] * b[1] + s[1] * b[2] + s[2] * a[0] + s[3] * a[1]}; - output[i] = static_cast<s32>(std::clamp(static_cast<s64>(sample), min, max)); + output[i] = static_cast<s32>(std::clamp(sample, min, max)); s[1] = s[0]; s[0] = in_sample; @@ -41,10 +42,10 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input, s[2] = sample; } - state.s0 = s[0]; - state.s1 = s[1]; - state.s2 = s[2]; - state.s3 = s[3]; + state.s0 = Common::BitCast<s64>(s[0]); + state.s1 = Common::BitCast<s64>(s[1]); + state.s2 = Common::BitCast<s64>(s[2]); + state.s3 = Common::BitCast<s64>(s[3]); } /** @@ -58,29 +59,20 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input, * @param sample_count - Number of samples to process. */ static void ApplyBiquadFilterInt(std::span<s32> output, std::span<const s32> input, - std::array<s16, 3>& b_, std::array<s16, 2>& a_, + std::array<s16, 3>& b, std::array<s16, 2>& a, VoiceState::BiquadFilterState& state, const u32 sample_count) { constexpr s64 min{std::numeric_limits<s32>::min()}; constexpr s64 max{std::numeric_limits<s32>::max()}; - std::array<Common::FixedPoint<50, 14>, 3> b{ - Common::FixedPoint<50, 14>::from_base(b_[0]), - Common::FixedPoint<50, 14>::from_base(b_[1]), - Common::FixedPoint<50, 14>::from_base(b_[2]), - }; - std::array<Common::FixedPoint<50, 14>, 3> a{ - Common::FixedPoint<50, 14>::from_base(a_[0]), - Common::FixedPoint<50, 14>::from_base(a_[1]), - }; for (u32 i = 0; i < sample_count; i++) { - s64 in_sample{input[i]}; - auto sample{in_sample * b[0] + state.s0}; - const auto out_sample{std::clamp(sample.to_long(), min, max)}; + const s64 in_sample{input[i]}; + const s64 sample{in_sample * b[0] + state.s0}; + const s64 out_sample{std::clamp<s64>((sample + (1 << 13)) >> 14, min, max)}; output[i] = static_cast<s32>(out_sample); state.s0 = state.s1 + b[1] * in_sample + a[0] * out_sample; - state.s1 = 0 + b[2] * in_sample + a[1] * out_sample; + state.s1 = b[2] * in_sample + a[1] * out_sample; } } diff --git a/src/audio_core/renderer/voice/voice_state.h b/src/audio_core/renderer/voice/voice_state.h index d5497e2fb..ce947233f 100644 --- a/src/audio_core/renderer/voice/voice_state.h +++ b/src/audio_core/renderer/voice/voice_state.h @@ -19,10 +19,10 @@ struct VoiceState { * State of the voice's biquad filter. */ struct BiquadFilterState { - Common::FixedPoint<50, 14> s0; - Common::FixedPoint<50, 14> s1; - Common::FixedPoint<50, 14> s2; - Common::FixedPoint<50, 14> s3; + s64 s0; + s64 s1; + s64 s2; + s64 s3; }; /** diff --git a/src/audio_core/sink/cubeb_sink.cpp b/src/audio_core/sink/cubeb_sink.cpp index 32c1b1cb3..9133f5388 100644 --- a/src/audio_core/sink/cubeb_sink.cpp +++ b/src/audio_core/sink/cubeb_sink.cpp @@ -302,11 +302,21 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) { std::vector<std::string> device_list; cubeb* ctx; +#ifdef _WIN32 + auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED); +#endif + if (cubeb_init(&ctx, "yuzu Device Enumerator", nullptr) != CUBEB_OK) { LOG_CRITICAL(Audio_Sink, "cubeb_init failed"); return {}; } +#ifdef _WIN32 + if (SUCCEEDED(com_init_result)) { + CoUninitialize(); + } +#endif + auto type{capture ? CUBEB_DEVICE_TYPE_INPUT : CUBEB_DEVICE_TYPE_OUTPUT}; cubeb_device_collection collection; if (cubeb_enumerate_devices(ctx, type, &collection) != CUBEB_OK) { @@ -329,12 +339,22 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) { u32 GetCubebLatency() { cubeb* ctx; +#ifdef _WIN32 + auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED); +#endif + 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 + cubeb_stream_params params{}; params.rate = TargetSampleRate; params.channels = 2; |
