diff --git a/src/ofdm.c b/src/ofdm.c index ba22f3f9..8d7a6dfc 100644 --- a/src/ofdm.c +++ b/src/ofdm.c @@ -192,6 +192,8 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG *config) { ofdm->codename = "HRA_112_112"; ofdm->amp_est_mode = 0; ofdm->tx_bpf_en = true; + ofdm->tx_bpf_proto = filtP650S900; + ofdm->tx_bpf_proto_n = sizeof(filtP650S900) / sizeof(float); ofdm->rx_bpf_en = false; ofdm->amp_scale = 245E3; ofdm->clip_gain1 = 2.0; @@ -226,6 +228,8 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG *config) { ofdm->codename = config->codename; ofdm->amp_est_mode = config->amp_est_mode; ofdm->tx_bpf_en = config->tx_bpf_en; + ofdm->tx_bpf_proto = config->tx_bpf_proto; + ofdm->tx_bpf_proto_n = config->tx_bpf_proto_n; ofdm->rx_bpf_en = config->rx_bpf_en; ofdm->foff_limiter = config->foff_limiter; ofdm->amp_scale = config->amp_scale; @@ -275,6 +279,8 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG *config) { ofdm->config.codename = ofdm->codename; ofdm->config.amp_est_mode = ofdm->amp_est_mode; ofdm->config.tx_bpf_en = ofdm->tx_bpf_en; + ofdm->config.tx_bpf_proto = ofdm->tx_bpf_proto; + ofdm->config.tx_bpf_proto_n = ofdm->tx_bpf_proto_n; ofdm->config.rx_bpf_en = ofdm->rx_bpf_en; ofdm->config.foff_limiter = ofdm->foff_limiter; ofdm->config.amp_scale = ofdm->amp_scale; @@ -539,36 +545,19 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG *config) { static void allocate_tx_bpf(struct OFDM *ofdm) { ofdm->tx_bpf = MALLOC(sizeof(struct quisk_cfFilter)); assert(ofdm->tx_bpf != NULL); + assert(ofdm->tx_bpf_proto != NULL); + assert(ofdm->tx_bpf_proto_n != 0); - /* Transmit bandpass filter; complex coefficients, center frequency */ - - if (!strcmp(ofdm->mode, "700D")) { - quisk_filt_cfInit(ofdm->tx_bpf, filtP650S900, - sizeof(filtP650S900) / sizeof(float)); - quisk_cfTune(ofdm->tx_bpf, ofdm->tx_centre / ofdm->fs); - } else if (!strcmp(ofdm->mode, "700E") || !strcmp(ofdm->mode, "2020") || - !strcmp(ofdm->mode, "datac1")) { - quisk_filt_cfInit(ofdm->tx_bpf, filtP900S1100, - sizeof(filtP900S1100) / sizeof(float)); - quisk_cfTune(ofdm->tx_bpf, ofdm->tx_centre / ofdm->fs); - } else if (!strcmp(ofdm->mode, "2020B")) { - quisk_filt_cfInit(ofdm->tx_bpf, filtP1100S1300, - sizeof(filtP1100S1300) / sizeof(float)); - quisk_cfTune(ofdm->tx_bpf, ofdm->tx_centre / ofdm->fs); - } else if (!strcmp(ofdm->mode, "datac0") || !strcmp(ofdm->mode, "datac3")) { - quisk_filt_cfInit(ofdm->tx_bpf, filtP400S600, - sizeof(filtP400S600) / sizeof(float)); - quisk_cfTune(ofdm->tx_bpf, ofdm->tx_centre / ofdm->fs); - } else if (!strcmp(ofdm->mode, "datac4") || !strcmp(ofdm->mode, "datac13") || - !strcmp(ofdm->mode, "datac14")) { - quisk_filt_cfInit(ofdm->tx_bpf, filtP200S400, - sizeof(filtP200S400) / sizeof(float)); - // centre the filter on the mean carrier freq, allows a narrower filter to - // be used - float tx_centre = find_carrier_centre(ofdm); - quisk_cfTune(ofdm->tx_bpf, tx_centre / ofdm->fs); - } else - assert(0); + quisk_filt_cfInit(ofdm->tx_bpf, ofdm->tx_bpf_proto, ofdm->tx_bpf_proto_n); + float tx_centre = ofdm->tx_centre; + if (!strcmp(ofdm->mode, "datac4") || !strcmp(ofdm->mode, "datac13") || + !strcmp(ofdm->mode, "datac14")) { + // Centre the filter on the mean carrier freq, allows a narrower + // filter to be used. Only really useful for very narrow, Nc odd + // waveforms. TODO: make this feature config controlled + tx_centre = find_carrier_centre(ofdm); + } + quisk_cfTune(ofdm->tx_bpf, tx_centre / ofdm->fs); } static void deallocate_tx_bpf(struct OFDM *ofdm) { @@ -589,7 +578,9 @@ static void allocate_rx_bpf(struct OFDM *ofdm) { ofdm->rx_bpf = MALLOC(sizeof(struct quisk_cfFilter)); assert(ofdm->rx_bpf != NULL); - /* Receive bandpass filter; complex coefficients, center frequency */ + /* Receive bandpass filter; complex coefficients, center frequency, only + really needed for very low SNR waveforms. TODO: make this config + controlled. */ if (!strcmp(ofdm->mode, "datac4") || !strcmp(ofdm->mode, "datac13") || !strcmp(ofdm->mode, "datac14")) { diff --git a/src/ofdm_internal.h b/src/ofdm_internal.h index 8007934f..3cb91308 100644 --- a/src/ofdm_internal.h +++ b/src/ofdm_internal.h @@ -94,15 +94,17 @@ struct OFDM_CONFIG { char *codename; /* name of LDPC code used with this mode */ uint8_t tx_uw[MAX_UW_BITS]; /* user defined unique word */ int amp_est_mode; - bool tx_bpf_en; /* default tx (mod) hilbert clipper BPF enable */ - bool rx_bpf_en; /* default rx (demod) input BPF enable */ - bool foff_limiter; /* tames freq offset updates in low SNR */ - float amp_scale; /* used to scale Tx waveform to approx FREEDV_PEAK with - clipper off */ - float clip_gain1; /* gain we apply to Tx signal before clipping to control - PAPR*/ - float clip_gain2; /* gain we apply to Tx signal after clipping and BBF to - control peak level */ + bool tx_bpf_en; /* default tx (mod) hilbert clipper BPF enable */ + bool rx_bpf_en; /* default rx (demod) input BPF enable */ + float *tx_bpf_proto; /* low pass prototype for complex BPF */ + int tx_bpf_proto_n; /* number of taps in low pass prototype */ + bool foff_limiter; /* tames freq offset updates in low SNR */ + float amp_scale; /* used to scale Tx waveform to approx FREEDV_PEAK with + clipper off */ + float clip_gain1; /* gain we apply to Tx signal before clipping to control + PAPR*/ + float clip_gain2; /* gain we apply to Tx signal after clipping and BBF to + control peak level */ bool clip_en; char mode[16]; /* OFDM mode in string form */ char *data_mode; @@ -156,6 +158,7 @@ struct OFDM { int packetsperburst; /* for OFDM data modes, how many packets before we reset state machine */ int amp_est_mode; /* amplitude estimtor algorithm */ + int tx_bpf_proto_n; /* number of taps in low pass prototype */ float amp_scale; float clip_gain1; float clip_gain2; @@ -220,6 +223,7 @@ struct OFDM { float coarse_foff_est_hz; float timing_norm; float mean_amp; + float *tx_bpf_proto; // Integer int clock_offset_counter; diff --git a/src/ofdm_mode.c b/src/ofdm_mode.c index df0b4f5e..b6c8c369 100644 --- a/src/ofdm_mode.c +++ b/src/ofdm_mode.c @@ -46,6 +46,8 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) { config->clip_gain2 = 0.8; config->clip_en = true; config->tx_bpf_en = true; + config->tx_bpf_proto = filtP650S900; + config->tx_bpf_proto_n = sizeof(filtP650S900) / sizeof(float); config->rx_bpf_en = false; config->amp_scale = 245E3; config->foff_limiter = false; @@ -69,6 +71,8 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) { config->amp_scale = 155E3; config->clip_gain1 = 3; config->clip_gain2 = 0.8; + config->tx_bpf_proto = filtP900S1100; + config->tx_bpf_proto_n = sizeof(filtP900S1100) / sizeof(float); } else if ((strcmp(mode, "2020") == 0)) { config->ts = 0.0205; config->nc = 31; @@ -76,6 +80,8 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) { config->amp_scale = 167E3; config->clip_gain1 = 2.5; config->clip_gain2 = 0.8; + config->tx_bpf_proto = filtP900S1100; + config->tx_bpf_proto_n = sizeof(filtP900S1100) / sizeof(float); } else if (strcmp(mode, "2020B") == 0) { config->ts = 0.014; config->tcp = 0.004; @@ -92,6 +98,8 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) { config->state_machine = "voice2"; config->ftwindowwidth = 64; config->foff_limiter = true; + config->tx_bpf_proto = filtP1100S1300; + config->tx_bpf_proto_n = sizeof(filtP1100S1300) / sizeof(float); } else if (strcmp(mode, "qam16") == 0) { /* not in use yet */ config->ns = 5; @@ -109,6 +117,8 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) { config->tx_bpf_en = false; config->clip_en = false; config->data_mode = "streaming"; + config->tx_bpf_proto = NULL; + config->tx_bpf_proto_n = 0; } else if (strcmp(mode, "datac0") == 0) { config->ns = 5; config->np = 4; @@ -130,6 +140,8 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) { config->amp_scale = 300E3; config->clip_gain1 = 2.2; config->clip_gain2 = 0.85; + config->tx_bpf_proto = filtP400S600; + config->tx_bpf_proto_n = sizeof(filtP400S600) / sizeof(float); } else if (strcmp(mode, "datac1") == 0) { config->ns = 5; config->np = 38; @@ -152,6 +164,8 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) { config->amp_scale = 145E3; config->clip_gain1 = 2.7; config->clip_gain2 = 0.8; + config->tx_bpf_proto = filtP900S1100; + config->tx_bpf_proto_n = sizeof(filtP900S1100) / sizeof(float); } else if (strcmp(mode, "datac3") == 0) { config->ns = 5; config->np = 29; @@ -176,6 +190,8 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) { config->amp_scale = 300E3; config->clip_gain1 = 2.2; config->clip_gain2 = 0.8; + config->tx_bpf_proto = filtP400S600; + config->tx_bpf_proto_n = sizeof(filtP400S600) / sizeof(float); } else if (strcmp(mode, "datac4") == 0) { config->ns = 5; config->np = 47; @@ -201,6 +217,8 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) { config->clip_gain1 = 1.2; config->clip_gain2 = 1.0; config->rx_bpf_en = true; + config->tx_bpf_proto = filtP200S400; + config->tx_bpf_proto_n = sizeof(filtP200S400) / sizeof(float); } else if (strcmp(mode, "datac13") == 0) { config->ns = 5; config->np = 18; @@ -226,6 +244,8 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) { config->clip_gain1 = 1.2; config->clip_gain2 = 1.0; config->rx_bpf_en = true; + config->tx_bpf_proto = filtP200S400; + config->tx_bpf_proto_n = sizeof(filtP200S400) / sizeof(float); } else if (strcmp(mode, "datac14") == 0) { config->ns = 5; config->np = 4; @@ -251,6 +271,8 @@ void ofdm_init_mode(char mode[], struct OFDM_CONFIG *config) { config->clip_gain1 = 2.0; config->clip_gain2 = 1.0; config->rx_bpf_en = true; + config->tx_bpf_proto = filtP200S400; + config->tx_bpf_proto_n = sizeof(filtP200S400) / sizeof(float); } else { assert(0); }