diff --git a/internal/runtime/runtime.go b/internal/runtime/runtime.go index 6c8c7cb..05050ee 100644 --- a/internal/runtime/runtime.go +++ b/internal/runtime/runtime.go @@ -15,6 +15,7 @@ type ConfigUpdate struct { TunerBwKHz *int `json:"tuner_bw_khz"` UseGPUFFT *bool `json:"use_gpu_fft"` Detector *DetectorUpdate `json:"detector"` + Recorder *RecorderUpdate `json:"recorder"` } type DetectorUpdate struct { @@ -29,6 +30,21 @@ type SettingsUpdate struct { 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 { mu sync.RWMutex cfg config.Config @@ -71,6 +87,9 @@ func (m *Manager) ApplyConfig(update ConfigUpdate) (config.Config, error) { if *update.FFTSize <= 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 } if update.GainDb != nil { @@ -102,6 +121,44 @@ func (m *Manager) ApplyConfig(update ConfigUpdate) (config.Config, error) { 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 return m.cfg, nil