Wideband autonomous SDR analysis engine forked from sdr-visual-suite
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
1.9KB

  1. package pipeline
  2. import "strings"
  3. // AutoSpanForHint returns a suggested refinement span based on the candidate hint.
  4. // It is intentionally conservative: spans are wide enough for robust demod/classify,
  5. // but not so wide that refinement becomes wasteful.
  6. func AutoSpanForHint(hint string) (float64, string) {
  7. h := strings.ToLower(hint)
  8. switch {
  9. case strings.Contains(h, "wfm"):
  10. return 200000, "auto:wfm"
  11. case strings.Contains(h, "nfm"):
  12. return 18000, "auto:nfm"
  13. case strings.Contains(h, "usb") || strings.Contains(h, "lsb") || strings.Contains(h, "ssb"):
  14. return 6000, "auto:ssb"
  15. case strings.Contains(h, "cw"):
  16. return 500, "auto:cw"
  17. case strings.Contains(h, "dmr") || strings.Contains(h, "d-star") || strings.Contains(h, "dstar"):
  18. return 15000, "auto:dig_voice"
  19. case strings.Contains(h, "ft8") || strings.Contains(h, "wspr"):
  20. return 4000, "auto:dig_weak"
  21. case strings.Contains(h, "fsk") || strings.Contains(h, "psk"):
  22. return 6000, "auto:dig"
  23. case strings.Contains(h, "am"):
  24. return 12000, "auto:am"
  25. default:
  26. return 0, ""
  27. }
  28. }
  29. // RefinementWindowForCandidate applies policy-aware span rules to a candidate.
  30. func RefinementWindowForCandidate(policy Policy, candidate Candidate) RefinementWindow {
  31. span := candidate.BandwidthHz
  32. windowSource := "candidate"
  33. if policy.RefinementAutoSpan && (span <= 0 || span < 2000 || span > 400000) {
  34. autoSpan, autoSource := AutoSpanForHint(candidate.Hint)
  35. if autoSpan > 0 {
  36. span = autoSpan
  37. windowSource = autoSource
  38. }
  39. }
  40. if policy.RefinementMinSpanHz > 0 && span < policy.RefinementMinSpanHz {
  41. span = policy.RefinementMinSpanHz
  42. windowSource = "policy:min_span"
  43. }
  44. if policy.RefinementMaxSpanHz > 0 && span > policy.RefinementMaxSpanHz {
  45. span = policy.RefinementMaxSpanHz
  46. windowSource = "policy:max_span"
  47. }
  48. if span <= 0 {
  49. span = 12000
  50. windowSource = "default"
  51. }
  52. return RefinementWindow{
  53. CenterHz: candidate.CenterHz,
  54. SpanHz: span,
  55. Source: windowSource,
  56. }
  57. }