-
Notifications
You must be signed in to change notification settings - Fork 10
Description
Summary
When scanning wide bands, SDR++ CE currently treats “sample rate” as the span per hop. In practice, the trustworthy spectrum per tune is smaller due to front-end and digital filter roll-off—or capped by a device’s vendor-defined instantaneous bandwidth (IBW). This causes missed signals at hop boundaries and edge artifacts. Please add a device-aware notion of usable bandwidth and scan with a configurable overlap.
Problem / Why this matters
Devices like Signal Hound BB60C/D expose a fixed IBW (e.g., 27 MHz) that is smaller/different than the maximum I/Q record rate.
Many consumer SDRs (e.g., Airspy) can stream at 6–10 MS/s, but only ~70–90% of that span is “clean” for detection; edges are unreliable.
Scanning by raw sample rate leads to gaps (missed hits falling in the edge region between hops) and false hits near the edges.
Proposal
Define usable bandwidth per device session
If the driver reports instantaneous_bandwidth_hz, use that.
Else derive usable_bw_hz = usable_bw_fraction × sample_rate_hz (default fraction = 0.80; user-tunable).
Always clamp usable_bw_hz ≤ sample_rate_hz.
Scan step with overlap
Add an overlap_fraction (default 0.10–0.20), so consecutive hops overlap their trustworthy middles.
step_hz = usable_bw_hz × (1 - overlap_fraction)
Edge guard (bin trimming) in detection
In each FFT frame, ignore a symmetric edge band: guard_fraction = (1 - usable_bw_fraction) / 2
Only run detection on the center bins inside the guard.
Device-specific overrides
Support per-device defaults via driver caps or a small JSON mapping (e.g., BB60D: instantaneous_bw_hz=27e6; Airspy R2: usable_bw_fraction=0.8).
Expose overrides in the UI and persist them.
UI/UX
In Scanner settings, display both:
Sample rate: e.g., 10 MS/s
Usable bandwidth: e.g., 8 MHz (derived or IBW)
Controls:
“Usable bandwidth fraction” (greyed out when IBW is in effect)
“Overlap (%)”
Optional: “Edge guard (%)” (auto-derived from usable fraction)
API/Driver capability
Extend the source/driver caps (or a query method) to optionally return:
instantaneous_bandwidth_hz (nullable)
recommended_usable_bw_fraction
recommended_overlap_fraction
Algorithm (pseudocode)
struct ScanCaps {
std::optional instantaneous_bw_hz; // if provided, prefer this
double usable_bw_fraction = 0.80; // default when IBW absent
double overlap_fraction = 0.15; // default overlap
};
double sample_rate = device.getSampleRate();
ScanCaps caps = device.getScanCaps(); // may be empty/partial
double usable_bw =
caps.instantaneous_bw_hz.has_value()
? std::min(caps.instantaneous_bw_hz.value(), sample_rate)
: std::min(caps.usable_bw_fraction * sample_rate, sample_rate);
double step = usable_bw * (1.0 - caps.overlap_fraction);
// optional detection mask inside each FFT frame
double guard_frac = 1.0 - (usable_bw / sample_rate);
double trim_each_side = 0.5 * guard_frac;
// plan hops
for (double f = f_min; f < f_max; f += step) {
double center = f + 0.5 * usable_bw; // or align so last hop covers f_max
tune(center);
run_detection(trim_each_side); // analyze only center bins
}
Acceptance criteria
✅ Scanner UI shows Sample rate and Usable bandwidth distinctly.
✅ Users can set usable_bw_fraction (unless IBW provided) and overlap_fraction.
✅ With a synthetic two-tone signal placed near hop boundaries, both tones are detected across hops (no gap).
✅ Edge false-positives decrease when usable_bw_fraction < 1.0.
✅ Device with IBW (e.g., BB60x) scans by IBW rather than raw sample rate.
Performance considerations
Overlap increases the number of hops; keep defaults modest (10–15%).
Expose a “Retune guard time (ms)” to account for LO settling when stepping faster.
Document that higher overlap or lower usable fraction improves reliability at the cost of scan speed.
Backward compatibility
Default behavior mirrors current behavior when usable_bw_fraction=1.0 and overlap_fraction=0.0.
Migration path: ship sane defaults per common devices.
Configuration example (optional JSON mapping)
{
"device_overrides": {
"signal_hound_bb60d": {
"instantaneous_bw_hz": 27000000,
"overlap_fraction": 0.15
},
"airspy_r2": {
"usable_bw_fraction": 0.80,
"overlap_fraction": 0.125
}
}
}
Out of scope (for this issue)
Automatic self-calibration of usable bandwidth via swept tone measurement.
Per-window adaptive trimming based on window type (can be a follow-up).
Notes
This change aligns the scanner with real-world RF front-end behavior and avoids missing signals at band boundaries, especially on devices where IBW ≠ max I/Q rate.