combined tx filter and up conversion to remove abou 30k of stack in tx_mod. tests...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 13 Aug 2014 22:07:09 +0000 (22:07 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 13 Aug 2014 22:07:09 +0000 (22:07 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1800 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/tfdmdv.m
codec2-dev/src/fdmdv.c
codec2-dev/src/fdmdv_internal.h
codec2-dev/unittest/tfdmdv.c

index ac7186a829155a396b877cb049abc2ec1a5d4bb8..e570416b28b780917caa57e40ab5f3552e7ef163 100644 (file)
@@ -220,13 +220,6 @@ n = 28;
 stem_sig_and_error(1, 211, tx_bits_log_c(1:n), tx_bits_log(1:n) - tx_bits_log_c(1:n), 'tx bits', [1 n -1.5 1.5])
 stem_sig_and_error(1, 212, real(tx_symbols_log_c(1:n/2)), real(tx_symbols_log(1:n/2) - tx_symbols_log_c(1:n/2)), 'tx symbols real', [1 n/2 -1.5 1.5])
 
-% tx_filter()
-
-diff = tx_baseband_log - tx_baseband_log_c;
-c=1;
-plot_sig_and_error(2, 211, real(tx_baseband_log_c(c,:)), real(tx_baseband_log(c,:) - tx_baseband_log_c(c,:)), 'tx baseband real')
-plot_sig_and_error(2, 212, imag(tx_baseband_log_c(c,:)), imag(tx_baseband_log(c,:) - tx_baseband_log_c(c,:)), 'tx baseband imag')
-
 % fdm_upconvert()
 
 plot_sig_and_error(3, 211, real(tx_fdm_log_c), real(tx_fdm_log - tx_fdm_log_c), 'tx fdm real')
@@ -315,7 +308,6 @@ endfunction
 
 check(tx_bits_log, tx_bits_log_c, 'tx_bits');
 check(tx_symbols_log,  tx_symbols_log_c, 'tx_symbols');
-check(tx_baseband_log, tx_baseband_log_c, 'tx_baseband');
 check(tx_fdm_log, tx_fdm_log_c, 'tx_fdm');
 check(pilot_lut, pilot_lut_c, 'pilot_lut');
 check(pilot_coeff, pilot_coeff_c, 'pilot_coeff');
index c6ea6990c9464a4612fd6ff3648ddb1d8d8e56d4..2a91ed1d919a61a1f133b9ea8f230d82e8845669 100644 (file)
@@ -112,7 +112,7 @@ static COMP cadd(COMP a, COMP b)
 
 static float cabsolute(COMP a)
 {
-    return sqrtf(pow(a.real, 2.0) + pow(a.imag, 2.0));
+    return sqrtf(powf(a.real, 2.0) + powf(a.imag, 2.0));
 }
 
 /*---------------------------------------------------------------------------*\
@@ -391,6 +391,7 @@ void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], in
        *pilot_bit = 1;
 }
 
+
 /*---------------------------------------------------------------------------*\
                                                        
   FUNCTION....: tx_filter()         
@@ -452,6 +453,115 @@ void tx_filter(COMP tx_baseband[NC+1][M], int Nc, COMP tx_symbols[], COMP tx_fil
     }
 }
 
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: tx_filter_and_upconvert()           
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 13 August 2014
+
+  Given Nc*NB bits construct M samples (1 symbol) of Nc+1 filtered
+  symbols streams.
+
+\*---------------------------------------------------------------------------*/
+
+void tx_filter_and_upconvert(COMP tx_fdm[], int Nc, COMP tx_symbols[], 
+                             COMP tx_filter_memory[NC+1][NSYM],
+                             COMP phase_tx[], COMP freq[], 
+                             COMP *fbb_phase, COMP fbb_rect)
+{
+    int     c;
+    int     i,j,k;
+    float   acc;
+    COMP    gain;
+    COMP    tx_baseband;
+    COMP  two = {2.0, 0.0};
+    float mag;
+
+    gain.real = sqrtf(2.0)/2.0;
+    gain.imag = 0.0;
+    
+    for(i=0; i<M; i++) {
+       tx_fdm[i].real = 0.0;
+       tx_fdm[i].imag = 0.0;
+    }
+
+    for(c=0; c<Nc+1; c++)
+       tx_filter_memory[c][NSYM-1] = cmult(tx_symbols[c], gain);
+    
+    /* 
+       tx filter each symbol, generate M filtered output samples for
+       each symbol, which we then freq shift and sum with other
+       carriers.  Efficient polyphase filter techniques used as
+       tx_filter_memory is sparse
+    */
+
+    for(c=0; c<Nc+1; c++) {
+        for(i=0; i<M; i++) {
+
+           /* filter real sample of symbol for carrier c */
+
+           acc = 0.0;
+           for(j=0,k=M-i-1; j<NSYM; j++,k+=M)
+               acc += M * tx_filter_memory[c][j].real * gt_alpha5_root[k];
+           tx_baseband.real = acc;     
+
+           /* filter imag sample of symbol for carrier c */
+
+           acc = 0.0;
+           for(j=0,k=M-i-1; j<NSYM; j++,k+=M)
+               acc += M * tx_filter_memory[c][j].imag * gt_alpha5_root[k];
+           tx_baseband.imag = acc;
+
+            /* freq shift and sum */
+
+           phase_tx[c] = cmult(phase_tx[c], freq[c]);
+           tx_fdm[i] = cadd(tx_fdm[i], cmult(tx_baseband, phase_tx[c]));
+       }
+    }
+
+    /* shift whole thing up to carrier freq */
+
+    for (i=0; i<M; i++) {
+       *fbb_phase = cmult(*fbb_phase, fbb_rect);
+       tx_fdm[i] = cmult(tx_fdm[i], *fbb_phase);
+    }
+
+    /*
+      Scale such that total Carrier power C of real(tx_fdm) = Nc.  This
+      excludes the power of the pilot tone.
+      We return the complex (single sided) signal to make frequency
+      shifting for the purpose of testing easier
+    */
+
+    for (i=0; i<M; i++) 
+       tx_fdm[i] = cmult(two, tx_fdm[i]);
+
+    /* normalise digital oscillators as the magnitude can drift over time */
+
+    for (c=0; c<Nc+1; c++) {
+        mag = cabsolute(phase_tx[c]);
+       phase_tx[c].real /= mag;        
+       phase_tx[c].imag /= mag;        
+    }
+
+    mag = cabsolute(*fbb_phase);
+    fbb_phase->real /= mag;    
+    fbb_phase->imag /= mag;    
+
+    /* shift memory, inserting zeros at end */
+
+    for(i=0; i<NSYM-1; i++)
+       for(c=0; c<Nc+1; c++)
+           tx_filter_memory[c][i] = tx_filter_memory[c][i+1];
+
+    for(c=0; c<Nc+1; c++) {
+       tx_filter_memory[c][NSYM-1].real = 0.0;
+       tx_filter_memory[c][NSYM-1].imag = 0.0;
+    }
+}
+
+
 /*---------------------------------------------------------------------------*\
                                                        
   FUNCTION....: fdm_upconvert()             
@@ -499,7 +609,7 @@ void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_
     for (i=0; i<M; i++) 
        tx_fdm[i] = cmult(two, tx_fdm[i]);
 
-    /* normalise digital oscilators as the magnitude can drfift over time */
+    /* normalise digital oscilators as the magnitude can drift over time */
 
     for (c=0; c<Nc+1; c++) {
         mag = cabsolute(phase_tx[c]);
@@ -533,17 +643,14 @@ void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_
 void fdmdv_mod(struct FDMDV *fdmdv, COMP tx_fdm[], int tx_bits[], int *sync_bit)
 {
     COMP          tx_symbols[NC+1];
-    COMP          tx_baseband[NC+1][M];
-    PROFILE_VAR(mod_start, tx_filter_start, fdm_upconvert_start);
+    PROFILE_VAR(mod_start, tx_filter_and_upconvert_start);
 
     PROFILE_SAMPLE(mod_start);
     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));
-    PROFILE_SAMPLE_AND_LOG(tx_filter_start, mod_start, "    bits_to_dqpsk_symbols"); 
-    tx_filter(tx_baseband, fdmdv->Nc, tx_symbols, fdmdv->tx_filter_memory);
-    PROFILE_SAMPLE_AND_LOG(fdm_upconvert_start, tx_filter_start, "    tx_filter"); 
-    fdm_upconvert(tx_fdm, fdmdv->Nc, tx_baseband, fdmdv->phase_tx, fdmdv->freq, &fdmdv->fbb_phase_tx, fdmdv->fbb_rect);
-    PROFILE_SAMPLE_AND_LOG2(fdm_upconvert_start, "    fdm_upconvert"); 
+    PROFILE_SAMPLE_AND_LOG(tx_filter_and_upconvert_start, mod_start, "    bits_to_dqpsk_symbols"); 
+    tx_filter_and_upconvert(tx_fdm, fdmdv->Nc, tx_symbols, fdmdv->tx_filter_memory, 
+                            fdmdv->phase_tx, fdmdv->freq, &fdmdv->fbb_phase_tx, fdmdv->fbb_rect);
 
     *sync_bit = fdmdv->tx_pilot_bit;
 }
index b66ee9ef96a2f5679a5003aecae8c135570292b2..bf1c3a17aef56d409b9c73d341ca2b8e744fdeb5 100644 (file)
@@ -167,6 +167,9 @@ void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], in
 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[],
                    COMP *fbb_phase, COMP fbb_rect);
+void tx_filter_and_upconvert(COMP tx_fdm[], int Nc, COMP tx_symbols[], 
+                             COMP tx_filter_memory[NC+1][NSYM],
+                             COMP phase_tx[], COMP freq[], COMP *fbb_phase, COMP fbb_rect);
 void generate_pilot_fdm(COMP *pilot_fdm, int *bit, float *symbol, float *filter_mem, COMP *phase, COMP *freq);
 void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq);
 float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin);
index 746bc94035be3da6548a9aa767a803609b834561..427a1573d64e8916f44ad4940ff18825fc8d07d3 100644 (file)
@@ -48,7 +48,6 @@ int main(int argc, char *argv[])
     struct FDMDV *fdmdv;
     int           tx_bits[FDMDV_BITS_PER_FRAME];
     COMP          tx_symbols[FDMDV_NC+1];
-    COMP          tx_baseband[NC+1][M];
     COMP          tx_fdm[M];
     float         channel[CHANNEL_BUF_SIZE];
     int           channel_count;
@@ -68,7 +67,6 @@ int main(int argc, char *argv[])
 
     int           tx_bits_log[FDMDV_BITS_PER_FRAME*FRAMES];
     COMP          tx_symbols_log[(FDMDV_NC+1)*FRAMES];
-    COMP          tx_baseband_log[(NC+1)][M*FRAMES];
     COMP          tx_fdm_log[M*FRAMES];
     COMP          pilot_baseband1_log[NPILOTBASEBAND*FRAMES];
     COMP          pilot_baseband2_log[NPILOTBASEBAND*FRAMES];
@@ -115,8 +113,8 @@ int main(int argc, char *argv[])
        fdmdv_get_test_bits(fdmdv, tx_bits);
        bits_to_dqpsk_symbols(tx_symbols, FDMDV_NC, fdmdv->prev_tx_symbols, tx_bits, &fdmdv->tx_pilot_bit, 0);
        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, &fdmdv->fbb_phase_tx, fdmdv->fbb_rect);
+        tx_filter_and_upconvert(tx_fdm, FDMDV_NC , tx_symbols, fdmdv->tx_filter_memory, 
+                                fdmdv->phase_tx, fdmdv->freq, &fdmdv->fbb_phase_tx, fdmdv->fbb_rect);
 
        /* --------------------------------------------------------*\
                                  Channel
@@ -198,9 +196,6 @@ int main(int argc, char *argv[])
 
        memcpy(&tx_bits_log[FDMDV_BITS_PER_FRAME*f], tx_bits, sizeof(int)*FDMDV_BITS_PER_FRAME);
        memcpy(&tx_symbols_log[(FDMDV_NC+1)*f], tx_symbols, sizeof(COMP)*(FDMDV_NC+1));
-       for(c=0; c<FDMDV_NC+1; c++)
-           for(i=0; i<M; i++)
-               tx_baseband_log[c][f*M+i] = tx_baseband[c][i]; 
        memcpy(&tx_fdm_log[M*f], tx_fdm, sizeof(COMP)*M);
 
        memcpy(&pilot_baseband1_log[f*NPILOTBASEBAND], fdmdv->pilot_baseband1, sizeof(COMP)*NPILOTBASEBAND);
@@ -263,8 +258,7 @@ int main(int argc, char *argv[])
     fprintf(fout, "# Created by tfdmdv.c\n");
     octave_save_int(fout, "tx_bits_log_c", tx_bits_log, 1, FDMDV_BITS_PER_FRAME*FRAMES);
     octave_save_complex(fout, "tx_symbols_log_c", tx_symbols_log, 1, (FDMDV_NC+1)*FRAMES, (FDMDV_NC+1)*FRAMES);  
-    octave_save_complex(fout, "tx_baseband_log_c", (COMP*)tx_baseband_log, (FDMDV_NC+1), M*FRAMES, M*FRAMES);  
-    octave_save_complex(fout, "tx_fdm_log_c", (COMP*)tx_fdm_log, 1, M*FRAMES, M*FRAMES);  
+octave_save_complex(fout, "tx_fdm_log_c", (COMP*)tx_fdm_log, 1, M*FRAMES, M*FRAMES);  
     octave_save_complex(fout, "pilot_lut_c", (COMP*)fdmdv->pilot_lut, 1, NPILOT_LUT, NPILOT_LUT);  
     octave_save_complex(fout, "pilot_baseband1_log_c", pilot_baseband1_log, 1, NPILOTBASEBAND*FRAMES, NPILOTBASEBAND*FRAMES);  
     octave_save_complex(fout, "pilot_baseband2_log_c", pilot_baseband2_log, 1, NPILOTBASEBAND*FRAMES, NPILOTBASEBAND*FRAMES);