Преглед на файлове

feat: capture phase snapshots for API

master
Jan Svabenik преди 7 часа
родител
ревизия
831119c369
променени са 4 файла, в които са добавени 51 реда и са изтрити 22 реда
  1. +6
    -1
      cmd/sdrd/dsp_loop.go
  2. +3
    -3
      cmd/sdrd/http_handlers.go
  3. +15
    -18
      cmd/sdrd/main.go
  4. +27
    -0
      cmd/sdrd/phase_snapshot.go

+ 6
- 1
cmd/sdrd/dsp_loop.go Целия файл

@@ -13,10 +13,11 @@ import (
"sdr-wideband-suite/internal/config"
"sdr-wideband-suite/internal/detector"
"sdr-wideband-suite/internal/dsp"
"sdr-wideband-suite/internal/pipeline"
"sdr-wideband-suite/internal/recorder"
)

func runDSP(ctx context.Context, srcMgr *sourceManager, cfg config.Config, det *detector.Detector, window []float64, h *hub, eventFile *os.File, eventMu *sync.RWMutex, updates <-chan dspUpdate, gpuState *gpuStatus, rec *recorder.Manager, sigSnap *signalSnapshot, extractMgr *extractionManager) {
func runDSP(ctx context.Context, srcMgr *sourceManager, cfg config.Config, det *detector.Detector, window []float64, h *hub, eventFile *os.File, eventMu *sync.RWMutex, updates <-chan dspUpdate, gpuState *gpuStatus, rec *recorder.Manager, sigSnap *signalSnapshot, extractMgr *extractionManager, phaseSnap *phaseSnapshot) {
defer func() {
if r := recover(); r != nil {
log.Printf("FATAL: runDSP goroutine panic: %v\n%s", r, debug.Stack())
@@ -88,8 +89,12 @@ func runDSP(ctx context.Context, srcMgr *sourceManager, cfg config.Config, det *
}
rt.maintenance(displaySignals, rec)
} else {
state.refinement = pipeline.RefinementResult{}
displaySignals = rt.det.StableSignals()
}
if phaseSnap != nil {
phaseSnap.Set(*state)
}

if sigSnap != nil {
sigSnap.set(displaySignals)


+ 3
- 3
cmd/sdrd/http_handlers.go Целия файл

@@ -21,7 +21,7 @@ import (
"sdr-wideband-suite/internal/runtime"
)

func registerAPIHandlers(mux *http.ServeMux, cfgPath string, cfgManager *runtime.Manager, srcMgr *sourceManager, dspUpdates chan dspUpdate, gpuState *gpuStatus, recMgr *recorder.Manager, sigSnap *signalSnapshot, eventMu *sync.RWMutex) {
func registerAPIHandlers(mux *http.ServeMux, cfgPath string, cfgManager *runtime.Manager, srcMgr *sourceManager, dspUpdates chan dspUpdate, gpuState *gpuStatus, recMgr *recorder.Manager, sigSnap *signalSnapshot, eventMu *sync.RWMutex, phaseSnap *phaseSnapshot) {
mux.HandleFunc("/api/config", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
switch r.Method {
@@ -291,10 +291,10 @@ func registerAPIHandlers(mux *http.ServeMux, cfgPath string, cfgManager *runtime
})
}

func newHTTPServer(addr string, webRoot string, h *hub, cfgPath string, cfgManager *runtime.Manager, srcMgr *sourceManager, dspUpdates chan dspUpdate, gpuState *gpuStatus, recMgr *recorder.Manager, sigSnap *signalSnapshot, eventMu *sync.RWMutex) *http.Server {
func newHTTPServer(addr string, webRoot string, h *hub, cfgPath string, cfgManager *runtime.Manager, srcMgr *sourceManager, dspUpdates chan dspUpdate, gpuState *gpuStatus, recMgr *recorder.Manager, sigSnap *signalSnapshot, eventMu *sync.RWMutex, phaseSnap *phaseSnapshot) *http.Server {
mux := http.NewServeMux()
registerWSHandlers(mux, h, recMgr)
registerAPIHandlers(mux, cfgPath, cfgManager, srcMgr, dspUpdates, gpuState, recMgr, sigSnap, eventMu)
registerAPIHandlers(mux, cfgPath, cfgManager, srcMgr, dspUpdates, gpuState, recMgr, sigSnap, eventMu, phaseSnap)
mux.Handle("/", http.FileServer(http.Dir(webRoot)))
return &http.Server{Addr: addr, Handler: mux}
}


+ 15
- 18
cmd/sdrd/main.go Целия файл

@@ -97,18 +97,18 @@ func main() {

decodeMap := buildDecoderMap(cfg)
recMgr := recorder.New(cfg.SampleRate, cfg.FFTSize, recorder.Policy{
Enabled: cfg.Recorder.Enabled,
MinSNRDb: cfg.Recorder.MinSNRDb,
MinDuration: mustParseDuration(cfg.Recorder.MinDuration, 1*time.Second),
MaxDuration: mustParseDuration(cfg.Recorder.MaxDuration, 300*time.Second),
PrerollMs: cfg.Recorder.PrerollMs,
RecordIQ: cfg.Recorder.RecordIQ,
RecordAudio: cfg.Recorder.RecordAudio,
AutoDemod: cfg.Recorder.AutoDemod,
AutoDecode: cfg.Recorder.AutoDecode,
MaxDiskMB: cfg.Recorder.MaxDiskMB,
OutputDir: cfg.Recorder.OutputDir,
ClassFilter: cfg.Recorder.ClassFilter,
Enabled: cfg.Recorder.Enabled,
MinSNRDb: cfg.Recorder.MinSNRDb,
MinDuration: mustParseDuration(cfg.Recorder.MinDuration, 1*time.Second),
MaxDuration: mustParseDuration(cfg.Recorder.MaxDuration, 300*time.Second),
PrerollMs: cfg.Recorder.PrerollMs,
RecordIQ: cfg.Recorder.RecordIQ,
RecordAudio: cfg.Recorder.RecordAudio,
AutoDemod: cfg.Recorder.AutoDemod,
AutoDecode: cfg.Recorder.AutoDecode,
MaxDiskMB: cfg.Recorder.MaxDiskMB,
OutputDir: cfg.Recorder.OutputDir,
ClassFilter: cfg.Recorder.ClassFilter,
RingSeconds: cfg.Recorder.RingSeconds,
DeemphasisUs: cfg.Recorder.DeemphasisUs,
ExtractionTaps: cfg.Recorder.ExtractionTaps,
@@ -120,9 +120,10 @@ func main() {
extractMgr := &extractionManager{}
defer extractMgr.reset()

go runDSP(ctx, srcMgr, cfg, det, window, h, eventFile, eventMu, dspUpdates, gpuState, recMgr, sigSnap, extractMgr)
phaseSnap := &phaseSnapshot{}
go runDSP(ctx, srcMgr, cfg, det, window, h, eventFile, eventMu, dspUpdates, gpuState, recMgr, sigSnap, extractMgr, phaseSnap)

server := newHTTPServer(cfg.WebAddr, cfg.WebRoot, h, cfgPath, cfgManager, srcMgr, dspUpdates, gpuState, recMgr, sigSnap, eventMu)
server := newHTTPServer(cfg.WebAddr, cfg.WebRoot, h, cfgPath, cfgManager, srcMgr, dspUpdates, gpuState, recMgr, sigSnap, eventMu, phaseSnap)
go func() {
log.Printf("web listening on %s", cfg.WebAddr)
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
@@ -135,7 +136,3 @@ func main() {
<-stop
shutdownServer(server)
}





+ 27
- 0
cmd/sdrd/phase_snapshot.go Целия файл

@@ -0,0 +1,27 @@
package main

import "sync"

type phaseSnapshot struct {
mu sync.RWMutex
state phaseState
}

func (p *phaseSnapshot) Set(state phaseState) {
if p == nil {
return
}
p.mu.Lock()
p.state = state
p.mu.Unlock()
}

func (p *phaseSnapshot) Snapshot() phaseState {
if p == nil {
return phaseState{}
}
p.mu.RLock()
state := p.state
p.mu.RUnlock()
return state
}

Loading…
Отказ
Запис