Bläddra i källkod

Add feed/process gap diagnostics for live audio

master
Jan Svabenik 9 timmar sedan
förälder
incheckning
0b9f86685a
2 ändrade filer med 24 tillägg och 3 borttagningar
  1. +4
    -0
      cmd/sdrd/dsp_loop.go
  2. +20
    -3
      internal/recorder/streamer.go

+ 4
- 0
cmd/sdrd/dsp_loop.go Visa fil

@@ -13,6 +13,7 @@ import (
"sdr-wideband-suite/internal/config" "sdr-wideband-suite/internal/config"
"sdr-wideband-suite/internal/detector" "sdr-wideband-suite/internal/detector"
"sdr-wideband-suite/internal/dsp" "sdr-wideband-suite/internal/dsp"
"sdr-wideband-suite/internal/logging"
"sdr-wideband-suite/internal/pipeline" "sdr-wideband-suite/internal/pipeline"
"sdr-wideband-suite/internal/recorder" "sdr-wideband-suite/internal/recorder"
) )
@@ -93,6 +94,7 @@ func runDSP(ctx context.Context, srcMgr *sourceManager, cfg config.Config, det *
continue continue
} }
if j >= len(streamSnips) || len(streamSnips[j]) == 0 { if j >= len(streamSnips) || len(streamSnips[j]) == 0 {
logging.Warn("gap", "snippet_empty", "signal", ds.ID)
continue continue
} }
snipRate := rt.cfg.SampleRate snipRate := rt.cfg.SampleRate
@@ -106,6 +108,8 @@ func runDSP(ctx context.Context, srcMgr *sourceManager, cfg config.Config, det *
} }
if len(items) > 0 { if len(items) > 0 {
rec.FeedSnippets(items) rec.FeedSnippets(items)
} else {
logging.Warn("gap", "feed_empty", "signals", len(streamSignals))
} }
} }
rt.maintenance(displaySignals, rec) rt.maintenance(displaySignals, rec)


+ 20
- 3
internal/recorder/streamer.go Visa fil

@@ -170,6 +170,9 @@ type Streamer struct {
droppedFeed uint64 droppedFeed uint64
droppedPCM uint64 droppedPCM uint64


lastFeedTS time.Time
lastProcTS time.Time

// pendingListens are subscribers waiting for a matching session. // pendingListens are subscribers waiting for a matching session.
pendingListens map[int64]*pendingListen pendingListens map[int64]*pendingListen
} }
@@ -260,6 +263,14 @@ func (st *Streamer) FeedSnippets(items []streamFeedItem) {
hasListeners := st.hasListenersLocked() hasListeners := st.hasListenersLocked()
pending := len(st.pendingListens) pending := len(st.pendingListens)
debugLiveAudio := st.policy.DebugLiveAudio debugLiveAudio := st.policy.DebugLiveAudio
now := time.Now()
if !st.lastFeedTS.IsZero() {
gap := now.Sub(st.lastFeedTS)
if gap > 150*time.Millisecond {
logging.Warn("gap", "feed_gap", "gap_ms", gap.Milliseconds())
}
}
st.lastFeedTS = now
st.mu.Unlock() st.mu.Unlock()


if debugLiveAudio { if debugLiveAudio {
@@ -280,16 +291,22 @@ func (st *Streamer) FeedSnippets(items []streamFeedItem) {
// processFeed runs in the worker goroutine. // processFeed runs in the worker goroutine.
func (st *Streamer) processFeed(msg streamFeedMsg) { func (st *Streamer) processFeed(msg streamFeedMsg) {
st.mu.Lock() st.mu.Lock()
defer st.mu.Unlock()

recEnabled := st.policy.Enabled && (st.policy.RecordAudio || st.policy.RecordIQ) recEnabled := st.policy.Enabled && (st.policy.RecordAudio || st.policy.RecordIQ)
hasListeners := st.hasListenersLocked() hasListeners := st.hasListenersLocked()
now := time.Now()
if !st.lastProcTS.IsZero() {
gap := now.Sub(st.lastProcTS)
if gap > 150*time.Millisecond {
logging.Warn("gap", "process_gap", "gap_ms", gap.Milliseconds())
}
}
st.lastProcTS = now
defer st.mu.Unlock()


if !recEnabled && !hasListeners { if !recEnabled && !hasListeners {
return return
} }


now := time.Now()
seen := make(map[int64]bool, len(msg.items)) seen := make(map[int64]bool, len(msg.items))


for i := range msg.items { for i := range msg.items {


Laddar…
Avbryt
Spara