added clip option to ofdm/700d, minor change in BER, brings PAPR down to 8dB ish
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 30 Apr 2018 21:31:32 +0000 (21:31 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 30 Apr 2018 21:31:32 +0000 (21:31 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3539 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/codec2_cohpsk.h
codec2-dev/src/codec2_ofdm.h
codec2-dev/src/cohpsk.c
codec2-dev/src/cohpsk_internal.h
codec2-dev/src/cohpsk_mod.c
codec2-dev/src/freedv_api.c
codec2-dev/src/freedv_tx.c

index a7c9b4f01adf0f678077e1b3285b8caa1aac68ea..8a28b04d377c876e3a8011318ef006350f73317b 100644 (file)
@@ -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);
index 3fc69833e7d21f0f5583a54da7291bffcb30767a..47c80051d5f1e9372e08b573a39120a19ca2674c 100644 (file)
@@ -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;
 
index ac2452c36a3d8f4d81da5ba657d7a8bfdef98a7a..5bf86451d0652cbd2d9fa8623b325c6f16cf0922 100644 (file)
@@ -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_M; i++) {
-               tx_fdm[i].real = 0.0;
-               tx_fdm[i].imag = 0.0;
+        tx_fdm[i].real = 0.0;
+        tx_fdm[i].imag = 0.0;
     }
 
     for(c=0; c<Nc; c++)
@@ -506,14 +506,17 @@ void tx_filter_and_upconvert_coh(COMP tx_fdm[], int Nc,const COMP tx_symbols[],
 
     /* shift memory, inserting zeros at end */
 
-    for(i=0; i<COHPSK_NSYM-1; i++)
-       for(c=0; c<Nc; c++)
-           tx_filter_memory[c][i] = tx_filter_memory[c][i+1];
-
+    for(i=0; i<COHPSK_NSYM-1; i++) {
        for(c=0; c<Nc; c++) {
-               tx_filter_memory[c][COHPSK_NSYM-1].real = 0.0;
-               tx_filter_memory[c][COHPSK_NSYM-1].imag = 0.0;
+           tx_filter_memory[c][i] = tx_filter_memory[c][i+1];
+        }
+    }
+    
+    for(c=0; c<Nc; c++) {
+        tx_filter_memory[c][COHPSK_NSYM-1].real = 0.0;
+        tx_filter_memory[c][COHPSK_NSYM-1].imag = 0.0;
     }
+   
 }
 
 void corr_with_pilots_comp(float *corr_out, float *mag_out, struct COHPSK *coh, int t, COMP dp_f_fine)
@@ -737,17 +740,17 @@ void cohpsk_mod(struct COHPSK *coh, 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)
 {
     COMP  sam;
     float mag;
     int   i;
 
-    for(i=0; i<COHPSK_NOM_SAMPLES_PER_FRAME; i++) {
+    for(i=0; i<n; i++) {
         sam = tx_fdm[i];
         mag = cabsolute(sam);
-        if (mag >  COHPSK_CLIP)  {
-            sam = fcmult( COHPSK_CLIP/mag, sam);
+        if (mag > clip_thresh)  {
+            sam = fcmult(clip_thresh/mag, sam);
         }
         tx_fdm[i] = sam;
     }
index 478bc4e098cf5d5c35ff126ecc01b3fdddaaa9e6..32cd842b197d757b916d9ddda1b0d43d4c5d479f 100644 (file)
@@ -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"
index 51953e3870c9f5abd9708540fd27373b2e66eda3..4ed510c2fd59abb83e48f88674ac265e3ba288de 100644 (file)
@@ -99,7 +99,7 @@ int main(int argc, char *argv[])
         for(i=0; i<COHPSK_BITS_PER_FRAME*diversity; i++)
             tx_bits[i] = tx_bits_char[i];
        cohpsk_mod(cohpsk, tx_fdm, tx_bits, COHPSK_BITS_PER_FRAME*diversity);
-        cohpsk_clip(tx_fdm);
+        cohpsk_clip(tx_fdm, COHPSK_CLIP, COHPSK_NOM_SAMPLES_PER_FRAME);
 
        /* scale and save to disk as shorts */
 
index f348094b9477e2ec370836ea518c5c92de0cb2b9..15798f734045f66c34647aa8e5b40ce7097a7f83 100644 (file)
@@ -858,8 +858,8 @@ static void freedv_comptx_700(struct freedv *f, COMP mod_out[]) {
     /* cohpsk modulator */
 
     cohpsk_mod(f->cohpsk, 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; i<f->n_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
index adbd2f4593e0c55d05e41d392096b65572b70bf0..7ae44c69b32e6af9162f9e010809fa6b0d5a8a70 100644 (file)
@@ -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);