added support for old and new QPSK mapping, tested new OK
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 7 Mar 2013 04:54:59 +0000 (04:54 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 7 Mar 2013 04:54:59 +0000 (04:54 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1190 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/codec2_fdmdv.h
codec2-dev/src/fdmdv.c
codec2-dev/src/fdmdv_internal.h

index d85b8902b9abe97040f777afb862a97e3c7d3269..0e9ddb3d8e61ae49b23fefd4b51088cf51307e3c 100644 (file)
@@ -92,6 +92,7 @@ struct FDMDV_STATS {
 
 struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc);
 void           CODEC2_WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv_state);
+void           CODEC2_WIN32SUPPORT fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv_state);
 int            CODEC2_WIN32SUPPORT fdmdv_bits_per_frame(struct FDMDV *fdmdv_state);
     
 void           CODEC2_WIN32SUPPORT fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[], int *sync_bit);
index 7762802f16c739c7cf722a22eb01eac74d72a299..9e6799c33de5fe8386a71b0945693e6d57e5794c 100644 (file)
@@ -144,6 +144,8 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc)
        f->rx_test_bits_mem[i] = 0;
     assert((sizeof(test_bits)/sizeof(int)) >= f->ntest_bits);
 
+    f->old_qpsk_mapping = 0;
+
     f->tx_pilot_bit = 0;
 
     for(c=0; c<Nc+1; c++) {
@@ -263,6 +265,12 @@ void CODEC2_WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv)
     free(fdmdv);
 }
 
+
+void CODEC2_WIN32SUPPORT fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv) {
+    fdmdv->old_qpsk_mapping = 1;  
+}
+
+
 int CODEC2_WIN32SUPPORT fdmdv_bits_per_frame(struct FDMDV *fdmdv)
 {
     return (fdmdv->Nc * NB);
@@ -305,12 +313,13 @@ void CODEC2_WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *f, int tx_bits[])
 
 \*---------------------------------------------------------------------------*/
 
-void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], int tx_bits[], int *pilot_bit)
+void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], int tx_bits[], int *pilot_bit, int old_qpsk_mapping)
 {
     int c, msb, lsb;
     COMP j = {0.0,1.0};
 
-    /* map tx_bits to to Nc DQPSK symbols */
+    /* Map tx_bits to to Nc DQPSK symbols.  Note legacy support for
+       old (suboptimal) V0.91 FreeDV mapping */
 
     for(c=0; c<Nc; c++) {
        msb = tx_bits[2*c]; 
@@ -318,11 +327,19 @@ void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], in
        if ((msb == 0) && (lsb == 0))
            tx_symbols[c] = prev_tx_symbols[c];
        if ((msb == 0) && (lsb == 1))
-           tx_symbols[c] = cmult(j, prev_tx_symbols[c]);
-       if ((msb == 1) && (lsb == 0))
-           tx_symbols[c] = cmult(cneg(j),prev_tx_symbols[c]);
-       if ((msb == 1) && (lsb == 1))
-           tx_symbols[c] = cneg(prev_tx_symbols[c]);
+            tx_symbols[c] = cmult(j, prev_tx_symbols[c]);
+       if ((msb == 1) && (lsb == 0)) {
+           if (old_qpsk_mapping)
+                tx_symbols[c] = cneg(prev_tx_symbols[c]);           
+            else
+                tx_symbols[c] = cmult(cneg(j),prev_tx_symbols[c]);
+        }
+       if ((msb == 1) && (lsb == 1)) {
+           if (old_qpsk_mapping)
+                tx_symbols[c] = cmult(cneg(j),prev_tx_symbols[c]);  
+            else
+                tx_symbols[c] = cneg(prev_tx_symbols[c]);
+        }
     }
 
     /* +1 -1 +1 -1 BPSK sync carrier, once filtered becomes (roughly)
@@ -490,7 +507,7 @@ void CODEC2_WIN32SUPPORT fdmdv_mod(struct FDMDV *fdmdv, COMP tx_fdm[],
     COMP          tx_symbols[NC+1];
     COMP          tx_baseband[NC+1][M];
 
-    bits_to_dqpsk_symbols(tx_symbols, fdmdv->Nc, fdmdv->prev_tx_symbols, tx_bits, &fdmdv->tx_pilot_bit);
+    bits_to_dqpsk_symbols(tx_symbols, fdmdv->Nc, fdmdv->prev_tx_symbols, tx_bits, &fdmdv->tx_pilot_bit, fdmdv->old_qpsk_mapping);
     memcpy(fdmdv->prev_tx_symbols, tx_symbols, sizeof(COMP)*(fdmdv->Nc+1));
     tx_filter(tx_baseband, fdmdv->Nc, tx_symbols, fdmdv->tx_filter_memory);
     fdm_upconvert(tx_fdm, fdmdv->Nc, tx_baseband, fdmdv->phase_tx, fdmdv->freq);
@@ -961,7 +978,8 @@ float rx_est_timing(COMP rx_symbols[],
 
 \*---------------------------------------------------------------------------*/
 
-float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[], COMP prev_rx_symbols[], COMP rx_symbols[])
+float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[], COMP prev_rx_symbols[], 
+                   COMP rx_symbols[], int old_qpsk_mapping)
 {
     int   c;
     COMP  pi_on_4;
@@ -987,16 +1005,24 @@ float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[]
     for (c=0; c<Nc; c++) {
       d = phase_difference[c];
       if ((d.real >= 0) && (d.imag >= 0)) {
-         msb = 0; lsb = 0;
+          msb = 0; lsb = 0;
       }
       if ((d.real < 0) && (d.imag >= 0)) {
-         msb = 0; lsb = 1;
+          msb = 0; lsb = 1;
       }
       if ((d.real < 0) && (d.imag < 0)) {
-         msb = 1; lsb = 1;
+          if (old_qpsk_mapping) {
+              msb = 1; lsb = 0;
+          } else {
+              msb = 1; lsb = 1;
+          }
       }
       if ((d.real >= 0) && (d.imag < 0)) {
-         msb = 1; lsb = 0;
+          if (old_qpsk_mapping) {
+              msb = 1; lsb = 1;
+          } else {
+              msb = 1; lsb = 0;
+          }
       }
       rx_bits[2*c] = msb;
       rx_bits[2*c+1] = lsb;
@@ -1283,7 +1309,8 @@ void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
     if (fdmdv->rx_timing < 0)
        *nin -= M/P;
     
-    foff_fine = qpsk_to_bits(rx_bits, sync_bit, fdmdv->Nc, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols);
+    foff_fine = qpsk_to_bits(rx_bits, sync_bit, fdmdv->Nc, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols, 
+                             fdmdv->old_qpsk_mapping);
     memcpy(fdmdv->prev_rx_symbols, rx_symbols, sizeof(COMP)*(fdmdv->Nc+1));
     snr_update(fdmdv->sig_est, fdmdv->noise_est, fdmdv->Nc, fdmdv->phase_difference);
 
index b899e30267e9d143bf977266119c9b60d4d926a9..87fb93c2ba7c48a2d52d2b16dcabc2534885dfaa 100644 (file)
@@ -90,6 +90,7 @@ struct FDMDV {
 
     /* Modulator */
 
+    int  old_qpsk_mapping;
     int  tx_pilot_bit;
     COMP prev_tx_symbols[NC+1];
     COMP tx_filter_memory[NC+1][NSYM];
@@ -151,7 +152,7 @@ struct FDMDV {
 
 \*---------------------------------------------------------------------------*/
 
-void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], int tx_bits[], int *pilot_bit);
+void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], int tx_bits[], int *pilot_bit, int old_qpsk_mapping);
 void tx_filter(COMP tx_baseband[NC+1][M], int Nc, COMP tx_symbols[], COMP tx_filter_memory[NC+1][NSYM]);
 void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq_tx[]);
 void generate_pilot_fdm(COMP *pilot_fdm, int *bit, float *symbol, float *filter_mem, COMP *phase, COMP *freq);
@@ -168,7 +169,7 @@ float rx_est_timing(COMP  rx_symbols[], int Nc,
                   float env[],
                   COMP  rx_baseband_mem_timing[NC+1][NFILTERTIMING], 
                   int   nin);   
-float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[], COMP prev_rx_symbols[], COMP rx_symbols[]);
+float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[], COMP prev_rx_symbols[], COMP rx_symbols[], int old_qpsk_mapping);
 void snr_update(float sig_est[], float noise_est[], int Nc, COMP phase_difference[]);
 int freq_state(int sync_bit, int *state, int *bad_sync);
 float calc_snr(int Nc, float sig_est[], float noise_est[]);