diff --git a/src/libmobile/main_mobile.c b/src/libmobile/main_mobile.c index 6dac38d..19312f3 100644 --- a/src/libmobile/main_mobile.c +++ b/src/libmobile/main_mobile.c @@ -626,6 +626,11 @@ next_char: /* dump info */ dump_info(); goto next_char; +#ifdef HAVE_SDR + case 'B': + calibrate_bias(); + goto next_char; +#endif } /* process call control */ diff --git a/src/libmobile/main_mobile.h b/src/libmobile/main_mobile.h index e958f2c..4912057 100644 --- a/src/libmobile/main_mobile.h +++ b/src/libmobile/main_mobile.h @@ -42,4 +42,5 @@ void sighandler(int sigset); void main_mobile(int *quit, int latency, int interval, void (*myhandler)(void), const char *station_id, int station_id_digits); void dump_info(void); +void calibrate_bias(void); diff --git a/src/libsdr/sdr.c b/src/libsdr/sdr.c index 1660e3c..9a33697 100644 --- a/src/libsdr/sdr.c +++ b/src/libsdr/sdr.c @@ -391,6 +391,39 @@ error: return NULL; } +double bias_I, bias_Q; /* calculated bias */ +int bias_count = -1; /* number of calculations */ + +void calibrate_bias(void) +{ + bias_count = 0; + bias_I = 0.0; + bias_Q = 0.0; +} + +static void sdr_bias(float *buffer, int count) +{ + int i; + + if (bias_count < sdr_config->samplerate) { + for (i = 0; i < count; i++) { + bias_I += *buffer++; + bias_Q += *buffer++; + } + bias_count += count; + if (bias_count >= sdr_config->samplerate) { + bias_I /= bias_count; + bias_Q /= bias_count; + PDEBUG(DSDR, DEBUG_INFO, "DC bias calibration finished.\n"); + } + } else { + for (i = 0; i < count; i++) { + *buffer++ -= bias_I; + *buffer++ -= bias_Q; + } + } +} + static void *sdr_write_child(void *arg) { sdr_t *sdr = (sdr_t *)arg; @@ -461,6 +494,8 @@ static void *sdr_read_child(void *arg) if (sdr_config->soapy) count = soapy_receive(sdr->thread_read.buffer2, num); #endif + if (bias_count >= 0) + sdr_bias(sdr->thread_read.buffer2, count); if (count > 0) { #ifdef DEBUG_BUFFER printf("Thread read %d samples from SDR and writes them to read buffer.\n", count); @@ -767,6 +802,8 @@ int sdr_read(void *inst, sample_t **samples, int num, int channels, double *rf_l if (sdr_config->soapy) count = soapy_receive(buff, num); #endif + if (bias_count >= 0) + sdr_bias(buff, count); if (count <= 0) return count; } diff --git a/src/libsdr/sdr_config.c b/src/libsdr/sdr_config.c index 078e179..1c2297b 100644 --- a/src/libsdr/sdr_config.c +++ b/src/libsdr/sdr_config.c @@ -95,6 +95,7 @@ void sdr_config_print_hotkeys(void) { printf("Press 'q' key to toggle display of RX I/Q vector.\n"); printf("Press 's' key to toggle display of RX spectrum.\n"); + printf("Press shift + 'B' key to remove DC level.\n"); } #define OPT_SDR_UHD 1500 diff --git a/src/libsquelch/squelch.c b/src/libsquelch/squelch.c index 99dcb11..4edb84e 100644 --- a/src/libsquelch/squelch.c +++ b/src/libsquelch/squelch.c @@ -43,7 +43,8 @@ * loss_time, the 'loss' condition is returned. */ -#define SQUELCH_INIT_TIME 1.0 /* wait some time before performing squelch */ +/* NOTE: SQUELCH must be calibrated !AFTER! DC bias, to get the actual noise floor */ +#define SQUELCH_INIT_TIME 1.1 /* wait some time before performing squelch */ #define SQUELCH_AUTO_TIME 1.0 /* duration of squelch quelch calibration */ #define SQUELCH_AUTO_OFFSET 6.0 /* auto calibration: offset above noise floor */