Noise suppression tweaks.

This commit is contained in:
Storm Dragon
2026-02-21 02:08:55 -05:00
parent 3db526f42b
commit e84cb67500

103
noise/suppression_test.go Normal file
View File

@@ -0,0 +1,103 @@
package noise
import (
"math"
"testing"
)
func TestSuppressorDisabledBypassesSamples(t *testing.T) {
suppressor := NewSuppressor()
samples := []int16{100, -200, 300, -400, 500}
original := append([]int16(nil), samples...)
suppressor.ProcessSamples(samples)
for i := range samples {
if samples[i] != original[i] {
t.Fatalf("expected sample %d to remain unchanged, got %d want %d", i, samples[i], original[i])
}
}
}
func TestSuppressorAttenuatesLowLevelNoise(t *testing.T) {
suppressor := NewSuppressor()
suppressor.SetEnabled(true)
suppressor.SetThreshold(0.08)
input := makeSineFrame(600, 700)
originalRMS := frameRMS(input)
processed := append([]int16(nil), input...)
suppressor.ProcessSamples(processed)
processedRMS := frameRMS(processed)
if processedRMS >= originalRMS*0.8 {
t.Fatalf("expected low-level noise attenuation, got RMS %.2f from %.2f", processedRMS, originalRMS)
}
}
func TestSuppressorPreservesSpeechLikeSignal(t *testing.T) {
suppressor := NewSuppressor()
suppressor.SetEnabled(true)
suppressor.SetThreshold(0.08)
voice := makeSineFrame(1000, 9000)
originalRMS := frameRMS(voice)
processed := append([]int16(nil), voice...)
suppressor.ProcessSamples(processed)
processedRMS := frameRMS(processed)
if processedRMS <= originalRMS*0.6 {
t.Fatalf("expected speech-like signal to be mostly preserved, got RMS %.2f from %.2f", processedRMS, originalRMS)
}
}
func TestHigherThresholdAppliesStrongerSuppression(t *testing.T) {
lowSuppressor := NewSuppressor()
lowSuppressor.SetEnabled(true)
lowSuppressor.SetThreshold(0.02)
highSuppressor := NewSuppressor()
highSuppressor.SetEnabled(true)
highSuppressor.SetThreshold(0.20)
noiseFrame := makeSineFrame(500, 700)
lowRMS := runFrameWarmup(lowSuppressor, noiseFrame, 8)
highRMS := runFrameWarmup(highSuppressor, noiseFrame, 8)
if highRMS >= lowRMS*0.8 {
t.Fatalf("expected stronger suppression at higher threshold, got low %.2f high %.2f", lowRMS, highRMS)
}
}
func runFrameWarmup(suppressor *Suppressor, frame []int16, repeats int) float64 {
var processed []int16
for i := 0; i < repeats; i++ {
processed = append([]int16(nil), frame...)
suppressor.ProcessSamples(processed)
}
return frameRMS(processed)
}
func makeSineFrame(frequency float64, amplitude float64) []int16 {
const sampleRate = 48000.0
const frameSize = 480
frame := make([]int16, frameSize)
for i := 0; i < frameSize; i++ {
value := math.Sin((2.0 * math.Pi * frequency * float64(i)) / sampleRate)
frame[i] = int16(value * amplitude)
}
return frame
}
func frameRMS(samples []int16) float64 {
if len(samples) == 0 {
return 0.0
}
var sumSquares float64
for _, sample := range samples {
normalized := float64(sample) / 32768.0
sumSquares += normalized * normalized
}
return math.Sqrt(sumSquares / float64(len(samples)))
}