package dsp import ( "math" "testing" ) func TestPreEmphasisBoostsHighFrequency(t *testing.T) { fs := 48000.0 pe := NewPreEmphasis(50, fs) // Generate a low-frequency tone and a high-frequency tone, // measure the energy ratio after pre-emphasis. n := 4800 // 100ms lowFreq := 100.0 highFreq := 10000.0 var lowEnergy, highEnergy float64 for i := 0; i < n; i++ { s := math.Sin(2 * math.Pi * lowFreq * float64(i) / fs) out := pe.Process(s) lowEnergy += out * out } pe.Reset() for i := 0; i < n; i++ { s := math.Sin(2 * math.Pi * highFreq * float64(i) / fs) out := pe.Process(s) highEnergy += out * out } // High frequency should have more energy than low frequency // after pre-emphasis. The input energy is the same for both. ratio := highEnergy / lowEnergy if ratio < 2.0 { t.Fatalf("expected high-freq boost, energy ratio=%.2f", ratio) } } func TestPreEmphasisDeEmphasisRoundtrip(t *testing.T) { fs := 48000.0 pe := NewPreEmphasis(50, fs) de := NewDeEmphasis(50, fs) // Run a 1kHz tone through pre+de, should approximately recover n := 4800 freq := 1000.0 var maxErr float64 // Let filters settle for 200 samples for i := 0; i < 200; i++ { s := math.Sin(2 * math.Pi * freq * float64(i) / fs) de.Process(pe.Process(s)) } for i := 200; i < n; i++ { s := math.Sin(2 * math.Pi * freq * float64(i) / fs) recovered := de.Process(pe.Process(s)) err := math.Abs(recovered - s) if err > maxErr { maxErr = err } } if maxErr > 0.05 { t.Fatalf("roundtrip error too large: %.4f", maxErr) } } func TestDisabledPreEmphasis(t *testing.T) { pe := NewPreEmphasis(0, 48000) if pe.Process(0.5) != 0.5 { t.Fatal("disabled filter should pass through") } }