mirror of
https://github.com/celisej567/abaddon.git
synced 2026-09-06 20:15:19 +03:00
add noise suppression
This commit is contained in:
@@ -423,19 +423,36 @@ void AudioManager::OnCapturedPCM(const int16_t *pcm, ma_uint32 frames) {
|
||||
|
||||
UpdateCaptureVolume(new_pcm.data(), frames);
|
||||
|
||||
static std::array<float, 480> denoised_L;
|
||||
static std::array<float, 480> denoised_R;
|
||||
|
||||
switch (m_vad_method) {
|
||||
case VADMethod::Gate:
|
||||
if (!CheckVADVoiceGate()) return;
|
||||
break;
|
||||
#ifdef WITH_RNNOISE
|
||||
case VADMethod::RNNoise:
|
||||
if (!CheckVADRNNoise(pcm)) return;
|
||||
if (!CheckVADRNNoise(new_pcm.data(), denoised_L.data(), denoised_R.data())) 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);
|
||||
int payload_len = -1;
|
||||
|
||||
if (m_enable_noise_suppression) {
|
||||
static std::array<int16_t, 960> denoised_interleaved;
|
||||
for (size_t i = 0; i < 480; i++) {
|
||||
denoised_interleaved[i * 2] = static_cast<int16_t>(denoised_L[i]);
|
||||
}
|
||||
for (size_t i = 0; i < 480; i++) {
|
||||
denoised_interleaved[i * 2 + 1] = static_cast<int16_t>(denoised_R[i]);
|
||||
}
|
||||
payload_len = opus_encode(m_encoder, denoised_interleaved.data(), 480, static_cast<unsigned char *>(m_opus_buffer), 1275);
|
||||
} else {
|
||||
payload_len = opus_encode(m_encoder, new_pcm.data(), 480, static_cast<unsigned char *>(m_opus_buffer), 1275);
|
||||
}
|
||||
|
||||
m_enc_mutex.unlock();
|
||||
if (payload_len < 0) {
|
||||
spdlog::get("audio")->error("encoding error: {}", payload_len);
|
||||
@@ -480,15 +497,23 @@ bool AudioManager::CheckVADVoiceGate() {
|
||||
}
|
||||
|
||||
#ifdef WITH_RNNOISE
|
||||
bool AudioManager::CheckVADRNNoise(const int16_t *pcm) {
|
||||
static float denoised[480];
|
||||
bool AudioManager::CheckVADRNNoise(const int16_t *pcm, float *denoised_left, float *denoised_right) {
|
||||
// use left channel for vad, only denoise right if noise suppression enabled
|
||||
std::unique_lock<std::mutex> _(m_rnn_mutex);
|
||||
|
||||
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]);
|
||||
}
|
||||
std::unique_lock<std::mutex> _(m_rnn_mutex);
|
||||
m_vad_prob = rnnoise_process_frame(m_rnnoise, denoised, rnnoise_input);
|
||||
m_vad_prob = rnnoise_process_frame(m_rnnoise[0], denoised_left, rnnoise_input);
|
||||
|
||||
if (m_enable_noise_suppression) {
|
||||
for (size_t i = 0; i < 480; i++) {
|
||||
rnnoise_input[i] = static_cast<float>(pcm[i * 2 + 1]);
|
||||
}
|
||||
m_vad_prob = rnnoise_process_frame(m_rnnoise[1], denoised_right, rnnoise_input);
|
||||
}
|
||||
|
||||
return m_vad_prob > m_prob_threshold;
|
||||
}
|
||||
|
||||
@@ -496,7 +521,8 @@ void AudioManager::RNNoiseInitialize() {
|
||||
spdlog::get("audio")->debug("Initializing RNNoise");
|
||||
RNNoiseUninitialize();
|
||||
std::unique_lock<std::mutex> _(m_rnn_mutex);
|
||||
m_rnnoise = rnnoise_create(nullptr);
|
||||
m_rnnoise[0] = rnnoise_create(nullptr);
|
||||
m_rnnoise[1] = 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");
|
||||
@@ -504,11 +530,13 @@ void AudioManager::RNNoiseInitialize() {
|
||||
}
|
||||
|
||||
void AudioManager::RNNoiseUninitialize() {
|
||||
if (m_rnnoise != nullptr) {
|
||||
if (m_rnnoise[0] != nullptr) {
|
||||
spdlog::get("audio")->debug("Uninitializing RNNoise");
|
||||
std::unique_lock<std::mutex> _(m_rnn_mutex);
|
||||
rnnoise_destroy(m_rnnoise);
|
||||
m_rnnoise = nullptr;
|
||||
rnnoise_destroy(m_rnnoise[0]);
|
||||
rnnoise_destroy(m_rnnoise[1]);
|
||||
m_rnnoise[0] = nullptr;
|
||||
m_rnnoise[1] = nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -571,6 +599,7 @@ AudioManager::VADMethod AudioManager::GetVADMethod() const {
|
||||
return m_vad_method;
|
||||
}
|
||||
|
||||
#ifdef WITH_RNNOISE
|
||||
float AudioManager::GetCurrentVADProbability() const {
|
||||
return m_vad_prob;
|
||||
}
|
||||
@@ -583,6 +612,15 @@ void AudioManager::SetRNNProbThreshold(double value) {
|
||||
m_prob_threshold = value;
|
||||
}
|
||||
|
||||
void AudioManager::SetSuppressNoise(bool value) {
|
||||
m_enable_noise_suppression = value;
|
||||
}
|
||||
|
||||
bool AudioManager::GetSuppressNoise() const {
|
||||
return m_enable_noise_suppression;
|
||||
}
|
||||
#endif
|
||||
|
||||
AudioManager::type_signal_opus_packet AudioManager::signal_opus_packet() {
|
||||
return m_signal_opus_packet;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user