Adaptive gain: more aggressively re-probe for a higher gain
following a decrease in gain due to an increased noise floor. This is controlled by --adaptive-range-scan-delay and defaults to 5 minutes (vs. the default rescan delay of 1 hour)
This commit is contained in:
parent
fa8a066b4c
commit
f932baa5fa
14
adaptive.c
14
adaptive.c
|
|
@ -107,7 +107,7 @@ static void adaptive_burst_end_of_block();
|
||||||
static unsigned *adaptive_range_radix; // radix-sort buckets for current block
|
static unsigned *adaptive_range_radix; // radix-sort buckets for current block
|
||||||
static unsigned adaptive_range_radix_counter; // sum of all radix-sort buckets (= number of samples sorted)
|
static unsigned adaptive_range_radix_counter; // sum of all radix-sort buckets (= number of samples sorted)
|
||||||
static double adaptive_range_smoothed; // smoothed noise floor estimate, dBFS
|
static double adaptive_range_smoothed; // smoothed noise floor estimate, dBFS
|
||||||
static enum { RANGE_SCAN_IDLE, RANGE_SCAN_UP, RANGE_SCAN_DOWN } adaptive_range_state = RANGE_SCAN_UP;
|
static enum { RANGE_SCAN_IDLE, RANGE_SCAN_UP, RANGE_SCAN_DOWN, RANGE_RESCAN_UP, RANGE_RESCAN_DOWN } adaptive_range_state = RANGE_SCAN_UP;
|
||||||
static unsigned adaptive_range_change_timer; // countdown inhibiting control after changing gain
|
static unsigned adaptive_range_change_timer; // countdown inhibiting control after changing gain
|
||||||
static unsigned adaptive_range_rescan_timer; // countdown to next upwards gain reprobe
|
static unsigned adaptive_range_rescan_timer; // countdown to next upwards gain reprobe
|
||||||
static int adaptive_range_gain_limit; // probed maximum gain step with acceptable dynamic range
|
static int adaptive_range_gain_limit; // probed maximum gain step with acceptable dynamic range
|
||||||
|
|
@ -196,7 +196,7 @@ void adaptive_init()
|
||||||
adaptive_burst_window_counter = 0;
|
adaptive_burst_window_counter = 0;
|
||||||
|
|
||||||
adaptive_range_radix = calloc(sizeof(unsigned), 65536);
|
adaptive_range_radix = calloc(sizeof(unsigned), 65536);
|
||||||
adaptive_range_state = RANGE_SCAN_UP;
|
adaptive_range_state = RANGE_RESCAN_UP;
|
||||||
|
|
||||||
// select and enforce gain limits
|
// select and enforce gain limits
|
||||||
for (adaptive_gain_min = 0; adaptive_gain_min < maxgain; ++adaptive_gain_min) {
|
for (adaptive_gain_min = 0; adaptive_gain_min < maxgain; ++adaptive_gain_min) {
|
||||||
|
|
@ -514,7 +514,7 @@ static void adaptive_control_update()
|
||||||
|
|
||||||
// if we're currently doing a downward scan, reducing gain further may confuse it;
|
// if we're currently doing a downward scan, reducing gain further may confuse it;
|
||||||
// stop that scan and restart it once we are no longer in a reduced-gain state
|
// stop that scan and restart it once we are no longer in a reduced-gain state
|
||||||
if (adaptive_range_state == RANGE_SCAN_DOWN) {
|
if (adaptive_range_state == RANGE_SCAN_DOWN || adaptive_range_state == RANGE_RESCAN_DOWN) {
|
||||||
adaptive_range_state = RANGE_SCAN_IDLE;
|
adaptive_range_state = RANGE_SCAN_IDLE;
|
||||||
adaptive_range_rescan_timer = 0;
|
adaptive_range_rescan_timer = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -539,12 +539,13 @@ static void adaptive_control_update()
|
||||||
}
|
}
|
||||||
switch (adaptive_range_state) {
|
switch (adaptive_range_state) {
|
||||||
case RANGE_SCAN_UP:
|
case RANGE_SCAN_UP:
|
||||||
|
case RANGE_RESCAN_UP:
|
||||||
if (available_range < Modes.adaptive_range_target) {
|
if (available_range < Modes.adaptive_range_target) {
|
||||||
// Current gain fails to meet our target. Switch to downward scanning.
|
// Current gain fails to meet our target. Switch to downward scanning.
|
||||||
fprintf(stderr, "adaptive: available dynamic range (%.1fdB) < required dynamic range (%.1fdB), switching to downward scan\n", available_range, Modes.adaptive_range_target);
|
fprintf(stderr, "adaptive: available dynamic range (%.1fdB) < required dynamic range (%.1fdB), switching to downward scan\n", available_range, Modes.adaptive_range_target);
|
||||||
gain_down = gain_not_up = true;
|
gain_down = gain_not_up = true;
|
||||||
gain_down_reason = "probing dynamic range gain lower bound";
|
gain_down_reason = "probing dynamic range gain lower bound";
|
||||||
adaptive_range_state = RANGE_SCAN_DOWN;
|
adaptive_range_state = (adaptive_range_state == RANGE_RESCAN_UP ? RANGE_RESCAN_DOWN : RANGE_SCAN_DOWN);
|
||||||
if (adaptive_range_gain_limit >= current_gain) {
|
if (adaptive_range_gain_limit >= current_gain) {
|
||||||
adaptive_range_gain_limit = current_gain - 1;
|
adaptive_range_gain_limit = current_gain - 1;
|
||||||
}
|
}
|
||||||
|
|
@ -569,11 +570,12 @@ static void adaptive_control_update()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RANGE_SCAN_DOWN:
|
case RANGE_SCAN_DOWN:
|
||||||
|
case RANGE_RESCAN_DOWN:
|
||||||
if (available_range >= Modes.adaptive_range_target) {
|
if (available_range >= Modes.adaptive_range_target) {
|
||||||
// Current gain meets our target; we are done with the scan.
|
// Current gain meets our target; we are done with the scan.
|
||||||
fprintf(stderr, "adaptive: available dynamic range (%.1fdB) >= required dynamic range (%.1fdB), stopping downwards scan here\n", available_range, Modes.adaptive_range_target);
|
fprintf(stderr, "adaptive: available dynamic range (%.1fdB) >= required dynamic range (%.1fdB), stopping downwards scan here\n", available_range, Modes.adaptive_range_target);
|
||||||
adaptive_range_state = RANGE_SCAN_IDLE;
|
adaptive_range_state = RANGE_SCAN_IDLE;
|
||||||
adaptive_range_rescan_timer = Modes.adaptive_range_rescan_delay;
|
adaptive_range_rescan_timer = (adaptive_range_state == RANGE_SCAN_DOWN ? Modes.adaptive_range_scan_delay : Modes.adaptive_range_rescan_delay);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -616,7 +618,7 @@ static void adaptive_control_update()
|
||||||
fprintf(stderr, "adaptive: start periodic scan for acceptable dynamic range at increased gain\n");
|
fprintf(stderr, "adaptive: start periodic scan for acceptable dynamic range at increased gain\n");
|
||||||
gain_up = true;
|
gain_up = true;
|
||||||
gain_up_reason = "periodic re-probing of dynamic range gain upper bound";
|
gain_up_reason = "periodic re-probing of dynamic range gain upper bound";
|
||||||
adaptive_range_state = RANGE_SCAN_UP;
|
adaptive_range_state = RANGE_RESCAN_UP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
10
dump1090.c
10
dump1090.c
|
|
@ -143,6 +143,7 @@ static void modesInitConfig(void) {
|
||||||
Modes.adaptive_range_alpha = 2.0 / (5 + 1);
|
Modes.adaptive_range_alpha = 2.0 / (5 + 1);
|
||||||
Modes.adaptive_range_percentile = 40;
|
Modes.adaptive_range_percentile = 40;
|
||||||
Modes.adaptive_range_change_delay = 10;
|
Modes.adaptive_range_change_delay = 10;
|
||||||
|
Modes.adaptive_range_scan_delay = 300;
|
||||||
Modes.adaptive_range_rescan_delay = 3600;
|
Modes.adaptive_range_rescan_delay = 3600;
|
||||||
|
|
||||||
sdrInitConfig();
|
sdrInitConfig();
|
||||||
|
|
@ -373,8 +374,11 @@ static void showHelp(void)
|
||||||
"--adaptive-range-percentile <p> Set dynamic range noise percentile\n"
|
"--adaptive-range-percentile <p> Set dynamic range noise percentile\n"
|
||||||
"--adaptive-range-change-delay <s> Set delay after changing gain before\n"
|
"--adaptive-range-change-delay <s> Set delay after changing gain before\n"
|
||||||
" resuming dynamic range control (seconds)\n"
|
" resuming dynamic range control (seconds)\n"
|
||||||
"--adaptive-range-rescan-delay <s> Set rescan interval for dynamic range\n"
|
"--adaptive-range-scan-delay <s> Set scan interval for dynamic range\n"
|
||||||
" gain scanning (seconds)\n"
|
" gain scanning following a gain decrease\n"
|
||||||
|
" due to an increase in noise (seconds)\n"
|
||||||
|
"--adaptive-range-rescan-delay <s> Set periodic rescan interval for dynamic\n"
|
||||||
|
" range gain scanning (seconds)\n"
|
||||||
"--adaptive-min-gain <g> Set gain adjustment range lower limit (dB)\n"
|
"--adaptive-min-gain <g> Set gain adjustment range lower limit (dB)\n"
|
||||||
"--adaptive-max-gain <g> Set gain adjustment range upper limit (dB)\n"
|
"--adaptive-max-gain <g> Set gain adjustment range upper limit (dB)\n"
|
||||||
"--adaptive-duty-cycle <p> Set adaptive gain duty cycle %% (1..100)\n"
|
"--adaptive-duty-cycle <p> Set adaptive gain duty cycle %% (1..100)\n"
|
||||||
|
|
@ -796,6 +800,8 @@ int main(int argc, char **argv) {
|
||||||
Modes.adaptive_range_target = atof(argv[++j]);
|
Modes.adaptive_range_target = atof(argv[++j]);
|
||||||
} else if (!strcmp(argv[j], "--adaptive-range-change-delay") && more) {
|
} else if (!strcmp(argv[j], "--adaptive-range-change-delay") && more) {
|
||||||
Modes.adaptive_range_change_delay = atoi(argv[++j]);
|
Modes.adaptive_range_change_delay = atoi(argv[++j]);
|
||||||
|
} else if (!strcmp(argv[j], "--adaptive-range-scan-delay") && more) {
|
||||||
|
Modes.adaptive_range_scan_delay = atoi(argv[++j]);
|
||||||
} else if (!strcmp(argv[j], "--adaptive-range-rescan-delay") && more) {
|
} else if (!strcmp(argv[j], "--adaptive-range-rescan-delay") && more) {
|
||||||
Modes.adaptive_range_rescan_delay = atoi(argv[++j]);
|
Modes.adaptive_range_rescan_delay = atoi(argv[++j]);
|
||||||
} else if (sdrHandleOption(argc, argv, &j)) {
|
} else if (sdrHandleOption(argc, argv, &j)) {
|
||||||
|
|
|
||||||
|
|
@ -431,6 +431,7 @@ struct _Modes { // Internal state
|
||||||
unsigned adaptive_range_percentile;
|
unsigned adaptive_range_percentile;
|
||||||
float adaptive_range_target;
|
float adaptive_range_target;
|
||||||
unsigned adaptive_range_change_delay;
|
unsigned adaptive_range_change_delay;
|
||||||
|
unsigned adaptive_range_scan_delay;
|
||||||
unsigned adaptive_range_rescan_delay;
|
unsigned adaptive_range_rescan_delay;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue