From: drowe67 Date: Mon, 30 Apr 2018 21:31:32 +0000 (+0000) Subject: added clip option to ofdm/700d, minor change in BER, brings PAPR down to 8dB ish X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=c0cc31684673e6c7a5942b96ad9a8b816bd6b7f0;p=freetel-svn-tracking.git added clip option to ofdm/700d, minor change in BER, brings PAPR down to 8dB ish git-svn-id: https://svn.code.sf.net/p/freetel/code@3539 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/src/codec2_cohpsk.h b/codec2-dev/src/codec2_cohpsk.h index a7c9b4f0..8a28b04d 100644 --- a/codec2-dev/src/codec2_cohpsk.h +++ b/codec2-dev/src/codec2_cohpsk.h @@ -36,6 +36,7 @@ #define COHPSK_FS 7500 /* note this is a wierd value to get an integer oversampling rate */ +#define COHPSK_CLIP 6.5 /* hard clipping for Nc*Nc=14 to reduce PAPR */ #include "comp.h" #include "modem_stats.h" @@ -47,7 +48,7 @@ extern const int test_bits_coh[]; struct COHPSK *cohpsk_create(void); void cohpsk_destroy(struct COHPSK *coh); void cohpsk_mod(struct COHPSK *cohpsk, COMP tx_fdm[], int tx_bits[], int nbits); -void cohpsk_clip(COMP tx_fdm[]); +void cohpsk_clip(COMP tx_fdm[], float clip_thresh, int n); void cohpsk_demod(struct COHPSK *cohpsk, float rx_bits[], int *sync, COMP rx_fdm[], int *nin_frame); void cohpsk_get_demod_stats(struct COHPSK *cohpsk, struct MODEM_STATS *stats); void cohpsk_set_verbose(struct COHPSK *coh, int verbose); diff --git a/codec2-dev/src/codec2_ofdm.h b/codec2-dev/src/codec2_ofdm.h index 3fc69833..47c80051 100644 --- a/codec2-dev/src/codec2_ofdm.h +++ b/codec2-dev/src/codec2_ofdm.h @@ -42,6 +42,7 @@ extern "C" { /* Defines */ #define OFDM_AMP_SCALE (2E5*1.1491/1.06) /* use to scale to 16 bit short */ +#define OFDM_CLIP (32767*0.35) /* experimentally derived constant to reduce PAPR to about 8dB */ struct OFDM; diff --git a/codec2-dev/src/cohpsk.c b/codec2-dev/src/cohpsk.c index ac2452c3..5bf86451 100644 --- a/codec2-dev/src/cohpsk.c +++ b/codec2-dev/src/cohpsk.c @@ -441,8 +441,8 @@ void tx_filter_and_upconvert_coh(COMP tx_fdm[], int Nc,const COMP tx_symbols[], gain.imag = 0.0; for(i=0; i COHPSK_CLIP) { - sam = fcmult( COHPSK_CLIP/mag, sam); + if (mag > clip_thresh) { + sam = fcmult(clip_thresh/mag, sam); } tx_fdm[i] = sam; } diff --git a/codec2-dev/src/cohpsk_internal.h b/codec2-dev/src/cohpsk_internal.h index 478bc4e0..32cd842b 100644 --- a/codec2-dev/src/cohpsk_internal.h +++ b/codec2-dev/src/cohpsk_internal.h @@ -38,7 +38,6 @@ #define COHPSK_NFILTER (COHPSK_NSYM*COHPSK_M) #define COHPSK_EXCESS_BW 0.5 /* excess BW factor of root nyq filter */ #define COHPSK_NT 5 /* number of symbols we estimate timing over */ -#define COHPSK_CLIP 6.5 /* hard clipping for Nc*Nc=14 to reduce PAPR */ #include "fdmdv_internal.h" #include "kiss_fft.h" diff --git a/codec2-dev/src/cohpsk_mod.c b/codec2-dev/src/cohpsk_mod.c index 51953e38..4ed510c2 100644 --- a/codec2-dev/src/cohpsk_mod.c +++ b/codec2-dev/src/cohpsk_mod.c @@ -99,7 +99,7 @@ int main(int argc, char *argv[]) for(i=0; icohpsk, tx_fdm, f->codec_bits, COHPSK_BITS_PER_FRAME); - if (f->clip) - cohpsk_clip(tx_fdm); + if (f->clip) + cohpsk_clip(tx_fdm, COHPSK_CLIP, COHPSK_NOM_SAMPLES_PER_FRAME); for(i=0; in_nat_modem_samples; i++) mod_out[i] = fcmult(FDMDV_SCALE*NORM_PWR_COHPSK, tx_fdm[i]); i = quisk_cfInterpDecim(mod_out, f->n_nat_modem_samples, f->ptFilter7500to8000, 16, 15); @@ -965,7 +965,10 @@ static void freedv_comptx_700d(struct freedv *f, COMP mod_out[]) { mod_out[i] = fcmult(OFDM_AMP_SCALE*NORM_PWR_OFDM, asam); } - assert(f->clip == 0); /* todo: support clipping, requires some simulations and testing */ + if (f->clip) { + //fprintf(stderr, "clip "); + cohpsk_clip(mod_out, OFDM_CLIP, f->interleave_frames*f->n_nat_modem_samples); + } } #endif diff --git a/codec2-dev/src/freedv_tx.c b/codec2-dev/src/freedv_tx.c index adbd2f45..7ae44c69 100644 --- a/codec2-dev/src/freedv_tx.c +++ b/codec2-dev/src/freedv_tx.c @@ -94,13 +94,13 @@ int main(int argc, char *argv[]) { int mode; int n_speech_samples; int n_nom_modem_samples; - int use_codectx, use_datatx, use_testframes, interleave_frames; + int use_codectx, use_datatx, use_testframes, interleave_frames, use_clip; struct CODEC2 *c2; int i; if (argc < 4) { printf("usage: %s 1600|700|700B|700C|700D|2400A|2400B|800XA InputRawSpeechFile OutputModemRawFile\n" - " [--testframes] [--interleave depth] [--codectx] [--datatx]\n", argv[0]); + " [--testframes] [--interleave depth] [--codectx] [--datatx] [--clip 0|1]\n", argv[0]); printf("e.g %s 1600 hts1a.raw hts1a_fdmdv.raw\n", argv[0]); exit(1); } @@ -137,7 +137,7 @@ int main(int argc, char *argv[]) { exit(1); } - use_codectx = 0; use_datatx = 0; use_testframes = 0; interleave_frames = 1; + use_codectx = 0; use_datatx = 0; use_testframes = 0; interleave_frames = 1; use_clip = 0; if (argc > 4) { for (i = 4; i < argc; i++) { @@ -164,6 +164,9 @@ int main(int argc, char *argv[]) { if (strcmp(argv[i], "--interleave") == 0) { interleave_frames = atoi(argv[i+1]); } + if (strcmp(argv[i], "--clip") == 0) { + use_clip = atoi(argv[i+1]); + } } } @@ -185,6 +188,7 @@ int main(int argc, char *argv[]) { freedv_set_snr_squelch_thresh(freedv, -100.0); freedv_set_squelch_en(freedv, 1); + freedv_set_clip(freedv, use_clip); n_speech_samples = freedv_get_n_speech_samples(freedv); n_nom_modem_samples = freedv_get_n_nom_modem_samples(freedv);