Skip to content

Commit 55e1cf8

Browse files
committed
test(adaptive): add unit tests for highpass frequency tuning
- Cover voice brightness classification (dark/normal/bright) - Test LUFS gap boost levels (normal/moderate/aggressive) - Verify frequency capping at 120Hz maximum - Include boundary condition tests for threshold values - Handle edge cases: missing spectral data, negative centroid
1 parent 2d11a03 commit 55e1cf8

1 file changed

Lines changed: 147 additions & 0 deletions

File tree

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package processor
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestTuneHighpassFreq(t *testing.T) {
8+
tests := []struct {
9+
name string
10+
centroid float64 // spectral centroid (Hz)
11+
lufsGap float64 // target - input LUFS (dB)
12+
wantFreqMin float64 // minimum expected frequency
13+
wantFreqMax float64 // maximum expected frequency
14+
}{
15+
// Voice brightness classification (normal gain, lufsGap <= 15)
16+
{
17+
name: "dark voice, normal gain",
18+
centroid: 3500, // below centroidNormal (4000)
19+
lufsGap: 10, // below lufsGapModerate (15)
20+
wantFreqMin: 60, // highpassMinFreq
21+
wantFreqMax: 60,
22+
},
23+
{
24+
name: "normal voice, normal gain",
25+
centroid: 5000, // between centroidNormal (4000) and centroidBright (6000)
26+
lufsGap: 10,
27+
wantFreqMin: 80, // highpassDefaultFreq
28+
wantFreqMax: 80,
29+
},
30+
{
31+
name: "bright voice, normal gain",
32+
centroid: 7000, // above centroidBright (6000)
33+
lufsGap: 10,
34+
wantFreqMin: 100, // highpassBrightFreq
35+
wantFreqMax: 100,
36+
},
37+
38+
// LUFS gap boost (moderate: 15-25 dB gap adds 20Hz)
39+
{
40+
name: "dark voice, moderate gain",
41+
centroid: 3500,
42+
lufsGap: 20, // between lufsGapModerate (15) and lufsGapAggressive (25)
43+
wantFreqMin: 80, // 60 + 20
44+
wantFreqMax: 80,
45+
},
46+
{
47+
name: "normal voice, moderate gain",
48+
centroid: 5000,
49+
lufsGap: 20,
50+
wantFreqMin: 100, // 80 + 20
51+
wantFreqMax: 100,
52+
},
53+
{
54+
name: "bright voice, moderate gain",
55+
centroid: 7000,
56+
lufsGap: 20,
57+
wantFreqMin: 120, // 100 + 20, capped at highpassMaxFreq
58+
wantFreqMax: 120,
59+
},
60+
61+
// LUFS gap boost (aggressive: >25 dB gap adds 40Hz)
62+
{
63+
name: "dark voice, aggressive gain",
64+
centroid: 3500,
65+
lufsGap: 30, // above lufsGapAggressive (25)
66+
wantFreqMin: 100, // 60 + 40
67+
wantFreqMax: 100,
68+
},
69+
{
70+
name: "normal voice, aggressive gain",
71+
centroid: 5000,
72+
lufsGap: 30,
73+
wantFreqMin: 120, // 80 + 40, capped at highpassMaxFreq
74+
wantFreqMax: 120,
75+
},
76+
{
77+
name: "bright voice, aggressive gain",
78+
centroid: 7000,
79+
lufsGap: 30,
80+
wantFreqMin: 120, // 100 + 40 = 140, capped at highpassMaxFreq (120)
81+
wantFreqMax: 120,
82+
},
83+
84+
// Edge cases
85+
{
86+
name: "no spectral data - keeps default",
87+
centroid: 0, // triggers early return
88+
lufsGap: 20,
89+
wantFreqMin: 80, // DefaultFilterConfig().HighpassFreq
90+
wantFreqMax: 80,
91+
},
92+
{
93+
name: "negative centroid - keeps default",
94+
centroid: -100,
95+
lufsGap: 10,
96+
wantFreqMin: 80,
97+
wantFreqMax: 80,
98+
},
99+
{
100+
name: "boundary: exactly at centroidNormal",
101+
centroid: 4000, // exactly at centroidNormal threshold
102+
lufsGap: 10,
103+
wantFreqMin: 60, // dark voice (not > centroidNormal)
104+
wantFreqMax: 60,
105+
},
106+
{
107+
name: "boundary: exactly at centroidBright",
108+
centroid: 6000, // exactly at centroidBright threshold
109+
lufsGap: 10,
110+
wantFreqMin: 80, // normal voice (not > centroidBright)
111+
wantFreqMax: 80,
112+
},
113+
{
114+
name: "boundary: exactly at lufsGapModerate",
115+
centroid: 5000,
116+
lufsGap: 15, // exactly at lufsGapModerate threshold
117+
wantFreqMin: 80, // no boost (not > lufsGapModerate)
118+
wantFreqMax: 80,
119+
},
120+
{
121+
name: "boundary: exactly at lufsGapAggressive",
122+
centroid: 5000,
123+
lufsGap: 25, // exactly at lufsGapAggressive threshold
124+
wantFreqMin: 100, // moderate boost (not > lufsGapAggressive)
125+
wantFreqMax: 100,
126+
},
127+
}
128+
129+
for _, tt := range tests {
130+
t.Run(tt.name, func(t *testing.T) {
131+
// Setup: create default config and measurements
132+
config := DefaultFilterConfig()
133+
measurements := &AudioMeasurements{
134+
SpectralCentroid: tt.centroid,
135+
}
136+
137+
// Execute
138+
tuneHighpassFreq(config, measurements, tt.lufsGap)
139+
140+
// Verify
141+
if config.HighpassFreq < tt.wantFreqMin || config.HighpassFreq > tt.wantFreqMax {
142+
t.Errorf("HighpassFreq = %.1f Hz, want [%.1f, %.1f] Hz",
143+
config.HighpassFreq, tt.wantFreqMin, tt.wantFreqMax)
144+
}
145+
})
146+
}
147+
}

0 commit comments

Comments
 (0)