package stereo import ( "math" "testing" "github.com/jan/fm-rds-tx/internal/audio" ) func TestStereoEncoderEncode(t *testing.T) { enc := NewStereoEncoder(228000) frame := audio.NewFrame(1, -1) result := enc.Encode(frame) if diff := result.Mono; math.Abs(diff) > 1e-9 { t.Fatalf("expected mono 0, got %v", diff) } // Stereo should be non-zero for L!=R input // (exact value depends on oscillator phase at sample 0) // We just verify it's modulated (could be zero at phase=0 for sin) // Run a few samples and check some are non-zero var maxStereo float64 for i := 0; i < 100; i++ { c := enc.Encode(frame) if math.Abs(c.Stereo) > maxStereo { maxStereo = math.Abs(c.Stereo) } } if maxStereo < 0.1 { t.Fatalf("expected non-trivial stereo signal, maxStereo=%.6f", maxStereo) } } func TestStereoEncoderMonoSignal(t *testing.T) { enc := NewStereoEncoder(228000) // Identical L and R should produce zero difference/stereo frame := audio.NewFrame(0.5, 0.5) for i := 0; i < 100; i++ { c := enc.Encode(frame) if math.Abs(c.Stereo) > 1e-12 { t.Fatalf("expected zero stereo for mono input, got %.9f", c.Stereo) } if math.Abs(c.Mono-0.5) > 1e-9 { t.Fatalf("expected mono=0.5, got %.9f", c.Mono) } } } func TestStereoEncoderPilotRange(t *testing.T) { enc := NewStereoEncoder(228000) frame := audio.NewFrame(0.1, -0.1) for i := 0; i < 1000; i++ { c := enc.Encode(frame) if c.Pilot < -0.101 || c.Pilot > 0.101 { t.Fatalf("pilot out of range: %.6f", c.Pilot) } } } func TestStereoEncoderReset(t *testing.T) { frame := audio.NewFrame(0.1, -0.1) enc := NewStereoEncoder(228000) initial := make([]float64, 0, 4) for i := 0; i < 4; i++ { initial = append(initial, enc.Encode(frame).Pilot) } enc.Reset() afterReset := make([]float64, 0, 4) for i := 0; i < 4; i++ { afterReset = append(afterReset, enc.Encode(frame).Pilot) } for i := range initial { if math.Abs(initial[i]-afterReset[i]) > 1e-9 { t.Fatalf("reset failed at sample %d: %v vs %v", i, initial[i], afterReset[i]) } } }