fixed seg fault issue due to bit errors in delta-time Wo quantiser, first pass at...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 10 May 2012 02:37:17 +0000 (02:37 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 10 May 2012 02:37:17 +0000 (02:37 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@407 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/README_fdmdv.txt
codec2-dev/src/codec2.c
codec2-dev/src/fdmdv.c
codec2-dev/src/fdmdv_internal.h
codec2-dev/src/os.h [new file with mode: 0644]
codec2-dev/src/quantise.c

index 783239fd10e14b742413a72f38125788a710b4a3..301d6ad2dc88cdbe91d04b71fbbf5a1dcb14c3d0 100644 (file)
@@ -165,6 +165,7 @@ This introduces a simulated 1000ppm error:
 TODO
 ----
 
+[ ] 48 kHz to and from 8 kHz routines to drive 48 kHz sound card audio
 [ ] try interfering sine wave
     + maybe swept
     + does modem fall over?
@@ -172,10 +173,10 @@ TODO
     + make sure all estimators keep working
 [ ] test rx level sensitivity, i.e. 0 to 20dB attenuation
 [ ] make fine freq indep of amplitude
-    + use angle rather than imag corrd
+    + use angle rather than imag coord
 [ ] document use of fdmdv_ut and fdmdv_demod + PathSim
-[ ] more positibe form of sync reqd for DV frames?
-    + like using track/acquire bit
+[ ] more positive form of sync reqd for DV frames?
+    + like using coarse_fine==1 to decode valid DV frame bit?
     + when should we start decoding?
 [ ] more robust track/acquite state machine?
     + e.g. hang on thru the fades?
index ad806eca250105f5b6c1a5f07c077263f6f8566b..984b81704ba7ddd11e2bbe9a560f4691fe228c2c 100644 (file)
@@ -739,7 +739,7 @@ void codec2_decode_1500(struct CODEC2 *c2, short speech[], const unsigned char *
   Encodes 320 speech samples (40ms of speech) into 48 bits.  
 
   The codec2 algorithm actually operates internally on 10ms (80
-  sample) frames, so we run the encoding algorithm for times:
+  sample) frames, so we run the encoding algorithm four times:
 
   frame 0: just send voicing bit
   frame 1: predictive vector quantisation of LSPs and Wo and E
@@ -969,10 +969,12 @@ void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char *
     /* decode integer codes to model parameters */
 
     model.Wo = decode_Wo_dt(delta_Wo_index, prev__Wo);
+    assert(model.Wo >= TWO_PI/P_MAX);
+    assert(model.Wo <= TWO_PI/P_MIN);
     model.L = PI/model.Wo;
     memset(&model.A, 0, (model.L+1)*sizeof(model.A[0]));
     energy = decode_energy(energy_index);
-
+    
     /* decode frame 4  */
 
     aks_to_M2(ak, LPC_ORD, &model, energy, &snr, 1); 
index 0efe5e70a43093e0c96f4aaa90aab7e7e54bf9a4..c17ab48358f160ac28f9e554aa7c12eb34d4def2 100644 (file)
@@ -44,6 +44,7 @@
 #include "pilot_coeff.h"
 #include "fft.h"
 #include "hanning.h"
+#include "os.h"
 
 /*---------------------------------------------------------------------------*\
                                                                              
@@ -1170,3 +1171,69 @@ void fdmdv_get_demod_stats(struct FDMDV *fdmdv, struct FDMDV_STATS *fdmdv_stats)
 
 }
 
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: fdmdv_8_to_48()             
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 9 May 2012
+
+  Changes the sample rate of a signal from 8 to 48 kHz.  Experience
+  with PC based modems has shown that PC sound cards have a more
+  accurate sample clock when set for 48 kHz than 8 kHz.
+
+  n is the number of samples at the 8 kHz rate, there are FDMDV_OS*n samples
+  at the 48 kHz rate.  A memory of FDMDV_OS_TAPS/FDMDV_OS samples is reqd for
+  in8k[] (see example).
+
+  This is a classic polyphase upsampler.  We take the 8 kHz samples
+  and insert (FDMDV_OS-1) zeroes between each sample, then
+  FDMDV_OS_TAPS FIR low pass filter the signal at 4kHz.  As most of
+  the input samples are zeroes, we only need to multiply non-zero
+  input samples by filter coefficients.  The zero insertion and
+  filtering are combined in the code below and I'm too lazy to explain
+  it further right now....
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_8_to_48(float out48k[], float in8k[], int n)
+{
+    int i,j,k,l;
+
+    for(i=0; i<n; i++) {
+       for(j=0; j<FDMDV_OS; j++) {
+           out48k[i*FDMDV_OS+j] = 0.0;
+           for(k=0,l=0; k<FDMDV_OS_TAPS; k+=FDMDV_OS,l++)
+               out48k[i*FDMDV_OS+j] += fdmdv_os_filter[k+j]*in8k[i-l];
+           
+       }
+    }  
+}
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: fdmdv_48_to_8()             
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 9 May 2012
+
+  Changes the sample rate of a signal from 48 to 8 kHz.
+  n is the number of samples at the 8 kHz rate, there are FDMDV_OS*n
+  samples at the 48 kHz rate.  As above however a memory of
+  FDMDV_OS_TAPS samples is reqd for in48k[] (see example).
+
+  Low pass filter the 48 kHz signal at 4 kHz using the same filter as
+  the upsampler, then just output every FDMDV_OS-th filtered sample.
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_48_to_8(float out8k[], float in48k[], int n)
+{
+    int i,j;
+
+    for(i=0; i<n; i++) {
+       out8k[i] = 0.0;
+       for(j=0; j<FDMDV_OS_TAPS; j++)
+           out8k[i] += fdmdv_os_filter[j]*in48k[i*FDMDV_OS-j];
+    }
+}
+
index 435244fd9f29210edd0514b9d5ed8283f4a4f60c..6b63a32a0823bb9807b3b2b83d78581d8a08d7d9 100644 (file)
 #define FINE                     1
 #define TRACK_COEFF              0.5
 
+/* 8 to 48 kHz sample rate conversion */
+
+#define FDMDV_OS                 6         /* oversampling rate           */
+#define FDMDV_OS_TAPS           48         /* number of OS filter taps    */
+
 /*---------------------------------------------------------------------------*\
                                                                              
                                STRUCT for States
diff --git a/codec2-dev/src/os.h b/codec2-dev/src/os.h
new file mode 100644 (file)
index 0000000..0dae9bf
--- /dev/null
@@ -0,0 +1,53 @@
+/* Generate using fir1(47,1/6) in Octave */
+
+const float fdmdv_os_filter[]= {
+    -3.55606818e-04,
+    -8.98615286e-04,
+    -1.40119781e-03,
+    -1.71713852e-03,
+    -1.56471179e-03,
+    -6.28128960e-04,
+    1.24522223e-03,
+    3.83138676e-03,
+    6.41309478e-03,
+    7.85893186e-03,
+    6.93514929e-03,
+    2.79361991e-03,
+    -4.51051400e-03,
+    -1.36671853e-02,
+    -2.21034939e-02,
+    -2.64084653e-02,
+    -2.31425052e-02,
+    -9.84218694e-03,
+    1.40648474e-02,
+    4.67316298e-02,
+    8.39615986e-02,
+    1.19925275e-01,
+    1.48381174e-01,
+    1.64097819e-01,
+    1.64097819e-01,
+    1.48381174e-01,
+    1.19925275e-01,
+    8.39615986e-02,
+    4.67316298e-02,
+    1.40648474e-02,
+    -9.84218694e-03,
+    -2.31425052e-02,
+    -2.64084653e-02,
+    -2.21034939e-02,
+    -1.36671853e-02,
+    -4.51051400e-03,
+    2.79361991e-03,
+    6.93514929e-03,
+    7.85893186e-03,
+    6.41309478e-03,
+    3.83138676e-03,
+    1.24522223e-03,
+    -6.28128960e-04,
+    -1.56471179e-03,
+    -1.71713852e-03,
+    -1.40119781e-03,
+    -8.98615286e-04,
+    -3.55606818e-04
+};
+
index eeb484c99d8d45527ab991d2acbe89f5cfb3eec7..ad7e40084b93b20de6fe330472809fcf0c671925 100644 (file)
@@ -830,6 +830,12 @@ float decode_Wo_dt(int index, float prev_Wo)
     step = (Wo_max - Wo_min)/WO_LEVELS;
     Wo   = prev_Wo + step*(index);
 
+    /* bit errors can make us go out of range leading to all sorts of
+       probs like seg faults */
+
+    if (Wo > Wo_max) Wo = Wo_max;
+    if (Wo < Wo_min) Wo = Wo_min;
+
     return Wo;
 }