|
- package classifier
-
- import (
- "math"
- "testing"
- )
-
- func TestHardRulesFMBroadcast(t *testing.T) {
- cls := TryHardRule(100.0e6, 120000)
- if cls == nil {
- t.Fatal("expected hard rule match for FM broadcast")
- }
- if cls.ModType != ClassWFM {
- t.Errorf("expected WFM, got %s", cls.ModType)
- }
- if cls.Confidence < 0.95 {
- t.Errorf("confidence too low: %.2f", cls.Confidence)
- }
- cls2 := TryHardRule(434.0e6, 120000)
- if cls2 == nil || cls2.ModType != ClassWFM {
- t.Errorf("expected WFM for >100kHz signal")
- }
- }
-
- func TestHardRulesAirband(t *testing.T) {
- cls := TryHardRule(121.5e6, 8000)
- if cls == nil || cls.ModType != ClassAM {
- t.Fatalf("expected AM for airband, got %v", cls)
- }
- }
-
- func TestHardRulesCW(t *testing.T) {
- cls := TryHardRule(7.020e6, 100)
- if cls == nil || cls.ModType != ClassCW {
- t.Fatalf("expected CW for <500Hz, got %v", cls)
- }
- }
-
- func TestWFMPilotDetection(t *testing.T) {
- sampleRate := 192000
- n := sampleRate * 2
- iq := make([]complex64, n)
- phase := 0.0
- for i := range iq {
- pilot := math.Sin(2 * math.Pi * 19000 * float64(i) / float64(sampleRate))
- modulation := pilot * 0.1
- freqDev := modulation * 75000 / float64(sampleRate)
- phase += 2 * math.Pi * freqDev
- iq[i] = complex(float32(math.Cos(phase)), float32(math.Sin(phase)))
- }
- result := EstimateExactFrequency(iq, sampleRate, 102.1e6, ClassWFM)
- if !result.Locked {
- t.Fatal("PLL should lock on pilot")
- }
- if math.Abs(result.OffsetHz) > 5 {
- t.Errorf("offset too large: %.1f Hz", result.OffsetHz)
- }
- }
|