From b7dffa8d2630c49e97af50345130569232062c7b Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 12 Apr 2026 13:12:15 +0200 Subject: [PATCH] test(stereo): cover mono delay compensation Add regression coverage for SSB/VSB mono delay compensation, confirm DSB mono remains immediate, and verify Reset clears the delay state before reuse. --- internal/stereo/delay_test.go | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 internal/stereo/delay_test.go diff --git a/internal/stereo/delay_test.go b/internal/stereo/delay_test.go new file mode 100644 index 0000000..0b373ca --- /dev/null +++ b/internal/stereo/delay_test.go @@ -0,0 +1,60 @@ +package stereo + +import ( + "math" + "testing" + + "github.com/jan/fm-rds-tx/internal/audio" +) + +func TestSSBAndVSBDelayMonoToMatchDiffPath(t *testing.T) { + const sampleRate = 228000 + const wantDelay = (ssbHilbertTaps - 1) / 2 + + for _, mode := range []Mode{ModeSSB, ModeVSB} { + enc := NewStereoEncoder(sampleRate) + enc.SetMode(mode, sampleRate) + + for i := 0; i < wantDelay; i++ { + c := enc.Encode(audio.NewFrame(1, 1)) + if math.Abs(c.Mono) > 1e-12 { + t.Fatalf("mode %s: mono leaked before delay filled at sample %d: got %.9f want 0", mode, i, c.Mono) + } + } + + c := enc.Encode(audio.NewFrame(1, 1)) + if math.Abs(c.Mono-1) > 1e-12 { + t.Fatalf("mode %s: mono did not emerge after expected delay: got %.9f want 1", mode, c.Mono) + } + } +} + +func TestDSBMonoRemainsUndelayed(t *testing.T) { + enc := NewStereoEncoder(228000) + enc.SetMode(ModeDSB, 228000) + c := enc.Encode(audio.NewFrame(1, 1)) + if math.Abs(c.Mono-1) > 1e-12 { + t.Fatalf("DSB mono should be immediate: got %.9f want 1", c.Mono) + } +} + +func TestResetClearsMonoDelayState(t *testing.T) { + const sampleRate = 228000 + const wantDelay = (ssbHilbertTaps - 1) / 2 + + enc := NewStereoEncoder(sampleRate) + enc.SetMode(ModeSSB, sampleRate) + + for i := 0; i < wantDelay+4; i++ { + _ = enc.Encode(audio.NewFrame(1, 1)) + } + + enc.Reset() + + for i := 0; i < wantDelay; i++ { + c := enc.Encode(audio.NewFrame(1, 1)) + if math.Abs(c.Mono) > 1e-12 { + t.Fatalf("reset did not clear mono delay at sample %d: got %.9f want 0", i, c.Mono) + } + } +}