Files
homelab-radio/sdr/patches/rtl_airband-local.patch

150 lines
7.3 KiB
Diff

diff --git a/src/config.cpp b/src/config.cpp
index 84be9dd..609eb71 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -301,6 +301,7 @@ static struct freq_t* mk_freqlist(int n) {
fl[i].squelch = Squelch();
fl[i].active_counter = 0;
fl[i].modulation = MOD_AM;
+ fl[i].hold_ms = 0;
}
return fl;
}
@@ -425,7 +426,19 @@ static int parse_channels(libconfig::Setting& chans, device_t* dev, int i) {
error();
}
+ if (chans[j].exists("hold_ms") && (libconfig::Setting::TypeList != chans[j]["hold_ms"].getType() || chans[j]["hold_ms"].getLength() < channel->freq_count)) {
+ cerr << "Configuration error: devices.[" << i << "] channels.[" << j << "]: hold_ms should be a list of ints with at least " << channel->freq_count << " elements\n";
+ error();
+ }
for (int f = 0; f < channel->freq_count; f++) {
+ if (chans[j].exists("hold_ms")) {
+ int h = (int)chans[j]["hold_ms"][f];
+ if (h < 0 || h > 60000) {
+ cerr << "Configuration error: devices.[" << i << "] channels.[" << j << "]: hold_ms must be 0..60000\n";
+ error();
+ }
+ channel->freqlist[f].hold_ms = h;
+ }
channel->freqlist[f].frequency = parse_anynum2int((chans[j]["freqs"][f]));
if (chans[j].exists("labels")) {
channel->freqlist[f].label = strdup(chans[j]["labels"][f]);
diff --git a/src/helper_functions.cpp b/src/helper_functions.cpp
index 8a33130..d04fce4 100644
--- a/src/helper_functions.cpp
+++ b/src/helper_functions.cpp
@@ -74,7 +74,7 @@ bool make_subdirs(const string& basedir, const string& subdirs) {
string make_dated_subdirs(const string& basedir, const struct tm* time) {
// use the time to build the date subdirectories
char date_path[11];
- strftime(date_path, sizeof(date_path), "%Y/%m/%d", time);
+ strftime(date_path, sizeof(date_path), "%Y-%m-%d", time);
const string date_path_str = string(date_path);
// make all the subdirectories, and return the full path if successful
diff --git a/src/rtl_airband.cpp b/src/rtl_airband.cpp
index 8993356..3d10d03 100644
--- a/src/rtl_airband.cpp
+++ b/src/rtl_airband.cpp
@@ -83,6 +83,10 @@ bool use_localtime = false;
bool multiple_demod_threads = false;
bool multiple_output_threads = false;
bool log_scan_activity = false;
+// LOCAL PATCH (2026-10-20): configurable scan dwell / hold (upstream hardcodes 200 ms and 10 steps = 2 s)
+int scan_dwell_ms = 200;
+int scan_hold_ms = 2000;
+int scan_long_hold_min_ms = 800; // per-frequency hold_ms applies only after >= this much open squelch
char* stats_filepath = NULL;
double stats_update_interval = 15.0;
double global_split_min_file_time = 1.0;
@@ -110,38 +114,50 @@ void sighandler(int sig) {
void* controller_thread(void* params) {
device_t* dev = (device_t*)params;
int i = 0;
- int consecutive_squelch_off = 0;
+ int off_ticks = 0; // consecutive dwell ticks without signal on the current frequency
+ int on_ticks = 0; // dwell ticks with signal since the scanner stopped on this frequency
+ bool stepping = false; // true while hopping (hold expired); false while holding after activity
int new_centerfreq = 0;
struct timeval tv;
if (dev->channels[0].freq_count < 2)
return 0;
+ // LOCAL PATCH: dwell = scan_dwell_ms, hold after activity = per-frequency hold_ms (or scan_hold_ms)
while (!do_exit) {
- SLEEP(200);
+ SLEEP(scan_dwell_ms);
+ freq_t* fl = dev->channels[0].freqlist;
if (dev->channels[0].axcindicate == NO_SIGNAL) {
- if (consecutive_squelch_off < 10) {
- consecutive_squelch_off++;
+ // long per-frequency hold only after a real transmission, not after a noise blip
+ const bool real_tx = on_ticks * scan_dwell_ms >= scan_long_hold_min_ms;
+ const int hold = (fl[i].hold_ms > 0 && real_tx) ? fl[i].hold_ms : scan_hold_ms;
+ const int hold_steps = hold / scan_dwell_ms > 0 ? hold / scan_dwell_ms : 1;
+ if (!stepping && off_ticks < hold_steps) {
+ off_ticks++;
} else {
+ stepping = true;
+ on_ticks = 0;
i++;
i %= dev->channels[0].freq_count;
dev->channels[0].freq_idx = i;
- new_centerfreq = dev->channels[0].freqlist[i].frequency + 20 * (double)(dev->input->sample_rate / fft_size);
+ new_centerfreq = fl[i].frequency + 20 * (double)(dev->input->sample_rate / fft_size);
if (input_set_centerfreq(dev->input, new_centerfreq) < 0) {
break;
}
}
} else {
- if (consecutive_squelch_off == 10) {
+ if (stepping) {
if (log_scan_activity)
- log(LOG_INFO, "Activity on %7.3f MHz (%s)\n", dev->channels[0].freqlist[i].frequency / 1000000.0, dev->channels[0].freqlist[i].label);
+ log(LOG_INFO, "Activity on %7.3f MHz (%s)\n", fl[i].frequency / 1000000.0, fl[i].label);
if (i != dev->last_frequency) {
- // squelch has just opened on a new frequency - we might need to update outputs' metadata
+ // squelch just opened on a new frequency: outputs may need new metadata
gettimeofday(&tv, NULL);
tag_queue_put(dev, i, tv);
dev->last_frequency = i;
}
}
- consecutive_squelch_off = 0;
+ stepping = false;
+ off_ticks = 0;
+ on_ticks++;
}
}
return 0;
@@ -858,6 +874,16 @@ int main(int argc, char* argv[]) {
}
if (root.exists("log_scan_activity") && (bool)root["log_scan_activity"] == true)
log_scan_activity = true;
+ if (root.exists("scan_dwell_ms"))
+ scan_dwell_ms = (int)root["scan_dwell_ms"];
+ if (root.exists("scan_hold_ms"))
+ scan_hold_ms = (int)root["scan_hold_ms"];
+ if (root.exists("scan_long_hold_min_ms"))
+ scan_long_hold_min_ms = (int)root["scan_long_hold_min_ms"];
+ if (scan_dwell_ms < 20 || scan_dwell_ms > 5000 || scan_hold_ms < 0 || scan_hold_ms > 60000) {
+ cerr << "Configuration error: scan_dwell_ms must be 20..5000, scan_hold_ms 0..60000\n";
+ error();
+ }
if (root.exists("stats_filepath"))
stats_filepath = strdup(root["stats_filepath"]);
parse_global_double(root, "stats_update_interval", &stats_update_interval);
diff --git a/src/rtl_airband.h b/src/rtl_airband.h
index 2029fce..a1c27b4 100644
--- a/src/rtl_airband.h
+++ b/src/rtl_airband.h
@@ -256,6 +256,7 @@ struct freq_t {
NotchFilter notch_filter; // notch filter - good to remove CTCSS tones
LowpassFilter lowpass_filter; // lowpass filter, applied to I/Q after derotation, set at bandwidth/2 to remove out of band noise
enum modulations modulation;
+ int hold_ms; // LOCAL PATCH: per-frequency scan hold after activity (0 = global scan_hold_ms)
};
struct channel_t {
float wavein[WAVE_LEN]; // FFT output waveform