diff --git a/Source/Core/Core/IOS/USB/Emulated/Microphone.cpp b/Source/Core/Core/IOS/USB/Emulated/Microphone.cpp index eaa9d4f5b1..6d8b4740e8 100644 --- a/Source/Core/Core/IOS/USB/Emulated/Microphone.cpp +++ b/Source/Core/Core/IOS/USB/Emulated/Microphone.cpp @@ -45,7 +45,7 @@ void Microphone::StreamInit() } // TODO: Not here but rather inside the WiiSpeak device if possible? - StreamStart(); + StreamStart(m_sampler.DEFAULT_SAMPLING_RATE); } void Microphone::StreamTerminate() @@ -60,12 +60,12 @@ static void state_callback(cubeb_stream* stream, void* user_data, cubeb_state st { } -void Microphone::StreamStart() +void Microphone::StreamStart(u32 sampling_rate) { if (!m_cubeb_ctx) return; - m_worker.Execute([this] { + m_worker.Execute([this, sampling_rate] { #ifdef ANDROID JNIEnv* env = IDCache::GetEnvForThread(); if (jboolean result = env->CallStaticBooleanMethod( @@ -81,7 +81,7 @@ void Microphone::StreamStart() cubeb_stream_params params{}; params.format = CUBEB_SAMPLE_S16LE; - params.rate = SAMPLING_RATE; + params.rate = sampling_rate; params.channels = 1; params.layout = CUBEB_LAYOUT_MONO; @@ -249,6 +249,12 @@ Microphone::FloatType Microphone::ComputeGain(FloatType relative_db) const return m_loudness.ComputeGain(relative_db); } +void Microphone::SetSamplingRate(u32 sampling_rate) +{ + StreamStop(); + StreamStart(sampling_rate); +} + const Microphone::FloatType Microphone::Loudness::DB_MIN = 20 * std::log10(FloatType(1) / MAX_AMPLITUDE); const Microphone::FloatType Microphone::Loudness::DB_MAX = 20 * std::log10(FloatType(1)); diff --git a/Source/Core/Core/IOS/USB/Emulated/Microphone.h b/Source/Core/Core/IOS/USB/Emulated/Microphone.h index 27d773008e..638448dc11 100644 --- a/Source/Core/Core/IOS/USB/Emulated/Microphone.h +++ b/Source/Core/Core/IOS/USB/Emulated/Microphone.h @@ -37,6 +37,7 @@ public: void UpdateLoudness(std::ranges::input_range auto&& samples); const WiiSpeakState& GetSampler() const; FloatType ComputeGain(FloatType relative_db) const; + void SetSamplingRate(u32 sampling_rate); private: static long DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, @@ -44,12 +45,11 @@ private: void StreamInit(); void StreamTerminate(); - void StreamStart(); + void StreamStart(u32 sampling_rate); void StreamStop(); - static constexpr u32 SAMPLING_RATE = 8000; using SampleType = s16; - static constexpr u32 BUFF_SIZE_SAMPLES = 16; + static constexpr u32 BUFF_SIZE_SAMPLES = 32; static constexpr u32 STREAM_SIZE = BUFF_SIZE_SAMPLES * 500; std::array m_stream_buffer{}; @@ -96,8 +96,8 @@ private: void Reset(); void LogStats(); - // Samples used to compute the loudness level - static constexpr u16 SAMPLES_NEEDED = SAMPLING_RATE / 125; + // Samples used to compute the loudness level (arbitrarily chosen) + static constexpr u16 SAMPLES_NEEDED = 128; static_assert((SAMPLES_NEEDED % BUFF_SIZE_SAMPLES) == 0); static constexpr FloatType MAX_AMPLITUDE = diff --git a/Source/Core/Core/IOS/USB/Emulated/WiiSpeak.cpp b/Source/Core/Core/IOS/USB/Emulated/WiiSpeak.cpp index 1cea22c89b..686906fd55 100644 --- a/Source/Core/Core/IOS/USB/Emulated/WiiSpeak.cpp +++ b/Source/Core/Core/IOS/USB/Emulated/WiiSpeak.cpp @@ -250,8 +250,6 @@ void WiiSpeak::SetRegister(const std::unique_ptr& cmd) m_sampler.sample_on = !!arg1; break; case SAMPLER_FREQ: - WARN_LOG_FMT(IOS_USB, "Wii Speak SAMPLER_FREQ set (arg1={:04x}, arg2={:04x}) not implemented", - arg1, arg2); switch (arg1) { case FREQ_8KHZ: @@ -271,6 +269,8 @@ void WiiSpeak::SetRegister(const std::unique_ptr& cmd) m_sampler.freq = 16000; break; } + if (m_microphone) + m_microphone->SetSamplingRate(m_sampler.freq); break; case SAMPLER_GAIN: WARN_LOG_FMT(IOS_USB, "Wii Speak SAMPLER_GAIN set (arg1={:04x}, arg2={:04x}) not implemented", diff --git a/Source/Core/Core/IOS/USB/Emulated/WiiSpeak.h b/Source/Core/Core/IOS/USB/Emulated/WiiSpeak.h index 57e2959196..b4d298f778 100644 --- a/Source/Core/Core/IOS/USB/Emulated/WiiSpeak.h +++ b/Source/Core/Core/IOS/USB/Emulated/WiiSpeak.h @@ -20,6 +20,8 @@ struct WiiSpeakState int gain; bool ec_reset; bool sp_on; + + static constexpr u32 DEFAULT_SAMPLING_RATE = 16000; }; class WiiSpeak final : public Device