From 227976f379f2f030677e715ff6aa01f940360870 Mon Sep 17 00:00:00 2001 From: Yauhen Pahrabniak Date: Wed, 25 Oct 2023 16:18:59 +0200 Subject: [PATCH] Smooth gain for normalization --- src/CSoundInput.cpp | 32 +++++++++++++++++++++++--------- src/CSoundInput.h | 1 + 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/CSoundInput.cpp b/src/CSoundInput.cpp index fe15b07..4c744d0 100644 --- a/src/CSoundInput.cpp +++ b/src/CSoundInput.cpp @@ -288,29 +288,43 @@ bool CSoundInput::IsNormalizationEnabled() const return normalizationEnabled; } -void CSoundInput::Normalize(void* buffer, DWORD length) +void CSoundInput::Normalize(void* buffer, DWORD sampleCount) { short maxFrame = 0; - for (int i = 0; i < length; ++i) + for (int i = 0; i < sampleCount; ++i) { short s = abs(((short*)buffer)[i]); if (s > maxFrame) maxFrame = s; } - if (normalizeMax == 0.f || maxFrame > normalizeMax || normalizeMax / maxFrame < 0.5) + // Update normalizeMax using a running average or directly based on conditions + if (normalizeMax == 0.f || maxFrame > normalizeMax || normalizeMax / maxFrame < 0.5) { normalizeMax = maxFrame; - else + } + else { normalizeMax = (normalizeMax * (NORMALIZE_FRAME_COUNT - 1) + maxFrame) / NORMALIZE_FRAME_COUNT; + } - if (normalizeMax <= 1.f) + if (normalizeMax <= 1.f) { return; + } + + float desiredGain = MAXSHORT / normalizeMax / 2; + desiredGain = std::fmin(desiredGain, 10.0f); - float gain = MAXSHORT / normalizeMax / 2; - gain = std::fmin(gain, 10); + // Smooth the transition of gain + static float currentGain = 1.0f; + float smoothingFactor = 0.05f; + currentNormalizationGain = (1 - smoothingFactor) * currentNormalizationGain + smoothingFactor * desiredGain; - for (int i = 0; i < length; ++i) - ((short*)buffer)[i] *= gain; + const auto shortSamples = static_cast(buffer); + + for (int i = 0; i < sampleCount; ++i) + { + float processedSample = (float)shortSamples[i] * currentGain; + shortSamples[i] = static_cast(clampFloatSample(processedSample)); + } } void CSoundInput::NormalizeDSP(HDSP handle, DWORD channel, void* buffer, DWORD length, void* user) diff --git a/src/CSoundInput.h b/src/CSoundInput.h index 4441ba4..ea6936e 100644 --- a/src/CSoundInput.h +++ b/src/CSoundInput.h @@ -22,6 +22,7 @@ class CSoundInput : public ISoundInput float volume = 1.f; float micLevel = 0.f; float micLevelDb = 0.f; + float currentNormalizationGain = 1.f; bool noiseSuppressionEnabled = false; bool normalizationEnabled = false;