Codec 2 optimised so that one less FFT is rqd, fdmdv C and Octave optimised so freq...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 16 Aug 2014 22:31:22 +0000 (22:31 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 16 Aug 2014 22:31:22 +0000 (22:31 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1806 01035d8c-6547-0410-b346-abe4f91aad63

14 files changed:
codec2-dev/octave/fdmdv.m
codec2-dev/octave/pl2.m
codec2-dev/octave/tfdmdv.m
codec2-dev/src/c2sim.c
codec2-dev/src/codec2.c
codec2-dev/src/fdmdv.c
codec2-dev/src/fdmdv_internal.h
codec2-dev/src/interp.c
codec2-dev/src/phase.c
codec2-dev/src/phase.h
codec2-dev/src/quantise.c
codec2-dev/src/quantise.h
codec2-dev/unittest/tfdmdv.c
codec2-dev/unittest/tlspsens.c

index 0f650eec7f5b527486bc6ced4a78fa7ce766ec6e..c6aaf866d3aca7a7869fe9aa266e3c6251109189 100644 (file)
@@ -391,7 +391,7 @@ endfunction
 
 % LPF and peak pick part of freq est, put in a function as we call it twice
 
-function [foff imax pilot_lpf_out S] = lpf_peak_pick(pilot_baseband, pilot_lpf, nin)
+function [foff imax pilot_lpf_out S] = lpf_peak_pick(pilot_baseband, pilot_lpf, nin, do_fft)
   global M;
   global Npilotlpf;
   global Npilotbaseband;
@@ -409,24 +409,30 @@ function [foff imax pilot_lpf_out S] = lpf_peak_pick(pilot_baseband, pilot_lpf,
     k++;
   end
   
-  % decimate to improve DFT resolution, window and DFT
+  imax = 0;
+  foff = 0;
+  S = zeros(1, Mpilotfft);
 
-  Mpilot = Fs/(2*200);  % calc decimation rate given new sample rate is twice LPF freq
-  h = hanning(Npilotlpf);
-  s = pilot_lpf(1:Mpilot:Npilotlpf) .* h(1:Mpilot:Npilotlpf)';
-  s = [s zeros(1,Mpilotfft-Npilotlpf/Mpilot)];
-  S = fft(s, Mpilotfft);
+  if do_fft
+    % decimate to improve DFT resolution, window and DFT
+
+    Mpilot = Fs/(2*200);  % calc decimation rate given new sample rate is twice LPF freq
+    h = hanning(Npilotlpf);
+    s = pilot_lpf(1:Mpilot:Npilotlpf) .* h(1:Mpilot:Npilotlpf)';
+    s = [s zeros(1,Mpilotfft-Npilotlpf/Mpilot)];
+    S = fft(s, Mpilotfft);
 
-  % peak pick and convert to Hz
+    % peak pick and convert to Hz
 
-  [imax ix] = max(abs(S));
-  r = 2*200/Mpilotfft;     % maps FFT bin to frequency in Hz
+    [imax ix] = max(abs(S));
+    r = 2*200/Mpilotfft;     % maps FFT bin to frequency in Hz
   
-  if ix > Mpilotfft/2
-    foff = (ix - Mpilotfft - 1)*r;
-  else
-    foff = (ix - 1)*r;
-  endif
+    if ix > Mpilotfft/2
+      foff = (ix - Mpilotfft - 1)*r;
+    else
+      foff = (ix - 1)*r;
+    endif
+  end
 
   pilot_lpf_out = pilot_lpf;
 
@@ -436,7 +442,7 @@ endfunction
 % Estimate frequency offset of FDM signal using BPSK pilot.  This is quite
 % sensitive to pilot tone level wrt other carriers
 
-function [foff S1 S2] = rx_est_freq_offset(rx_fdm, pilot, pilot_prev, nin)
+function [foff S1 S2] = rx_est_freq_offset(rx_fdm, pilot, pilot_prev, nin, do_fft)
   global M;
   global Npilotbaseband;
   global pilot_baseband1;
@@ -457,8 +463,8 @@ function [foff S1 S2] = rx_est_freq_offset(rx_fdm, pilot, pilot_prev, nin)
     pilot_baseband2(Npilotbaseband-nin+i) = rx_fdm(i) * conj(pilot_prev(i)); 
   end
 
-  [foff1 max1 pilot_lpf1 S1] = lpf_peak_pick(pilot_baseband1, pilot_lpf1, nin);
-  [foff2 max2 pilot_lpf2 S2] = lpf_peak_pick(pilot_baseband2, pilot_lpf2, nin);
+  [foff1 max1 pilot_lpf1 S1] = lpf_peak_pick(pilot_baseband1, pilot_lpf1, nin, do_fft);
+  [foff2 max2 pilot_lpf2 S2] = lpf_peak_pick(pilot_baseband2, pilot_lpf2, nin, do_fft);
 
   if max1 > max2
     foff = foff1;
index 17671c0857e7d801ea5caaf6a809c64ea8771d78..c7af10ccf5cab13b33f2e5124ec7753011c14b93 100644 (file)
@@ -37,5 +37,8 @@ function pl2(samname1, samname2, start_sam, end_sam, offset)
   figure(2)
   plot(s1(st1:en1)-s2(st2:en2));
   
+  f=fopen("diff.raw","wb");
+  d = s1(st1:en1)-s2(st2:en2);
+  fwrite(f,d,"short");
 
 endfunction
index e570416b28b780917caa57e40ab5f3552e7ef163..1ea15a4666ee060bb2232c884b32a66d29e74071 100644 (file)
@@ -104,7 +104,7 @@ for f=1:frames
   fbb_phase_rx /= mag;
 
   [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, nin);
-  [foff_coarse S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, nin);
+  [foff_coarse S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, nin, !sync);
 
   %sync = 0; % when debugging good idea to uncomment this to "open loop"
 
index 2099320431ad439635818484fa0e04f8d0afac56..dc258ea1714c650d960ea67b8d930d7af6a2e9e7 100644 (file)
@@ -171,7 +171,8 @@ int main(int argc, char *argv[])
         { NULL, no_argument, NULL, 0 }
     };
     int num_opts=sizeof(long_options)/sizeof(struct option);
-    
+    COMP Aw[FFT_ENC];
+
     for(i=0; i<M; i++) {
        Sn[i] = 1.0;
        Sn_pre[i] = 1.0;
@@ -708,7 +709,7 @@ int main(int argc, char *argv[])
 
            }
 
-           aks_to_M2(fft_fwd_cfg, ak, order, &model, e, &snr, 1, simlpcpf, lpcpf, 1, LPCPF_BETA, LPCPF_GAMMA); 
+           aks_to_M2(fft_fwd_cfg, ak, order, &model, e, &snr, 1, simlpcpf, lpcpf, 1, LPCPF_BETA, LPCPF_GAMMA, Aw); 
            apply_lpc_correction(&model);
 
             #ifdef DUMP
@@ -764,8 +765,13 @@ int main(int argc, char *argv[])
 
                interp_model.voiced = voiced1;
                
+                #ifdef FIX_ME
+                /* NOTE: need to get this woking again */
+                interpolate_lsp_ver2(lsps_interp, prev_lsps_,  lsps_, 0.5)
+                    aks_to_M2(fft_fwd_cfg, ak, order, &model, e, &snr, 1, simlpcpf, lpcpf, 1, LPCPF_BETA, LPCPF_GAMMA, Aw); 
                interpolate_lsp(fft_fwd_cfg, &interp_model, &prev_model, &model,
                                prev_lsps_, prev_e, lsps_, e, ak_interp, lsps_interp);          
+                #endif
                apply_lpc_correction(&interp_model);
 
                /* used to compare with c2enc/c2dec version 
@@ -799,8 +805,7 @@ int main(int argc, char *argv[])
                 #endif
 
                if (phase0)
-                   phase_synth_zero_order(fft_fwd_cfg, &interp_model, ak_interp, ex_phase,
-                                          order);      
+                   phase_synth_zero_order(fft_fwd_cfg, &interp_model, ex_phase, Aw);
                if (postfilt)
                    postfilter(&interp_model, &bg_est);
                synth_one_frame(fft_inv_cfg, buf, &interp_model, Sn_, Pn, prede, &de_mem, gain);
@@ -811,7 +816,7 @@ int main(int argc, char *argv[])
                /* decode this frame */
 
                if (phase0)
-                   phase_synth_zero_order(fft_fwd_cfg, &model, ak, ex_phase, order);   
+                   phase_synth_zero_order(fft_fwd_cfg, &model, ex_phase, Aw);  
                if (postfilt)
                    postfilter(&model, &bg_est);
                synth_one_frame(fft_inv_cfg, buf, &model, Sn_, Pn, prede, &de_mem, gain);
@@ -834,7 +839,7 @@ int main(int argc, char *argv[])
            /* no decimation - sythesise each 10ms frame immediately */
            
            if (phase0)
-               phase_synth_zero_order(fft_fwd_cfg, &model, ak, ex_phase, order);           
+               phase_synth_zero_order(fft_fwd_cfg, &model, ex_phase, Aw);          
 
            if (postfilt)
                postfilter(&model, &bg_est);
index bdb827c197f99053615dbba19cbb56bd717c8e84..7867911248db1c67717e47763a68cf47efb8e16b 100644 (file)
@@ -54,7 +54,7 @@
 
 void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]);
 void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model,
-                         float ak[]);
+                         COMP Aw[]);
 void codec2_encode_3200(struct CODEC2 *c2, unsigned char * bits, short speech[]);
 void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char * bits);
 void codec2_encode_2400(struct CODEC2 *c2, unsigned char * bits, short speech[]);
@@ -368,6 +368,7 @@ void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char *
     float   ak[2][LPC_ORD+1];
     int     i,j;
     unsigned int nbit = 0;
+    COMP    Aw[2][FFT_ENC];
 
     assert(c2 != NULL);
     
@@ -412,14 +413,14 @@ void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char *
     for(i=0; i<2; i++) {
        lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
        aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, 
-                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); 
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, &Aw[i][0]); 
        apply_lpc_correction(&model[i]);
     }
 
     /* synthesise ------------------------------------------------*/
 
     for(i=0; i<2; i++)
-       synthesise_one_frame(c2, &speech[N*i], &model[i], &ak[i][0]);
+       synthesise_one_frame(c2, &speech[N*i], &model[i], &Aw[i][0]);
 
     /* update memories for next frame ----------------------------*/
 
@@ -516,6 +517,7 @@ void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char *
     float   ak[2][LPC_ORD+1];
     int     i,j;
     unsigned int nbit = 0;
+    COMP    Aw[2][FFT_ENC];
 
     assert(c2 != NULL);
     
@@ -558,14 +560,14 @@ void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char *
     for(i=0; i<2; i++) {
        lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
        aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, 
-                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); 
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, &Aw[i][0]); 
        apply_lpc_correction(&model[i]);
     }
 
     /* synthesise ------------------------------------------------*/
 
     for(i=0; i<2; i++)
-       synthesise_one_frame(c2, &speech[N*i], &model[i], &ak[i][0]);
+       synthesise_one_frame(c2, &speech[N*i], &model[i], &Aw[i][0]);
 
     /* update memories for next frame ----------------------------*/
 
@@ -685,6 +687,7 @@ void codec2_decode_1600(struct CODEC2 *c2, short speech[], const unsigned char *
     int     i,j;
     unsigned int nbit = 0;
     float   weight;
+    COMP    Aw[4][FFT_ENC];
     
     assert(c2 != NULL);
 
@@ -745,14 +748,14 @@ void codec2_decode_1600(struct CODEC2 *c2, short speech[], const unsigned char *
     for(i=0; i<4; i++) {
        lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
        aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
-                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); 
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, &Aw[i][0]); 
        apply_lpc_correction(&model[i]);
     }
 
     /* synthesise ------------------------------------------------*/
 
     for(i=0; i<4; i++)
-       synthesise_one_frame(c2, &speech[N*i], &model[i], &ak[i][0]);
+       synthesise_one_frame(c2, &speech[N*i], &model[i], &Aw[i][0]);
 
     /* update memories for next frame ----------------------------*/
 
@@ -866,6 +869,7 @@ void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char *
     int     i,j;
     unsigned int nbit = 0;
     float   weight;
+    COMP    Aw[4][FFT_ENC];
 
     assert(c2 != NULL);
 
@@ -918,14 +922,14 @@ void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char *
     for(i=0; i<4; i++) {
        lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
        aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
-                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); 
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, &Aw[i][0]); 
        apply_lpc_correction(&model[i]);
     }
 
     /* synthesise ------------------------------------------------*/
 
     for(i=0; i<4; i++)
-       synthesise_one_frame(c2, &speech[N*i], &model[i], &ak[i][0]);
+       synthesise_one_frame(c2, &speech[N*i], &model[i], &Aw[i][0]);
 
     /* update memories for next frame ----------------------------*/
 
@@ -1046,6 +1050,7 @@ void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char *
     int     i,j;
     unsigned int nbit = 0;
     float   weight;
+    COMP    Aw[4][FFT_ENC];
     PROFILE_VAR(recover_start);
     
     assert(c2 != NULL);
@@ -1104,7 +1109,7 @@ void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char *
     for(i=0; i<4; i++) {
        lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
        aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
-                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); 
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, &Aw[i][0]); 
        apply_lpc_correction(&model[i]);
     }
     PROFILE_SAMPLE_AND_LOG2(recover_start, "    recover"); 
@@ -1116,7 +1121,7 @@ void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char *
     /* synthesise ------------------------------------------------*/
 
     for(i=0; i<4; i++)
-       synthesise_one_frame(c2, &speech[N*i], &model[i], &ak[i][0]);
+       synthesise_one_frame(c2, &speech[N*i], &model[i], &Aw[i][0]);
 
     /* update memories for next frame ----------------------------*/
 
@@ -1235,6 +1240,7 @@ void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char *
     int     i,j;
     unsigned int nbit = 0;
     float   weight;
+    COMP    Aw[4][FFT_ENC];
 
     assert(c2 != NULL);
 
@@ -1287,14 +1293,14 @@ void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char *
     for(i=0; i<4; i++) {
        lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
        aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
-                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); 
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, &Aw[i][0]); 
        apply_lpc_correction(&model[i]);
     }
 
     /* synthesise ------------------------------------------------*/
 
     for(i=0; i<4; i++)
-       synthesise_one_frame(c2, &speech[N*i], &model[i], &ak[i][0]);
+       synthesise_one_frame(c2, &speech[N*i], &model[i], &Aw[i][0]);
 
     /* update memories for next frame ----------------------------*/
 
@@ -1315,7 +1321,7 @@ void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char *
 
 \*---------------------------------------------------------------------------*/
 
-void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, float ak[])
+void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, COMP Aw[])
 {
     int     i;
     PROFILE_VAR(phase_start, pf_start, synth_start);
@@ -1326,7 +1332,7 @@ void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, float
 
     PROFILE_SAMPLE(phase_start);
 
-    phase_synth_zero_order(c2->fft_fwd_cfg, model, ak, &c2->ex_phase, LPC_ORD);
+    phase_synth_zero_order(c2->fft_fwd_cfg, model, &c2->ex_phase, Aw);
 
     PROFILE_SAMPLE_AND_LOG(pf_start, phase_start, "    phase_synth"); 
 
index 3090aa28742c1f9b8c2857aa53f616355c6f07e9..238abd3fd1ec90c5a217bd12520a89e231af4cc2 100644 (file)
@@ -756,7 +756,8 @@ void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq)
 \*---------------------------------------------------------------------------*/
 
 void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], 
-                  COMP pilot_lpf[], kiss_fft_cfg fft_pilot_cfg, COMP S[], int nin)
+                  COMP pilot_lpf[], kiss_fft_cfg fft_pilot_cfg, COMP S[], int nin,
+                   int do_fft)
 {
     int   i,j,k;
     int   mpilot;
@@ -775,35 +776,49 @@ void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[],
            pilot_lpf[i] = cadd(pilot_lpf[i], fcmult(pilot_coeff[k], pilot_baseband[j-NPILOTCOEFF+1+k]));
     }
 
-    /* decimate to improve DFT resolution, window and DFT */
+    /* We only need to do FFTs if we are out of sync.  Making them optional saves CPU in sync, which is when
+       we need to run the codec */
 
-    mpilot = FS/(2*200);  /* calc decimation rate given new sample rate is twice LPF freq */
+    imax = 0.0;
+    *foff = 0.0;
     for(i=0; i<MPILOTFFT; i++) {
-       s[i].real = 0.0; s[i].imag = 0.0;
-    }
-    for(i=0,j=0; i<NPILOTLPF; i+=mpilot,j++) {
-       s[j] = fcmult(hanning[i], pilot_lpf[i]); 
+        S[i].real = 0.0;
+        S[i].imag = 0.0;
     }
 
-    kiss_fft(fft_pilot_cfg, (kiss_fft_cpx *)s, (kiss_fft_cpx *)S);
+    if (do_fft) {
+        
+        /* decimate to improve DFT resolution, window and DFT */
 
-    /* peak pick and convert to Hz */
+        mpilot = FS/(2*200);  /* calc decimation rate given new sample rate is twice LPF freq */
+        for(i=0; i<MPILOTFFT; i++) {
+            s[i].real = 0.0; s[i].imag = 0.0;
+        }
+        for(i=0,j=0; i<NPILOTLPF; i+=mpilot,j++) {
+            s[j] = fcmult(hanning[i], pilot_lpf[i]); 
+        }
 
-    imax = 0.0;
-    ix = 0;
-    for(i=0; i<MPILOTFFT; i++) {
-       mag = S[i].real*S[i].real + S[i].imag*S[i].imag;
-       if (mag > imax) {
-           imax = mag;
-           ix = i;
-       }
-    }
-    r = 2.0*200.0/MPILOTFFT;     /* maps FFT bin to frequency in Hz */
+        kiss_fft(fft_pilot_cfg, (kiss_fft_cpx *)s, (kiss_fft_cpx *)S);
+
+        /* peak pick and convert to Hz */
+
+        imax = 0.0;
+        ix = 0;
+        for(i=0; i<MPILOTFFT; i++) {
+            mag = S[i].real*S[i].real + S[i].imag*S[i].imag;
+            if (mag > imax) {
+                imax = mag;
+                ix = i;
+            }
+        }
+        r = 2.0*200.0/MPILOTFFT;     /* maps FFT bin to frequency in Hz */
   
-    if (ix >= MPILOTFFT/2)
-       *foff = (ix - MPILOTFFT)*r;
-    else
-       *foff = (ix)*r;
+        if (ix >= MPILOTFFT/2)
+            *foff = (ix - MPILOTFFT)*r;
+        else
+            *foff = (ix)*r;
+    }
+
     *max = imax;
 
 }
@@ -820,7 +835,7 @@ void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[],
 
 \*---------------------------------------------------------------------------*/
 
-float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin)
+float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin, int do_fft)
 {
     int  i,j;
     COMP pilot[M+M/P];
@@ -862,8 +877,8 @@ float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin)
        f->pilot_baseband2[j] = cmult(rx_fdm[i], cconj(prev_pilot[i]));
     }
 
-    lpf_peak_pick(&foff1, &max1, f->pilot_baseband1, f->pilot_lpf1, f->fft_pilot_cfg, f->S1, nin);
-    lpf_peak_pick(&foff2, &max2, f->pilot_baseband2, f->pilot_lpf2, f->fft_pilot_cfg, f->S2, nin);
+    lpf_peak_pick(&foff1, &max1, f->pilot_baseband1, f->pilot_lpf1, f->fft_pilot_cfg, f->S1, nin, do_fft);
+    lpf_peak_pick(&foff2, &max2, f->pilot_baseband2, f->pilot_lpf2, f->fft_pilot_cfg, f->S2, nin, do_fft);
 
     if (max1 > max2)
        foff = foff1;
@@ -1577,7 +1592,7 @@ void fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
     /* freq offset estimation and correction */
    
     PROFILE_SAMPLE(demod_start);
-    foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm_bb, *nin);
+    foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm_bb, *nin, !fdmdv->sync);
     PROFILE_SAMPLE_AND_LOG(fdmdv_freq_shift_start, demod_start, "    rx_est_freq_offset"); 
     
     if (fdmdv->sync == 0)
index bf1c3a17aef56d409b9c73d341ca2b8e744fdeb5..97011e8d9de415d177ff51ec2b87d0b0408964ad 100644 (file)
@@ -172,8 +172,8 @@ void tx_filter_and_upconvert(COMP tx_fdm[], int Nc, COMP tx_symbols[],
                              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);
-void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], kiss_fft_cfg fft_pilot_cfg, COMP S[], int nin);
+float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin, int do_fft);
+void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], kiss_fft_cfg fft_pilot_cfg, COMP S[], int nin, int do_fft);
 void fdm_downconvert(COMP rx_baseband[NC+1][M+M/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin);
 void rxdec_filter(COMP rx_fdm_filter[], COMP rx_fdm[], COMP rxdec_lpf_mem[], int nin);
 void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M+M/P], COMP rx_filter_memory[NC+1][NFILTER], int nin);
index e712a46ee58ab98ef3b4dcb79f6207c3a453bb0b..d2f1e7bb1188e248e3846edec9fdaa9a114f8e3b 100644 (file)
@@ -129,6 +129,8 @@ float sample_log_amp(MODEL *model, float w)
     return log_amp;
 }
 
+#ifdef NOT_NEEDED
+
 /*---------------------------------------------------------------------------*\
 
   FUNCTION....: interp_lsp()        
@@ -204,7 +206,7 @@ void interpolate_lsp(
     aks_to_M2(fft_fwd_cfg, ak_interp, LPC_ORD, interp, e, &snr, 0, 0, 1, 1, LPCPF_BETA, LPCPF_GAMMA); 
     //printf("  interp: ak[1]: %f A[1] %f\n", ak_interp[1], interp->A[1]);
 }
-
+#endif
 
 /*---------------------------------------------------------------------------*\
 
index e1476862f9072f68d2295ec05bb7a43576b84f62..08a2cf41bc774e2930b103bf811eea1f913ea908 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 
-/*---------------------------------------------------------------------------*\
-
-  aks_to_H()
-
-  Samples the complex LPC synthesis filter spectrum at the harmonic
-  frequencies.
-
-\*---------------------------------------------------------------------------*/
-
-void aks_to_H(
-              kiss_fft_cfg fft_fwd_cfg, 
-             MODEL *model,     /* model parameters */
-             float  aks[],     /* LPC's */
-             float  G,         /* energy term */
-             COMP   H[],       /* complex LPC spectral samples */
-             int    order
-)
-{
-  COMP  pw[FFT_ENC];   /* power spectrum (input) */
-  COMP  Pw[FFT_ENC];   /* power spectrum (output) */
-  int   i,m;           /* loop variables */
-  int   am,bm;         /* limits of current band */
-  float r;             /* no. rads/bin */
-  float Em;            /* energy in band */
-  float Am;            /* spectral amplitude sample */
-  int   b;             /* centre bin of harmonic */
-  float phi_;          /* phase of LPC spectra */
-
-  r = TWO_PI/(FFT_ENC);
-
-  /* Determine DFT of A(exp(jw)) ------------------------------------------*/
-
-  for(i=0; i<FFT_ENC; i++) {
-    pw[i].real = 0.0;
-    pw[i].imag = 0.0;
-  }
-
-  for(i=0; i<=order; i++)
-    pw[i].real = aks[i];
-
-  kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)pw, (kiss_fft_cpx *)Pw);
-
-  /* Sample magnitude and phase at harmonics */
-
-  for(m=1; m<=model->L; m++) {
-      am = (int)((m - 0.5)*model->Wo/r + 0.5);
-      bm = (int)((m + 0.5)*model->Wo/r + 0.5);
-      b = (int)(m*model->Wo/r + 0.5);
-      
-      Em = 0.0;
-      for(i=am; i<bm; i++)
-          Em += G/(Pw[i].real*Pw[i].real + Pw[i].imag*Pw[i].imag);
-      Am = sqrtf(fabsf(Em/(bm-am)));
-
-      phi_ = -atan2f(Pw[b].imag,Pw[b].real);
-      H[m].real = Am*cosf(phi_);
-      H[m].imag = Am*sinf(phi_);
-  }
-}
-
 
 /*---------------------------------------------------------------------------*\
 
@@ -191,63 +131,69 @@ void aks_to_H(
 void phase_synth_zero_order(
     kiss_fft_cfg fft_fwd_cfg,     
     MODEL *model,
-    float  aks[],
     float *ex_phase,            /* excitation phase of fundamental */
-    int    order
+    COMP   A[]
 )
 {
-  int   m;
-  float new_phi;
-  COMP  Ex[MAX_AMP+1];         /* excitation samples */
-  COMP  A_[MAX_AMP+1];         /* synthesised harmonic samples */
-  COMP  H[MAX_AMP+1];           /* LPC freq domain samples */
-  float G;
-
-  G = 1.0;
-  aks_to_H(fft_fwd_cfg, model, aks, G, H, order);
-
-  /* 
-     Update excitation fundamental phase track, this sets the position
-     of each pitch pulse during voiced speech.  After much experiment
-     I found that using just this frame's Wo improved quality for UV
-     sounds compared to interpolating two frames Wo like this:
+    int   m, b;
+    float phi_, new_phi, r;
+    COMP  Ex[MAX_AMP+1];         /* excitation samples */
+    COMP  A_[MAX_AMP+1];         /* synthesised harmonic samples */
+    COMP  H[MAX_AMP+1];           /* LPC freq domain samples */
+
+    r = TWO_PI/(FFT_ENC);
+
+    /* Sample phase at harmonics */
+
+    for(m=1; m<=model->L; m++) {
+        b = (int)(m*model->Wo/r + 0.5);
+        phi_ = -atan2f(A[b].imag, A[b].real);
+        H[m].real = cosf(phi_);
+        H[m].imag = sinf(phi_);
+    }
+
+    /* 
+       Update excitation fundamental phase track, this sets the position
+       of each pitch pulse during voiced speech.  After much experiment
+       I found that using just this frame's Wo improved quality for UV
+       sounds compared to interpolating two frames Wo like this:
      
-     ex_phase[0] += (*prev_Wo+model->Wo)*N/2;
-  */
+       ex_phase[0] += (*prev_Wo+model->Wo)*N/2;
+    */
   
-  ex_phase[0] += (model->Wo)*N;
-  ex_phase[0] -= TWO_PI*floorf(ex_phase[0]/TWO_PI + 0.5);
+    ex_phase[0] += (model->Wo)*N;
+    ex_phase[0] -= TWO_PI*floorf(ex_phase[0]/TWO_PI + 0.5);
 
-  for(m=1; m<=model->L; m++) {
+    for(m=1; m<=model->L; m++) {
       
-    /* generate excitation */
+        /* generate excitation */
            
-      if (model->voiced) {
+        if (model->voiced) {
 
-       Ex[m].real = cosf(ex_phase[0]*m);
-       Ex[m].imag = sinf(ex_phase[0]*m);
-    }
-    else {
-
-       /* When a few samples were tested I found that LPC filter
-          phase is not needed in the unvoiced case, but no harm in
-          keeping it.
-        */
-       float phi = TWO_PI*(float)codec2_rand()/CODEC2_RAND_MAX;
-        Ex[m].real = cosf(phi);
-       Ex[m].imag = sinf(phi);
-    }
+            Ex[m].real = cosf(ex_phase[0]*m);
+            Ex[m].imag = sinf(ex_phase[0]*m);
+        }
+        else {
+
+            /* When a few samples were tested I found that LPC filter
+               phase is not needed in the unvoiced case, but no harm in
+               keeping it.
+            */
+            float phi = TWO_PI*(float)codec2_rand()/CODEC2_RAND_MAX;
+            Ex[m].real = cosf(phi);
+            Ex[m].imag = sinf(phi);
+        }
 
-    /* filter using LPC filter */
+        /* filter using LPC filter */
 
-    A_[m].real = H[m].real*Ex[m].real - H[m].imag*Ex[m].imag;
-    A_[m].imag = H[m].imag*Ex[m].real + H[m].real*Ex[m].imag;
+        A_[m].real = H[m].real*Ex[m].real - H[m].imag*Ex[m].imag;
+        A_[m].imag = H[m].imag*Ex[m].real + H[m].real*Ex[m].imag;
 
-    /* modify sinusoidal phase */
+        /* modify sinusoidal phase */
    
-    new_phi = atan2f(A_[m].imag, A_[m].real+1E-12);
-    model->phi[m] = new_phi;
-  }
+        new_phi = atan2f(A_[m].imag, A_[m].real+1E-12);
+        model->phi[m] = new_phi;
+    }
 
 }
 
index 367948dffb843a0b971aee8d274af9b934f1672f..03e1c5079072413ddb13423ba83dae02185da12c 100644 (file)
 #define __PHASE__
 
 #include "kiss_fft.h"
+#include "comp.h"
 
 void phase_synth_zero_order(kiss_fft_cfg fft_dec_cfg, 
                            MODEL *model, 
-                           float aks[], 
-                            float *ex_phase, 
-                           int order);
+                            float *ex_phase,
+                            COMP   A[]);
 
 #endif
index b4d3b31bda7b04005d2366613aead12fe00f9dda..23f2660e52208b396d4226860190d205a39863b4 100644 (file)
@@ -789,7 +789,6 @@ void lpc_post_filter(kiss_fft_cfg fft_fwd_cfg, COMP Pw[], float ak[],
 {
     int   i;
     COMP  x[FFT_ENC];   /* input to FFTs                */
-    COMP  Aw[FFT_ENC];  /* LPC analysis filter spectrum */     
     COMP  Ww[FFT_ENC];  /* weighting spectrum           */
     float Rw[FFT_ENC];  /* R = WA                       */
     float e_before, e_after, gain;
@@ -907,10 +906,11 @@ void aks_to_M2(
   int           pf,          /* true to LPC post filter */
   int           bass_boost,  /* enable LPC filter 0-1khz 3dB boost */
   float         beta,
-  float         gamma        /* LPC post filter parameters */
+  float         gamma,       /* LPC post filter parameters */
+  COMP          Aw[]         /* output power spectrum */
 )
 {
-  COMP pw[FFT_ENC];    /* input to FFT for power spectrum */
+  COMP a[FFT_ENC];     /* input to FFT for power spectrum */
   COMP Pw[FFT_ENC];    /* output power spectrum */
   int i,m;             /* loop variables */
   int am,bm;           /* limits of current band */
@@ -927,20 +927,22 @@ void aks_to_M2(
   /* Determine DFT of A(exp(jw)) --------------------------------------------*/
 
   for(i=0; i<FFT_ENC; i++) {
-    pw[i].real = 0.0;
-    pw[i].imag = 0.0; 
+    a[i].real = 0.0;
+    a[i].imag = 0.0; 
+    Pw[i].real = 0.0;
+    Pw[i].imag = 0.0;
   }
 
   for(i=0; i<=order; i++)
-    pw[i].real = ak[i];
-  kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)pw, (kiss_fft_cpx *)Pw);
-  
+    a[i].real = ak[i];
+  kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)a, (kiss_fft_cpx *)Aw);
+
   PROFILE_SAMPLE_AND_LOG(tfft, tstart, "      fft"); 
 
   /* Determine power spectrum P(w) = E/(A(exp(jw))^2 ------------------------*/
 
   for(i=0; i<FFT_ENC/2; i++)
-    Pw[i].real = 1.0/(Pw[i].real*Pw[i].real + Pw[i].imag*Pw[i].imag);
+    Pw[i].real = 1.0/(Aw[i].real*Aw[i].real + Aw[i].imag*Aw[i].imag);
 
   PROFILE_SAMPLE_AND_LOG(tpw, tfft, "      Pw"); 
 
index 7e8b3836e22a5a2c2af37283830d1ca06985f37e..d714106793db884288270c6ababa84ed01d30845 100644 (file)
@@ -27,6 +27,7 @@
 #define __QUANTISE__
 
 #include "kiss_fft.h"
+#include "comp.h"
 
 #define WO_BITS     7
 #define WO_LEVELS   (1<<WO_BITS)
@@ -57,7 +58,7 @@ float lpc_model_amplitudes(float Sn[], float w[], MODEL *model, int order,
                           int lsp,float ak[]);
 void aks_to_M2(kiss_fft_cfg fft_fwd_cfg, float ak[], int order, MODEL *model, 
               float E, float *snr, int dump, int sim_pf, 
-               int pf, int bass_boost, float beta, float gamma);
+               int pf, int bass_boost, float beta, float gamma, COMP Aw[]);
 
 int   encode_Wo(float Wo);
 float decode_Wo(int index);
index 427a1573d64e8916f44ad4940ff18825fc8d07d3..8ae5ccaa83aed9d6b13460f91fec5977f6e7f6a0 100644 (file)
@@ -154,10 +154,10 @@ int main(int argc, char *argv[])
 
        /* freq offset estimation and correction */
 
-       foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm, nin);
-
         //fdmdv->sync = 0; // when debugging good idea to uncomment this to "open loop"
 
+       foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm, nin, !fdmdv->sync);
+
        if (fdmdv->sync == 0)
            fdmdv->foff = foff_coarse;
        fdmdv_freq_shift(rx_fdm_fcorr, rx_fdm, -fdmdv->foff, &fdmdv->foff_phase_rect, nin);
index a53a66cd9af8f7c777fcdca58748d238a637cd94..4200d5705306b52edba16dd5e11391ee693c73d9 100644 (file)
@@ -50,6 +50,7 @@ float run_a_test(char raw_file_name[], int bit_to_corrupt)
     int     lsp_indexes[LPC_ORD], found_bit;
     float   snr, snr_sum;
     int     frames, i, mask, index;
+    COMP    Aw[FFT_ENC];
 
     c2 = codec2_create(CODEC2_MODE_2400);
     fft_fwd_cfg = kiss_fft_alloc(FFT_ENC, 0, NULL, NULL);
@@ -93,7 +94,7 @@ float run_a_test(char raw_file_name[], int bit_to_corrupt)
        check_lsp_order(lsps, LPC_ORD);
        bw_expand_lsps(lsps, LPC_ORD, 50.0, 100.0);
        lsp_to_lpc(lsps, ak, LPC_ORD);
-       aks_to_M2(fft_fwd_cfg, ak, LPC_ORD, &model, e, &snr, 0, 0, 1, 1, LPCPF_BETA, LPCPF_GAMMA); 
+       aks_to_M2(fft_fwd_cfg, ak, LPC_ORD, &model, e, &snr, 0, 0, 1, 1, LPCPF_BETA, LPCPF_GAMMA, Aw); 
        snr_sum += snr;
        frames++;
     }