You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
1.5KB

  1. package classifier
  2. import (
  3. "math"
  4. "testing"
  5. )
  6. func TestHardRulesFMBroadcast(t *testing.T) {
  7. cls := TryHardRule(100.0e6, 120000)
  8. if cls == nil {
  9. t.Fatal("expected hard rule match for FM broadcast")
  10. }
  11. if cls.ModType != ClassWFM {
  12. t.Errorf("expected WFM, got %s", cls.ModType)
  13. }
  14. if cls.Confidence < 0.95 {
  15. t.Errorf("confidence too low: %.2f", cls.Confidence)
  16. }
  17. cls2 := TryHardRule(434.0e6, 120000)
  18. if cls2 == nil || cls2.ModType != ClassWFM {
  19. t.Errorf("expected WFM for >100kHz signal")
  20. }
  21. }
  22. func TestHardRulesAirband(t *testing.T) {
  23. cls := TryHardRule(121.5e6, 8000)
  24. if cls == nil || cls.ModType != ClassAM {
  25. t.Fatalf("expected AM for airband, got %v", cls)
  26. }
  27. }
  28. func TestHardRulesCW(t *testing.T) {
  29. cls := TryHardRule(7.020e6, 100)
  30. if cls == nil || cls.ModType != ClassCW {
  31. t.Fatalf("expected CW for <500Hz, got %v", cls)
  32. }
  33. }
  34. func TestWFMPilotDetection(t *testing.T) {
  35. sampleRate := 192000
  36. n := sampleRate * 2
  37. iq := make([]complex64, n)
  38. phase := 0.0
  39. for i := range iq {
  40. pilot := math.Sin(2 * math.Pi * 19000 * float64(i) / float64(sampleRate))
  41. modulation := pilot * 0.1
  42. freqDev := modulation * 75000 / float64(sampleRate)
  43. phase += 2 * math.Pi * freqDev
  44. iq[i] = complex(float32(math.Cos(phase)), float32(math.Sin(phase)))
  45. }
  46. result := EstimateExactFrequency(iq, sampleRate, 102.1e6, ClassWFM)
  47. if !result.Locked {
  48. t.Fatal("PLL should lock on pilot")
  49. }
  50. if math.Abs(result.OffsetHz) > 5 {
  51. t.Errorf("offset too large: %.1f Hz", result.OffsetHz)
  52. }
  53. }