|
- 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")
- }
- }
|