Skip to content

Commit

Permalink
first attempt at quick autogain
Browse files Browse the repository at this point in the history
  • Loading branch information
wiedehopf committed Nov 2, 2024
1 parent a0ad60b commit f6c06e5
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 12 deletions.
26 changes: 26 additions & 0 deletions demod_2400.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,16 @@ void demodulate2400(struct mag_buf *mag) {
uint16_t *pa = m;
uint16_t *stop = m + mlen;

uint16_t *statsProgress = m;

const uint32_t statsWindow = MODES_SHORT_MSG_SAMPLES / 2; // half a short message
uint32_t loudSamples = 0;
uint32_t quietSamples = 0;
uint32_t quiet2Samples = 0;
uint32_t loudThreshold = 55000 * statsWindow; // max 65536
uint32_t quietThreshold = 800 * statsWindow;
uint32_t quiet2Threshold = 2 * quietThreshold;

for (; pa < stop; pa++) {
int32_t pa_mag, base_noise, ref_level;
int msglen;
Expand All @@ -308,6 +318,18 @@ void demodulate2400(struct mag_buf *mag) {
// due to plenty room in the message buffer for decoding
// we can with pa go beyond stop without a buffer overrun ...

if (Modes.autoGain && pa >= statsProgress) {
uint32_t magSum = 0;
for (uint32_t i = 0; i < statsWindow; i++) {
magSum += pa[i];
}
loudSamples += statsWindow * (magSum > loudThreshold);
quietSamples += statsWindow * (magSum < quietThreshold);
quiet2Samples += statsWindow * (magSum < quiet2Threshold);

statsProgress = pa + statsWindow;
}

if (pa[1] > pa[7] && pa[12] > pa[14] && pa[12] > pa[15]) { goto after_pre; }
pa++; if (pa[1] > pa[7] && pa[12] > pa[14] && pa[12] > pa[15]) { goto after_pre; }
pa++; if (pa[1] > pa[7] && pa[12] > pa[14] && pa[12] > pa[15]) { goto after_pre; }
Expand Down Expand Up @@ -471,6 +493,10 @@ void demodulate2400(struct mag_buf *mag) {
netUseMessage(mm);
}

mag->loudSamples = loudSamples;
mag->quietSamples = quietSamples;
mag->quiet2Samples = quiet2Samples;

/* update noise power */
{
double sum_signal_power = sum_scaled_signal_power / 65535.0 / 65535.0;
Expand Down
74 changes: 69 additions & 5 deletions readsb.c
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,65 @@ static void *globeBinEntryPoint(void *arg) {
return NULL;
}

static void gainStatistics(struct mag_buf *buf) {
static uint64_t loudSamples;
static uint64_t quietSamples;
static uint64_t quiet2Samples;
static uint64_t totalSamples;
static int slowRise;
static int lastGain;

loudSamples += buf->loudSamples;
quietSamples += buf->quietSamples;
quiet2Samples += buf->quiet2Samples;
totalSamples += buf->length;

if (totalSamples < 2 * Modes.sample_rate) {
return;
}

double loudPercent = loudSamples / (double) totalSamples * 100.0;
double quietPercent = quietSamples / (double) totalSamples * 100.0;
double quiet2Percent = quiet2Samples / (double) totalSamples * 100.0;

// reset
loudSamples = 0;
quietSamples = 0;
quiet2Samples = 0;
totalSamples = 0;

if (!Modes.autoGain) {
// don't adjust anything
return;
}

if (loudPercent > 0.05 || quiet2Percent < 0.05) {
Modes.lowerGain = 1;
} else if (
quietPercent > 10.0
) {
if (getUptime() < 1 * MINUTES || slowRise > 10) {
slowRise = 0;
Modes.increaseGain = 1;
} else {
slowRise++;
}
}
if (Modes.increaseGain || Modes.lowerGain) {
if (getUptime() < 1 * MINUTES) {
Modes.lowerGain *= 2;
Modes.increaseGain *= 2;
}
if (Modes.gain != lastGain) {
lastGain = Modes.gain;
fprintf(stderr, "loud: %8.4f %% quiet: %8.4f %% quiet2 %8.4f %%\n", loudPercent, quietPercent, quiet2Percent);
}
sdrSetGain();
}

}


static void timingStatistics(struct mag_buf *buf) {
static int64_t last_ts;

Expand Down Expand Up @@ -873,6 +932,10 @@ static void *decodeEntryPoint(void *arg) {
demodulate2400AC(buf);
}

gainStatistics(buf);
timingStatistics(buf);

Modes.stats_current.samples_lost += Modes.sdr_buf_samples - buf->length;
Modes.stats_current.samples_processed += buf->length;
Modes.stats_current.samples_dropped += buf->dropped;
end_cpu_timing(&start_time, &Modes.stats_current.demod_cpu);
Expand All @@ -883,10 +946,6 @@ static void *decodeEntryPoint(void *arg) {
pthread_cond_signal(&Threads.reader.cond);
unlockReader();

Modes.stats_current.samples_lost += Modes.sdr_buf_samples - buf->length;

timingStatistics(buf);

watchdogCounter = 100; // roughly 10 seconds
} else {
// Nothing to process this time around.
Expand Down Expand Up @@ -1446,7 +1505,12 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
Modes.dev_name = strdup(arg);
break;
case OptGain:
Modes.gain = (int) (atof(arg)*10); // Gain is in tens of DBs
if (strcmp(arg, "auto") == 0) {
Modes.autoGain = 1;
Modes.gain = 439;
} else {
Modes.gain = (int) (atof(arg)*10); // Gain is in tens of DBs
}
break;
case OptFreq:
Modes.freq = (int) strtoll(arg, NULL, 10);
Expand Down
7 changes: 7 additions & 0 deletions readsb.h
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,10 @@ struct mag_buf
unsigned length; // Number of valid samples _after_ overlap. Total buffer length is buf->length + Modes.trailing_samples.
int64_t sysTimestamp; // Estimated system time at start of block
int64_t sysMicroseconds; // sysTimestamp in microseconds
uint32_t loudSamples;
uint32_t quietSamples;
uint32_t quiet2Samples;
uint32_t padding2;
uint16_t *data; // Magnitude data. Starts with Modes.trailing_samples worth of overlap from the previous block
#if defined(__arm__)
/*padding 4 bytes*/
Expand Down Expand Up @@ -529,6 +533,9 @@ struct _Modes
pthread_mutex_t sdrControlMutex;
int8_t sdrInitialized;
int8_t sdrOpenFailed;
int8_t increaseGain;
int8_t lowerGain;
int8_t autoGain;
int gain;
int dc_filter; // should we apply a DC filter?
int enable_agc;
Expand Down
48 changes: 41 additions & 7 deletions sdr_rtlsdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,47 @@ void rtlsdrInitConfig() {
RTLSDR.tunerAgcEnabled = 0;
}

static int getClosestGainIndex(int target) {
target = (target == MODES_MAX_GAIN ? 9999 : target);
int closest = 0;

for (int i = 0; i < RTLSDR.numgains; ++i) {
if (abs(RTLSDR.gains[i] - target) < abs(RTLSDR.gains[closest] - target)) {
closest = i;
}
}
return closest;
}

void rtlsdrSetGain() {
if (Modes.increaseGain || Modes.lowerGain) {
int closest = getClosestGainIndex(Modes.gain);
if (Modes.increaseGain) {
closest += Modes.increaseGain;
} else if (Modes.lowerGain) {
closest -= Modes.lowerGain;
}
if (closest >= RTLSDR.numgains) {
closest = RTLSDR.numgains - 1;
}
if (closest < 0) {
closest = 0;
}
Modes.increaseGain = 0;
Modes.lowerGain = 0;

if (Modes.gain == RTLSDR.gains[closest]) {
// same gain, nothing to do
return;
}

// change gain
Modes.gain = RTLSDR.gains[closest];
}

if (Modes.gain < 0) {
Modes.gain = 0;
}
if (Modes.gain == MODES_AUTO_GAIN || Modes.gain >= 520) {
Modes.gain = 590;

Expand All @@ -104,13 +144,7 @@ void rtlsdrSetGain() {
}
} else {

int target = (Modes.gain == MODES_MAX_GAIN ? 9999 : Modes.gain);
int closest = -1;

for (int i = 0; i < RTLSDR.numgains; ++i) {
if (closest == -1 || abs(RTLSDR.gains[i] - target) < abs(RTLSDR.gains[closest] - target))
closest = i;
}
int closest = getClosestGainIndex(Modes.gain);
int newGain = RTLSDR.gains[closest];

if (RTLSDR.tunerAgcEnabled) {
Expand Down

0 comments on commit f6c06e5

Please sign in to comment.