From 5693da0f42ca92ad45166999988e250ebf494a00 Mon Sep 17 00:00:00 2001 From: Vektor Date: Tue, 15 Aug 2023 16:26:26 +0200 Subject: [PATCH] readd normalization --- examples/devicetests.cpp | 1 + include/ISoundInput.h | 3 +++ src/CSoundInput.cpp | 41 ++++++++++++++++++++++++++++++++++++++++ src/CSoundInput.h | 10 +++++++++- 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/examples/devicetests.cpp b/examples/devicetests.cpp index 81c2b5a..74c975a 100644 --- a/examples/devicetests.cpp +++ b/examples/devicetests.cpp @@ -63,6 +63,7 @@ int main() soundInput->SelectDeviceByUID(nullptr); soundInput->SetStreamEnabled(true); soundInput->SetNoiseSuppressionEnabled(true); + soundInput->SetNormalizatonEnabled(true); std::cout << soundInput->GetCurrentDeviceUID() << std::endl; for(;;) diff --git a/include/ISoundInput.h b/include/ISoundInput.h index 96409df..97f7b35 100644 --- a/include/ISoundInput.h +++ b/include/ISoundInput.h @@ -33,4 +33,7 @@ class ISoundInput virtual void SetStreamEnabled(bool enabled) = 0; virtual void SetNoiseSuppressionEnabled(bool enabled) = 0; [[nodiscard]] virtual bool IsNoiseSuppressionEnabled() const = 0; + + virtual void SetNormalizatonEnabled(bool enabled) = 0; + [[nodiscard]] virtual bool IsNormalizationEnabled() const = 0; }; \ No newline at end of file diff --git a/src/CSoundInput.cpp b/src/CSoundInput.cpp index 8f85422..ea915e9 100644 --- a/src/CSoundInput.cpp +++ b/src/CSoundInput.cpp @@ -242,6 +242,44 @@ void CSoundInput::NoiseSuppressionProcess(void* buffer, DWORD length) } } +void CSoundInput::SetNormalizatonEnabled(bool enabled) +{ + normalizationEnabled = enabled; +} + +bool CSoundInput::IsNormalizationEnabled() const +{ + return normalizationEnabled; +} + +void CSoundInput::Normalize(short* buffer, DWORD length) +{ + if(normalizationEnabled) + { + short maxFrame = 0; + for (int i = 0; i < length; ++i) + { + short s = abs(buffer[i]); + if (s > maxFrame) + maxFrame = s; + } + + if (normalizeMax == 0.f || maxFrame > normalizeMax || normalizeMax / maxFrame < 0.5) + normalizeMax = maxFrame; + else + normalizeMax = (normalizeMax * (NORMALIZE_FRAME_COUNT - 1) + maxFrame) / NORMALIZE_FRAME_COUNT; + + if (normalizeMax <= 1.f) + return; + + float gain = MAXSHORT / normalizeMax / 2; + gain = std::fmin(gain, 10); + + for (int i = 0; i < length; ++i) + buffer[i] *= gain; + } +} + void CSoundInput::SoundFrameCaptured(HRECORD handle, const void* buffer, DWORD length) { // Create new buffer on stack because buffer was marked as const in API @@ -250,6 +288,9 @@ void CSoundInput::SoundFrameCaptured(HRECORD handle, const void* buffer, DWORD l // Apply noise suppression NoiseSuppressionProcess(writableBuffer, FRAME_SIZE_SAMPLES); + // Apply normalization + Normalize(writableBuffer, FRAME_SIZE_SAMPLES); + // Get current microphone noise level const DWORD currentMicLevel = BASS_ChannelGetLevel(handle); diff --git a/src/CSoundInput.h b/src/CSoundInput.h index 7ac502f..69311ce 100644 --- a/src/CSoundInput.h +++ b/src/CSoundInput.h @@ -11,6 +11,7 @@ class CSoundInput : public ISoundInput { static constexpr int RNNoiseFrameSize = 480; static constexpr float MaxShortFloatValue = 32768.0f; + static constexpr int NORMALIZE_FRAME_COUNT = 20; HRECORD recordChannel = 0; COpusEncoder* encoder = nullptr; @@ -20,6 +21,9 @@ class CSoundInput : public ISoundInput float micLevel = 0; bool noiseSuppressionEnabled = false; + bool normalizationEnabled = false; + float normalizeMax = 0.f; + HFX VolumeChangeFX; DenoiseState* denoiser; @@ -56,8 +60,12 @@ class CSoundInput : public ISoundInput void RegisterCallback(OnVoiceCallback callback) override; void SetNoiseSuppressionEnabled(bool enabled) override; - void NoiseSuppressionProcess(void* buffer, DWORD length); [[nodiscard]] bool IsNoiseSuppressionEnabled() const override; + void NoiseSuppressionProcess(void* buffer, DWORD length); + + void SetNormalizatonEnabled(bool enabled) override; + [[nodiscard]] bool IsNormalizationEnabled() const override; + void Normalize(short* buffer, DWORD length); void SoundFrameCaptured(HRECORD handle, const void* buffer, DWORD length); static BOOL OnSoundFrame(HRECORD handle, const void* buffer, DWORD length, void* user);