Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

197 рядки
5.2KB

  1. package runtime
  2. import (
  3. "errors"
  4. "sync"
  5. "sdr-visual-suite/internal/config"
  6. )
  7. type ConfigUpdate struct {
  8. CenterHz *float64 `json:"center_hz"`
  9. SampleRate *int `json:"sample_rate"`
  10. FFTSize *int `json:"fft_size"`
  11. GainDb *float64 `json:"gain_db"`
  12. TunerBwKHz *int `json:"tuner_bw_khz"`
  13. UseGPUFFT *bool `json:"use_gpu_fft"`
  14. Detector *DetectorUpdate `json:"detector"`
  15. Recorder *RecorderUpdate `json:"recorder"`
  16. }
  17. type DetectorUpdate struct {
  18. ThresholdDb *float64 `json:"threshold_db"`
  19. MinDuration *int `json:"min_duration_ms"`
  20. HoldMs *int `json:"hold_ms"`
  21. EmaAlpha *float64 `json:"ema_alpha"`
  22. HysteresisDb *float64 `json:"hysteresis_db"`
  23. }
  24. type SettingsUpdate struct {
  25. AGC *bool `json:"agc"`
  26. DCBlock *bool `json:"dc_block"`
  27. IQBalance *bool `json:"iq_balance"`
  28. }
  29. type RecorderUpdate struct {
  30. Enabled *bool `json:"enabled"`
  31. MinSNRDb *float64 `json:"min_snr_db"`
  32. MinDuration *string `json:"min_duration"`
  33. MaxDuration *string `json:"max_duration"`
  34. PrerollMs *int `json:"preroll_ms"`
  35. RecordIQ *bool `json:"record_iq"`
  36. RecordAudio *bool `json:"record_audio"`
  37. AutoDemod *bool `json:"auto_demod"`
  38. AutoDecode *bool `json:"auto_decode"`
  39. MaxDiskMB *int `json:"max_disk_mb"`
  40. OutputDir *string `json:"output_dir"`
  41. ClassFilter *[]string `json:"class_filter"`
  42. RingSeconds *int `json:"ring_seconds"`
  43. }
  44. type Manager struct {
  45. mu sync.RWMutex
  46. cfg config.Config
  47. }
  48. func New(cfg config.Config) *Manager {
  49. return &Manager{cfg: cfg}
  50. }
  51. func (m *Manager) Snapshot() config.Config {
  52. m.mu.RLock()
  53. defer m.mu.RUnlock()
  54. return m.cfg
  55. }
  56. func (m *Manager) Replace(cfg config.Config) {
  57. m.mu.Lock()
  58. defer m.mu.Unlock()
  59. m.cfg = cfg
  60. }
  61. func (m *Manager) ApplyConfig(update ConfigUpdate) (config.Config, error) {
  62. m.mu.Lock()
  63. defer m.mu.Unlock()
  64. next := m.cfg
  65. if update.CenterHz != nil {
  66. if *update.CenterHz < 1e3 || *update.CenterHz > 2e9 {
  67. return m.cfg, errors.New("center_hz out of range")
  68. }
  69. next.CenterHz = *update.CenterHz
  70. }
  71. if update.SampleRate != nil {
  72. if *update.SampleRate <= 0 {
  73. return m.cfg, errors.New("sample_rate must be > 0")
  74. }
  75. next.SampleRate = *update.SampleRate
  76. }
  77. if update.FFTSize != nil {
  78. if *update.FFTSize <= 0 {
  79. return m.cfg, errors.New("fft_size must be > 0")
  80. }
  81. if *update.FFTSize&(*update.FFTSize-1) != 0 {
  82. return m.cfg, errors.New("fft_size must be a power of 2")
  83. }
  84. next.FFTSize = *update.FFTSize
  85. }
  86. if update.GainDb != nil {
  87. next.GainDb = *update.GainDb
  88. }
  89. if update.TunerBwKHz != nil {
  90. if *update.TunerBwKHz <= 0 {
  91. return m.cfg, errors.New("tuner_bw_khz must be > 0")
  92. }
  93. next.TunerBwKHz = *update.TunerBwKHz
  94. }
  95. if update.UseGPUFFT != nil {
  96. next.UseGPUFFT = *update.UseGPUFFT
  97. }
  98. if update.Detector != nil {
  99. if update.Detector.ThresholdDb != nil {
  100. next.Detector.ThresholdDb = *update.Detector.ThresholdDb
  101. }
  102. if update.Detector.MinDuration != nil {
  103. if *update.Detector.MinDuration <= 0 {
  104. return m.cfg, errors.New("min_duration_ms must be > 0")
  105. }
  106. next.Detector.MinDurationMs = *update.Detector.MinDuration
  107. }
  108. if update.Detector.HoldMs != nil {
  109. if *update.Detector.HoldMs <= 0 {
  110. return m.cfg, errors.New("hold_ms must be > 0")
  111. }
  112. next.Detector.HoldMs = *update.Detector.HoldMs
  113. }
  114. if update.Detector.EmaAlpha != nil {
  115. next.Detector.EmaAlpha = *update.Detector.EmaAlpha
  116. }
  117. if update.Detector.HysteresisDb != nil {
  118. next.Detector.HysteresisDb = *update.Detector.HysteresisDb
  119. }
  120. }
  121. if update.Recorder != nil {
  122. if update.Recorder.Enabled != nil {
  123. next.Recorder.Enabled = *update.Recorder.Enabled
  124. }
  125. if update.Recorder.MinSNRDb != nil {
  126. next.Recorder.MinSNRDb = *update.Recorder.MinSNRDb
  127. }
  128. if update.Recorder.MinDuration != nil {
  129. next.Recorder.MinDuration = *update.Recorder.MinDuration
  130. }
  131. if update.Recorder.MaxDuration != nil {
  132. next.Recorder.MaxDuration = *update.Recorder.MaxDuration
  133. }
  134. if update.Recorder.PrerollMs != nil {
  135. next.Recorder.PrerollMs = *update.Recorder.PrerollMs
  136. }
  137. if update.Recorder.RecordIQ != nil {
  138. next.Recorder.RecordIQ = *update.Recorder.RecordIQ
  139. }
  140. if update.Recorder.RecordAudio != nil {
  141. next.Recorder.RecordAudio = *update.Recorder.RecordAudio
  142. }
  143. if update.Recorder.AutoDemod != nil {
  144. next.Recorder.AutoDemod = *update.Recorder.AutoDemod
  145. }
  146. if update.Recorder.AutoDecode != nil {
  147. next.Recorder.AutoDecode = *update.Recorder.AutoDecode
  148. }
  149. if update.Recorder.MaxDiskMB != nil {
  150. next.Recorder.MaxDiskMB = *update.Recorder.MaxDiskMB
  151. }
  152. if update.Recorder.OutputDir != nil {
  153. next.Recorder.OutputDir = *update.Recorder.OutputDir
  154. }
  155. if update.Recorder.ClassFilter != nil {
  156. next.Recorder.ClassFilter = *update.Recorder.ClassFilter
  157. }
  158. if update.Recorder.RingSeconds != nil {
  159. next.Recorder.RingSeconds = *update.Recorder.RingSeconds
  160. }
  161. }
  162. m.cfg = next
  163. return m.cfg, nil
  164. }
  165. func (m *Manager) ApplySettings(update SettingsUpdate) (config.Config, error) {
  166. m.mu.Lock()
  167. defer m.mu.Unlock()
  168. next := m.cfg
  169. if update.AGC != nil {
  170. next.AGC = *update.AGC
  171. }
  172. if update.DCBlock != nil {
  173. next.DCBlock = *update.DCBlock
  174. }
  175. if update.IQBalance != nil {
  176. next.IQBalance = *update.IQBalance
  177. }
  178. m.cfg = next
  179. return m.cfg, nil
  180. }