Go-based FM stereo transmitter with RDS, Windows-first and cross-platform
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

83 Zeilen
2.0KB

  1. package stereo
  2. import (
  3. "math"
  4. "testing"
  5. "github.com/jan/fm-rds-tx/internal/audio"
  6. )
  7. func TestStereoEncoderEncode(t *testing.T) {
  8. enc := NewStereoEncoder(228000)
  9. frame := audio.NewFrame(1, -1)
  10. result := enc.Encode(frame)
  11. if diff := result.Mono; math.Abs(diff) > 1e-9 {
  12. t.Fatalf("expected mono 0, got %v", diff)
  13. }
  14. // Stereo should be non-zero for L!=R input
  15. // (exact value depends on oscillator phase at sample 0)
  16. // We just verify it's modulated (could be zero at phase=0 for sin)
  17. // Run a few samples and check some are non-zero
  18. var maxStereo float64
  19. for i := 0; i < 100; i++ {
  20. c := enc.Encode(frame)
  21. if math.Abs(c.Stereo) > maxStereo {
  22. maxStereo = math.Abs(c.Stereo)
  23. }
  24. }
  25. if maxStereo < 0.1 {
  26. t.Fatalf("expected non-trivial stereo signal, maxStereo=%.6f", maxStereo)
  27. }
  28. }
  29. func TestStereoEncoderMonoSignal(t *testing.T) {
  30. enc := NewStereoEncoder(228000)
  31. // Identical L and R should produce zero difference/stereo
  32. frame := audio.NewFrame(0.5, 0.5)
  33. for i := 0; i < 100; i++ {
  34. c := enc.Encode(frame)
  35. if math.Abs(c.Stereo) > 1e-12 {
  36. t.Fatalf("expected zero stereo for mono input, got %.9f", c.Stereo)
  37. }
  38. if math.Abs(c.Mono-0.5) > 1e-9 {
  39. t.Fatalf("expected mono=0.5, got %.9f", c.Mono)
  40. }
  41. }
  42. }
  43. func TestStereoEncoderPilotRange(t *testing.T) {
  44. enc := NewStereoEncoder(228000)
  45. frame := audio.NewFrame(0.1, -0.1)
  46. for i := 0; i < 1000; i++ {
  47. c := enc.Encode(frame)
  48. if c.Pilot < -0.101 || c.Pilot > 0.101 {
  49. t.Fatalf("pilot out of range: %.6f", c.Pilot)
  50. }
  51. }
  52. }
  53. func TestStereoEncoderReset(t *testing.T) {
  54. frame := audio.NewFrame(0.1, -0.1)
  55. enc := NewStereoEncoder(228000)
  56. initial := make([]float64, 0, 4)
  57. for i := 0; i < 4; i++ {
  58. initial = append(initial, enc.Encode(frame).Pilot)
  59. }
  60. enc.Reset()
  61. afterReset := make([]float64, 0, 4)
  62. for i := 0; i < 4; i++ {
  63. afterReset = append(afterReset, enc.Encode(frame).Pilot)
  64. }
  65. for i := range initial {
  66. if math.Abs(initial[i]-afterReset[i]) > 1e-9 {
  67. t.Fatalf("reset failed at sample %d: %v vs %v", i, initial[i], afterReset[i])
  68. }
  69. }
  70. }