summaryrefslogtreecommitdiff
path: root/src/audio/manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio/manager.cpp')
-rw-r--r--src/audio/manager.cpp92
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;
}