diff options
Diffstat (limited to 'src/audio/manager.cpp')
-rw-r--r-- | src/audio/manager.cpp | 92 |
1 files changed, 91 insertions, 1 deletions
diff --git a/src/audio/manager.cpp b/src/audio/manager.cpp index 67fbcd9..53eff54 100644 --- a/src/audio/manager.cpp +++ b/src/audio/manager.cpp @@ -143,6 +143,10 @@ AudioManager::~AudioManager() { ma_device_uninit(&m_capture_device); ma_context_uninit(&m_context); RemoveAllSSRCs(); + +#ifdef WITH_RNNOISE + RNNoiseUninitialize(); +#endif } void AudioManager::AddSSRC(uint32_t ssrc) { @@ -419,7 +423,16 @@ void AudioManager::OnCapturedPCM(const int16_t *pcm, ma_uint32 frames) { UpdateCaptureVolume(new_pcm.data(), frames); - if (m_capture_peak_meter / 32768.0 < m_capture_gate) return; + switch (m_vad_method) { + case VADMethod::Gate: + if (!CheckVADVoiceGate()) return; + break; +#ifdef WITH_RNNOISE + case VADMethod::RNNoise: + if (!CheckVADRNNoise(pcm)) return; + break; +#endif + } m_enc_mutex.lock(); int payload_len = opus_encode(m_encoder, new_pcm.data(), 480, static_cast<unsigned char *>(m_opus_buffer), 1275); @@ -462,6 +475,41 @@ bool AudioManager::DecayVolumeMeters() { return true; } +bool AudioManager::CheckVADVoiceGate() { + return m_capture_peak_meter / 32768.0 > m_capture_gate; +} + +#ifdef WITH_RNNOISE +bool AudioManager::CheckVADRNNoise(const int16_t *pcm) { + static float denoised[480]; + static float rnnoise_input[480]; + // take left channel + for (size_t i = 0; i < 480; i++) { + rnnoise_input[i] = static_cast<float>(pcm[i * 2]); + } + m_vad_prob = rnnoise_process_frame(m_rnnoise, denoised, rnnoise_input); + return m_vad_prob > m_prob_threshold; +} + +void AudioManager::RNNoiseInitialize() { + spdlog::get("audio")->debug("Initializing RNNoise"); + RNNoiseUninitialize(); + m_rnnoise = rnnoise_create(nullptr); + const auto expected = rnnoise_get_frame_size(); + if (expected != 480) { + spdlog::get("audio")->warn("RNNoise expects a frame count other than 480"); + } +} + +void AudioManager::RNNoiseUninitialize() { + if (m_rnnoise != nullptr) { + spdlog::get("audio")->debug("Uninitializing RNNoise"); + rnnoise_destroy(m_rnnoise); + m_rnnoise = nullptr; + } +} +#endif + bool AudioManager::OK() const { return m_ok; } @@ -486,6 +534,48 @@ uint32_t AudioManager::GetRTPTimestamp() const noexcept { return m_rtp_timestamp; } +void AudioManager::SetVADMethod(const std::string &method) { + spdlog::get("audio")->debug("Setting VAD method to {}", method); + if (method == "gate") { + SetVADMethod(VADMethod::Gate); + } else if (method == "rnnoise") { +#ifdef WITH_RNNOISE + SetVADMethod(VADMethod::RNNoise); +#else + SetVADMethod(VADMethod::Gate); + spdlog::get("audio")->error("Tried to set RNNoise VAD method with support disabled"); +#endif + } else { + SetVADMethod(VADMethod::Gate); + spdlog::get("audio")->error("Tried to set unknown VAD method {}", method); + } +} + +void AudioManager::SetVADMethod(VADMethod method) { + spdlog::get("audio")->debug("Setting VAD method to enum {}", static_cast<int>(method)); + m_vad_method = method; + +#ifdef WITH_RNNOISE + if (method == VADMethod::RNNoise) { + RNNoiseInitialize(); + } else { + RNNoiseUninitialize(); + } +#endif +} + +AudioManager::VADMethod AudioManager::GetVADMethod() const { + return m_vad_method; +} + +float AudioManager::GetCurrentVADProbability() const { + return m_vad_prob; +} + +double AudioManager::GetRNNProbThreshold() const { + return m_prob_threshold; +} + AudioManager::type_signal_opus_packet AudioManager::signal_opus_packet() { return m_signal_opus_packet; } |