Wideband autonomous SDR analysis engine forked from sdr-visual-suite
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.

131 lines
4.7KB

  1. package main
  2. import (
  3. "sync"
  4. "time"
  5. "github.com/gorilla/websocket"
  6. "sdr-wideband-suite/internal/config"
  7. "sdr-wideband-suite/internal/demod/gpudemod"
  8. "sdr-wideband-suite/internal/detector"
  9. "sdr-wideband-suite/internal/pipeline"
  10. "sdr-wideband-suite/internal/sdr"
  11. "sdr-wideband-suite/internal/telemetry"
  12. )
  13. type SpectrumDebug struct {
  14. Thresholds []float64 `json:"thresholds,omitempty"`
  15. NoiseFloor float64 `json:"noise_floor,omitempty"`
  16. Scores []map[string]any `json:"scores,omitempty"`
  17. CandidateSources map[string]int `json:"candidate_sources,omitempty"`
  18. CandidateEvidence []CandidateEvidenceSummary `json:"candidate_evidence,omitempty"`
  19. CandidateEvidenceStates *CandidateEvidenceStateSummary `json:"candidate_evidence_states,omitempty"`
  20. CandidateWindows []CandidateWindowSummary `json:"candidate_windows,omitempty"`
  21. MonitorWindowStats []pipeline.MonitorWindowStats `json:"monitor_window_stats,omitempty"`
  22. WindowSummary *WindowSummary `json:"window_summary,omitempty"`
  23. RefinementPlan *pipeline.RefinementPlan `json:"refinement_plan,omitempty"`
  24. Windows *RefinementWindowStats `json:"refinement_windows,omitempty"`
  25. Refinement *RefinementDebug `json:"refinement,omitempty"`
  26. Decisions *DecisionDebug `json:"decisions,omitempty"`
  27. }
  28. type RefinementWindowStats struct {
  29. Count int `json:"count"`
  30. MinSpan float64 `json:"min_span_hz"`
  31. MaxSpan float64 `json:"max_span_hz"`
  32. AvgSpan float64 `json:"avg_span_hz"`
  33. Sources map[string]int `json:"sources,omitempty"`
  34. }
  35. type RefinementDebug struct {
  36. Plan *pipeline.RefinementPlan `json:"plan,omitempty"`
  37. Request *pipeline.RefinementRequest `json:"request,omitempty"`
  38. WorkItems []pipeline.RefinementWorkItem `json:"work_items,omitempty"`
  39. Windows *RefinementWindowStats `json:"windows,omitempty"`
  40. MonitorWindowStats []pipeline.MonitorWindowStats `json:"monitor_window_stats,omitempty"`
  41. WindowSummary *WindowSummary `json:"window_summary,omitempty"`
  42. Arbitration *ArbitrationSnapshot `json:"arbitration,omitempty"`
  43. }
  44. type DecisionDebug struct {
  45. Summary decisionSummary `json:"summary"`
  46. Items []compactDecision `json:"items,omitempty"`
  47. }
  48. type ArbitrationSnapshot struct {
  49. Budgets *pipeline.BudgetModel `json:"budgets,omitempty"`
  50. HoldPolicy *pipeline.HoldPolicy `json:"hold_policy,omitempty"`
  51. RefinementAdmission *pipeline.RefinementAdmission `json:"refinement_admission,omitempty"`
  52. Queue pipeline.DecisionQueueStats `json:"queue,omitempty"`
  53. Pressure *pipeline.BudgetPressureSummary `json:"pressure,omitempty"`
  54. Rebalance *pipeline.BudgetRebalance `json:"rebalance,omitempty"`
  55. DecisionSummary decisionSummary `json:"decision_summary,omitempty"`
  56. DecisionItems []compactDecision `json:"decision_items,omitempty"`
  57. }
  58. type SpectrumFrame struct {
  59. Timestamp int64 `json:"ts"`
  60. CenterHz float64 `json:"center_hz"`
  61. SampleHz int `json:"sample_rate"`
  62. FFTSize int `json:"fft_size"`
  63. Spectrum []float64 `json:"spectrum_db"`
  64. Signals []detector.Signal `json:"signals"`
  65. Debug *SpectrumDebug `json:"debug,omitempty"`
  66. }
  67. type client struct {
  68. conn *websocket.Conn
  69. send chan []byte
  70. done chan struct{}
  71. closeOnce sync.Once
  72. // Per-client settings (set via initial config message)
  73. binary bool // send binary spectrum frames instead of JSON
  74. maxBins int // target bin count (0 = full resolution)
  75. targetFps int // target frame rate (0 = full rate)
  76. frameSkip int // skip counter: send every N-th frame
  77. frameN int // current frame counter
  78. }
  79. type hub struct {
  80. mu sync.Mutex
  81. clients map[*client]struct{}
  82. frameCnt int64
  83. lastLogTs time.Time
  84. }
  85. type gpuStatus struct {
  86. mu sync.RWMutex
  87. Available bool `json:"available"`
  88. Active bool `json:"active"`
  89. Error string `json:"error"`
  90. }
  91. type signalSnapshot struct {
  92. mu sync.RWMutex
  93. signals []detector.Signal
  94. }
  95. type sourceManager struct {
  96. mu sync.RWMutex
  97. src sdr.Source
  98. newSource func(cfg config.Config) (sdr.Source, error)
  99. telemetry *telemetry.Collector
  100. }
  101. type extractionManager struct {
  102. mu sync.Mutex
  103. runner *gpudemod.BatchRunner
  104. maxSamples int
  105. }
  106. type dspUpdate struct {
  107. cfg config.Config
  108. det *detector.Detector
  109. window []float64
  110. dcBlock bool
  111. iqBalance bool
  112. useGPUFFT bool
  113. }