diff options
Diffstat (limited to 'src/audio')
-rw-r--r-- | src/audio/manager.cpp | 92 | ||||
-rw-r--r-- | src/audio/manager.hpp | 54 |
2 files changed, 134 insertions, 12 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; } diff --git a/src/audio/manager.hpp b/src/audio/manager.hpp index ed40f35..dac9738 100644 --- a/src/audio/manager.hpp +++ b/src/audio/manager.hpp @@ -14,6 +14,11 @@ #include <miniaudio.h> #include <opus.h> #include <sigc++/sigc++.h> + +#ifdef WITH_RNNOISE +#include <rnnoise.h> +#endif + #include "devices.hpp" // clang-format on @@ -40,30 +45,42 @@ public: void SetCaptureGate(double gate); void SetCaptureGain(double gain); - [[nodiscard]] double GetCaptureGate() const noexcept; - [[nodiscard]] double GetCaptureGain() const noexcept; + double GetCaptureGate() const noexcept; + double GetCaptureGain() const noexcept; void SetMuteSSRC(uint32_t ssrc, bool mute); void SetVolumeSSRC(uint32_t ssrc, double volume); - [[nodiscard]] double GetVolumeSSRC(uint32_t ssrc) const; + double GetVolumeSSRC(uint32_t ssrc) const; void SetEncodingApplication(int application); - [[nodiscard]] int GetEncodingApplication(); + int GetEncodingApplication(); void SetSignalHint(int signal); - [[nodiscard]] int GetSignalHint(); + int GetSignalHint(); void SetBitrate(int bitrate); - [[nodiscard]] int GetBitrate(); + int GetBitrate(); void Enumerate(); - [[nodiscard]] bool OK() const; + bool OK() const; + + double GetCaptureVolumeLevel() const noexcept; + double GetSSRCVolumeLevel(uint32_t ssrc) const noexcept; + + AudioDevices &GetDevices(); + + uint32_t GetRTPTimestamp() const noexcept; - [[nodiscard]] double GetCaptureVolumeLevel() const noexcept; - [[nodiscard]] double GetSSRCVolumeLevel(uint32_t ssrc) const noexcept; + enum class VADMethod { + Gate, + RNNoise, + }; - [[nodiscard]] AudioDevices &GetDevices(); + void SetVADMethod(const std::string &method); + void SetVADMethod(VADMethod method); + VADMethod GetVADMethod() const; - [[nodiscard]] uint32_t GetRTPTimestamp() const noexcept; + float GetCurrentVADProbability() const; + double GetRNNProbThreshold() const; private: void OnCapturedPCM(const int16_t *pcm, ma_uint32 frames); @@ -74,6 +91,15 @@ private: bool DecayVolumeMeters(); + bool CheckVADVoiceGate(); + +#ifdef WITH_RNNOISE + bool CheckVADRNNoise(const int16_t *pcm); + + void RNNoiseInitialize(); + void RNNoiseUninitialize(); +#endif + friend void data_callback(ma_device *, void *, const void *, ma_uint32); friend void capture_data_callback(ma_device *, void *, const void *, ma_uint32); @@ -106,6 +132,8 @@ private: std::atomic<double> m_capture_gate = 0.0; std::atomic<double> m_capture_gain = 1.0; + std::atomic<double> m_prob_threshold = 0.5; + std::atomic<float> m_vad_prob = 0.0; std::unordered_set<uint32_t> m_muted_ssrcs; std::unordered_map<uint32_t, double> m_volume_ssrc; @@ -115,6 +143,10 @@ private: AudioDevices m_devices; + VADMethod m_vad_method; +#ifdef WITH_RNNOISE + DenoiseState *m_rnnoise; +#endif std::atomic<uint32_t> m_rtp_timestamp = 0; public: |