| @@ -15,6 +15,7 @@ type ConfigUpdate struct { | |||||
| TunerBwKHz *int `json:"tuner_bw_khz"` | TunerBwKHz *int `json:"tuner_bw_khz"` | ||||
| UseGPUFFT *bool `json:"use_gpu_fft"` | UseGPUFFT *bool `json:"use_gpu_fft"` | ||||
| Detector *DetectorUpdate `json:"detector"` | Detector *DetectorUpdate `json:"detector"` | ||||
| Recorder *RecorderUpdate `json:"recorder"` | |||||
| } | } | ||||
| type DetectorUpdate struct { | type DetectorUpdate struct { | ||||
| @@ -29,6 +30,21 @@ type SettingsUpdate struct { | |||||
| IQBalance *bool `json:"iq_balance"` | IQBalance *bool `json:"iq_balance"` | ||||
| } | } | ||||
| type RecorderUpdate struct { | |||||
| Enabled *bool `json:"enabled"` | |||||
| MinSNRDb *float64 `json:"min_snr_db"` | |||||
| MinDuration *string `json:"min_duration"` | |||||
| MaxDuration *string `json:"max_duration"` | |||||
| PrerollMs *int `json:"preroll_ms"` | |||||
| RecordIQ *bool `json:"record_iq"` | |||||
| RecordAudio *bool `json:"record_audio"` | |||||
| AutoDemod *bool `json:"auto_demod"` | |||||
| AutoDecode *bool `json:"auto_decode"` | |||||
| OutputDir *string `json:"output_dir"` | |||||
| ClassFilter *[]string `json:"class_filter"` | |||||
| RingSeconds *int `json:"ring_seconds"` | |||||
| } | |||||
| type Manager struct { | type Manager struct { | ||||
| mu sync.RWMutex | mu sync.RWMutex | ||||
| cfg config.Config | cfg config.Config | ||||
| @@ -71,6 +87,9 @@ func (m *Manager) ApplyConfig(update ConfigUpdate) (config.Config, error) { | |||||
| if *update.FFTSize <= 0 { | if *update.FFTSize <= 0 { | ||||
| return m.cfg, errors.New("fft_size must be > 0") | return m.cfg, errors.New("fft_size must be > 0") | ||||
| } | } | ||||
| if *update.FFTSize&(*update.FFTSize-1) != 0 { | |||||
| return m.cfg, errors.New("fft_size must be a power of 2") | |||||
| } | |||||
| next.FFTSize = *update.FFTSize | next.FFTSize = *update.FFTSize | ||||
| } | } | ||||
| if update.GainDb != nil { | if update.GainDb != nil { | ||||
| @@ -102,6 +121,44 @@ func (m *Manager) ApplyConfig(update ConfigUpdate) (config.Config, error) { | |||||
| next.Detector.HoldMs = *update.Detector.HoldMs | next.Detector.HoldMs = *update.Detector.HoldMs | ||||
| } | } | ||||
| } | } | ||||
| if update.Recorder != nil { | |||||
| if update.Recorder.Enabled != nil { | |||||
| next.Recorder.Enabled = *update.Recorder.Enabled | |||||
| } | |||||
| if update.Recorder.MinSNRDb != nil { | |||||
| next.Recorder.MinSNRDb = *update.Recorder.MinSNRDb | |||||
| } | |||||
| if update.Recorder.MinDuration != nil { | |||||
| next.Recorder.MinDuration = *update.Recorder.MinDuration | |||||
| } | |||||
| if update.Recorder.MaxDuration != nil { | |||||
| next.Recorder.MaxDuration = *update.Recorder.MaxDuration | |||||
| } | |||||
| if update.Recorder.PrerollMs != nil { | |||||
| next.Recorder.PrerollMs = *update.Recorder.PrerollMs | |||||
| } | |||||
| if update.Recorder.RecordIQ != nil { | |||||
| next.Recorder.RecordIQ = *update.Recorder.RecordIQ | |||||
| } | |||||
| if update.Recorder.RecordAudio != nil { | |||||
| next.Recorder.RecordAudio = *update.Recorder.RecordAudio | |||||
| } | |||||
| if update.Recorder.AutoDemod != nil { | |||||
| next.Recorder.AutoDemod = *update.Recorder.AutoDemod | |||||
| } | |||||
| if update.Recorder.AutoDecode != nil { | |||||
| next.Recorder.AutoDecode = *update.Recorder.AutoDecode | |||||
| } | |||||
| if update.Recorder.OutputDir != nil { | |||||
| next.Recorder.OutputDir = *update.Recorder.OutputDir | |||||
| } | |||||
| if update.Recorder.ClassFilter != nil { | |||||
| next.Recorder.ClassFilter = *update.Recorder.ClassFilter | |||||
| } | |||||
| if update.Recorder.RingSeconds != nil { | |||||
| next.Recorder.RingSeconds = *update.Recorder.RingSeconds | |||||
| } | |||||
| } | |||||
| m.cfg = next | m.cfg = next | ||||
| return m.cfg, nil | return m.cfg, nil | ||||