[FFmpeg-cvslog] r15901 - in trunk/libavcodec: qcelpdata.h qcelpdec.c

vitor subversion
Fri Nov 21 19:39:17 CET 2008


Author: vitor
Date: Fri Nov 21 19:39:16 2008
New Revision: 15901

Log:
More OKed parts of the QCELP decoder
patch by Kenan Gillet, kenan.gillet gmail com


Modified:
   trunk/libavcodec/qcelpdata.h
   trunk/libavcodec/qcelpdec.c

Modified: trunk/libavcodec/qcelpdata.h
==============================================================================
--- trunk/libavcodec/qcelpdata.h	(original)
+++ trunk/libavcodec/qcelpdata.h	Fri Nov 21 19:39:16 2008
@@ -391,6 +391,16 @@ static const qcelp_vector * const qcelp_
 #define QCELP_SCALE 8192.
 
 /**
+ * the upper boundary of the clipping, depends on QCELP_SCALE
+ */
+#define QCELP_CLIP_UPPER_BOUND (8191.75/8192.)
+
+/**
+ * the lower boundary of the clipping, depends on QCELP_SCALE
+ */
+#define QCELP_CLIP_LOWER_BOUND -1.
+
+/**
  * table for computing Ga (decoded linear codebook gain magnitude)
  *
  * @note The table could fit in int16_t in x*8 form, but it seems
@@ -470,7 +480,7 @@ static const int8_t qcelp_rate_half_code
 /**
  * sqrt(1.887) is the maximum of the pseudorandom
  * white sequence used to generate the scaled codebook
- * vector for framerate 1/4.
+ * vector for bitrate 1/4.
  *
  * TIA/EIA/IS-733 2.4.8.1.2
  */
@@ -478,7 +488,7 @@ static const int8_t qcelp_rate_half_code
 
 /**
  * table for impulse response of BPF used to filter
- * the white excitation for framerate 1/4 synthesis
+ * the white excitation for bitrate 1/4 synthesis
  *
  * Only half the tables are needed because of symmetry.
  *
@@ -490,4 +500,20 @@ static const double qcelp_rnd_fir_coefs[
   -9.918777e-2, 3.749518e-2,  8.985137e-1
 };
 
+/**
+ * This spread factor is used, for bitrate 1/8 and I_F_Q,
+ * to force the LSP frequencies to be at least 80 Hz apart.
+ *
+ * TIA/EIA/IS-733 2.4.3.3.2
+ */
+#define QCELP_LSP_SPREAD_FACTOR 0.02
+
+/**
+ * predictor coefficient for the conversion of LSP codes
+ * to LSP frequencies for 1/8 and I_F_Q
+ *
+ * TIA/EIA/IS-733 2.4.3.2.7-2
+ */
+#define QCELP_LSP_OCTAVE_PREDICTOR 29.0/32
+
 #endif /* AVCODEC_QCELPDATA_H */

Modified: trunk/libavcodec/qcelpdec.c
==============================================================================
--- trunk/libavcodec/qcelpdec.c	(original)
+++ trunk/libavcodec/qcelpdec.c	Fri Nov 21 19:39:16 2008
@@ -69,6 +69,116 @@ static av_cold int qcelp_decode_init(AVC
 }
 
 /**
+ * Decodes the 10 quantized LSP frequencies from the LSPV/LSP
+ * transmission codes of any bitrate and checks for badly received packets.
+ *
+ * @param q the context
+ * @param lspf line spectral pair frequencies
+ *
+ * @return 0 on success, -1 if the packet is badly received
+ *
+ * TIA/EIA/IS-733 2.4.3.2.6.2-2, 2.4.8.7.3
+ */
+static int decode_lspf(QCELPContext *q,
+                       float *lspf) {
+    int i;
+    float tmp_lspf;
+
+    if (q->bitrate == RATE_OCTAVE ||
+        q->bitrate == I_F_Q) {
+        float smooth;
+        const float *predictors = (q->prev_bitrate != RATE_OCTAVE &&
+                                   q->prev_bitrate != I_F_Q ? q->prev_lspf
+                                                            : q->predictor_lspf);
+
+        if (q->bitrate == RATE_OCTAVE) {
+            q->octave_count++;
+
+            for (i = 0; i < 10; i++) {
+                q->predictor_lspf[i] =
+                             lspf[i] = (q->lspv[i] ?  QCELP_LSP_SPREAD_FACTOR
+                                                   : -QCELP_LSP_SPREAD_FACTOR)
+                                     + predictors[i] * QCELP_LSP_OCTAVE_PREDICTOR
+                                     + (i + 1) * ((1 - QCELP_LSP_OCTAVE_PREDICTOR)/11);
+            }
+            smooth = (q->octave_count < 10 ? .875 : 0.1);
+        } else {
+            float erasure_coeff = QCELP_LSP_OCTAVE_PREDICTOR;
+
+            assert(q->bitrate == I_F_Q);
+
+            if (q->erasure_count > 1)
+                erasure_coeff *= (q->erasure_count < 4 ? 0.9 : 0.7);
+
+            for (i = 0; i < 10; i++) {
+                q->predictor_lspf[i] =
+                             lspf[i] = (i + 1) * ( 1 - erasure_coeff)/11
+                                     + erasure_coeff * predictors[i];
+            }
+            smooth = 0.125;
+        }
+
+        // Check the stability of the LSP frequencies.
+        lspf[0] = FFMAX(lspf[0], QCELP_LSP_SPREAD_FACTOR);
+        for (i = 1; i < 10; i++)
+            lspf[i] = FFMAX(lspf[i], (lspf[i-1] + QCELP_LSP_SPREAD_FACTOR));
+
+        lspf[9] = FFMIN(lspf[9], (1.0 - QCELP_LSP_SPREAD_FACTOR));
+        for (i = 9; i > 0; i--)
+            lspf[i-1] = FFMIN(lspf[i-1], (lspf[i] - QCELP_LSP_SPREAD_FACTOR));
+
+        // Low-pass filter the LSP frequencies.
+        weighted_vector_sumf(lspf, lspf, q->prev_lspf, smooth, 1.0 - smooth, 10);
+    } else {
+        q->octave_count = 0;
+
+        tmp_lspf = 0.;
+        for (i = 0; i < 5 ; i++) {
+            lspf[2*i+0] = tmp_lspf += qcelp_lspvq[i][q->lspv[i]][0] * 0.0001;
+            lspf[2*i+1] = tmp_lspf += qcelp_lspvq[i][q->lspv[i]][1] * 0.0001;
+        }
+
+        // Check for badly received packets.
+        if (q->bitrate == RATE_QUARTER) {
+            if (lspf[9] <= .70 || lspf[9] >=  .97)
+                return -1;
+            for (i = 3; i < 10; i++)
+                if (fabs(lspf[i] - lspf[i-2]) < .08)
+                    return -1;
+        } else {
+            if (lspf[9] <= .66 || lspf[9] >= .985)
+                return -1;
+            for (i = 4; i < 10; i++)
+                if (fabs(lspf[i] - lspf[i-4]) < .0931)
+                    return -1;
+        }
+    }
+    return 0;
+}
+
+/**
+ * If the received packet is Rate 1/4 a further sanity check is made of the codebook gain.
+ *
+ * @param cbgain the unpacked cbgain array
+ * @return -1 if the sanity check fails, 0 otherwise
+ *
+ * TIA/EIA/IS-733 2.4.8.7.3
+ */
+static int codebook_sanity_check_for_rate_quarter(const uint8_t *cbgain) {
+   int i, prev_diff=0;
+
+   for (i = 1; i < 5; i++) {
+       int diff = cbgain[i] - cbgain[i-1];
+       if (FFABS(diff) > 10)
+           return -1;
+       else if (FFABS(diff - prev_diff) > 12)
+           return -1;
+       prev_diff = diff;
+   }
+   return 0;
+}
+
+/**
  * Computes the scaled codebook vector Cdn From INDEX and GAIN
  * for all rates.
  *
@@ -96,7 +206,7 @@ static void compute_svector(const QCELPC
     uint16_t cbseed, cindex;
     float    *rnd, tmp_gain, fir_filter_value;
 
-    switch (q->framerate) {
+    switch (q->bitrate) {
     case RATE_FULL:
         for (i = 0; i < 16; i++) {
             tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO;
@@ -248,7 +358,7 @@ static const float *do_pitchfilter(float
 
 /**
  * Interpolates LSP frequencies and computes LPC coefficients
- * for a given framerate & pitch subframe.
+ * for a given bitrate & pitch subframe.
  *
  * TIA/EIA/IS-733 2.4.3.3.4
  *
@@ -263,9 +373,9 @@ void interpolate_lpc(QCELPContext *q, co
     float interpolated_lspf[10];
     float weight;
 
-    if(q->framerate >= RATE_QUARTER)
+    if(q->bitrate >= RATE_QUARTER)
         weight = 0.25 * (subframe_num + 1);
-    else if(q->framerate == RATE_OCTAVE && !subframe_num)
+    else if(q->bitrate == RATE_OCTAVE && !subframe_num)
         weight = 0.625;
     else
         weight = 1.0;
@@ -275,11 +385,11 @@ void interpolate_lpc(QCELPContext *q, co
         weighted_vector_sumf(interpolated_lspf, curr_lspf, q->prev_lspf,
                              weight, 1.0 - weight, 10);
         qcelp_lspf2lpc(interpolated_lspf, lpc);
-    }else if(q->framerate >= RATE_QUARTER || (q->framerate == I_F_Q && !subframe_num))
+    }else if(q->bitrate >= RATE_QUARTER || (q->bitrate == I_F_Q && !subframe_num))
         qcelp_lspf2lpc(curr_lspf, lpc);
 }
 
-static int buf_size2framerate(const int buf_size)
+static int buf_size2bitrate(const int buf_size)
 {
     switch(buf_size)
     {




More information about the ffmpeg-cvslog mailing list