More OKed parts of the QCELP decoder
authorKenan Gillet <kenan.gillet@gmail.com>
Tue, 11 Nov 2008 18:50:38 +0000 (18:50 +0000)
committerVitor Sessak <vitor1001@gmail.com>
Tue, 11 Nov 2008 18:50:38 +0000 (18:50 +0000)
patch by Kenan Gillet, kenan.gillet gmail com

Originally committed as revision 15802 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/qcelpdata.h
libavcodec/qcelpdec.c

index e5e9de5..f5b39b6 100644 (file)
@@ -378,6 +378,38 @@ static const qcelp_vector * const qcelp_lspvq[5] = {
     qcelp_lspvq5
 };
 
+/**
+ * the final gain scalefactor before clipping into a usable output float
+ */
+#define QCELP_SCALE 8192.
+
+/**
+ * table for computing Ga (decoded linear codebook gain magnitude)
+ *
+ * @note The table could fit in int16_t in x*8 form, but it seems
+ *       to be slower on x86
+ *
+ * TIA/EIA/IS-733 2.4.6.2.1-3
+ */
+
+static const float qcelp_g12ga[61] = {
+    1.000/QCELP_SCALE,   1.125/QCELP_SCALE,   1.250/QCELP_SCALE,   1.375/QCELP_SCALE,
+    1.625/QCELP_SCALE,   1.750/QCELP_SCALE,   2.000/QCELP_SCALE,   2.250/QCELP_SCALE,
+    2.500/QCELP_SCALE,   2.875/QCELP_SCALE,   3.125/QCELP_SCALE,   3.500/QCELP_SCALE,
+    4.000/QCELP_SCALE,   4.500/QCELP_SCALE,   5.000/QCELP_SCALE,   5.625/QCELP_SCALE,
+    6.250/QCELP_SCALE,   7.125/QCELP_SCALE,   8.000/QCELP_SCALE,   8.875/QCELP_SCALE,
+   10.000/QCELP_SCALE,  11.250/QCELP_SCALE,  12.625/QCELP_SCALE,  14.125/QCELP_SCALE,
+   15.875/QCELP_SCALE,  17.750/QCELP_SCALE,  20.000/QCELP_SCALE,  22.375/QCELP_SCALE,
+   25.125/QCELP_SCALE,  28.125/QCELP_SCALE,  31.625/QCELP_SCALE,  35.500/QCELP_SCALE,
+   39.750/QCELP_SCALE,  44.625/QCELP_SCALE,  50.125/QCELP_SCALE,  56.250/QCELP_SCALE,
+   63.125/QCELP_SCALE,  70.750/QCELP_SCALE,  79.375/QCELP_SCALE,  89.125/QCELP_SCALE,
+  100.000/QCELP_SCALE, 112.250/QCELP_SCALE, 125.875/QCELP_SCALE, 141.250/QCELP_SCALE,
+  158.500/QCELP_SCALE, 177.875/QCELP_SCALE, 199.500/QCELP_SCALE, 223.875/QCELP_SCALE,
+  251.250/QCELP_SCALE, 281.875/QCELP_SCALE, 316.250/QCELP_SCALE, 354.875/QCELP_SCALE,
+  398.125/QCELP_SCALE, 446.625/QCELP_SCALE, 501.125/QCELP_SCALE, 563.375/QCELP_SCALE,
+  631.000/QCELP_SCALE, 708.000/QCELP_SCALE, 794.375/QCELP_SCALE, 891.250/QCELP_SCALE,
+ 1000.000/QCELP_SCALE};
+
 /**
  * circular codebook for rate 1 frames in x*100 form
  *
@@ -428,4 +460,18 @@ static const int8_t qcelp_rate_half_codebook[128] = {
 };
 #define QCELP_RATE_HALF_CODEBOOK_RATIO 0.5
 
+/**
+ * table for impulse response of BPF used to filter
+ * the white excitation for framerate 1/4 synthesis
+ *
+ * Only half the tables are needed because of symetry.
+ *
+ * TIA/EIA/IS-733 2.4.8.1.2-1.1
+ */
+static const double qcelp_rnd_fir_coefs[11] = {
+  -1.344519e-1, 1.735384e-2, -6.905826e-2, 2.434368e-2,
+  -8.210701e-2, 3.041388e-2, -9.251384e-2, 3.501983e-2,
+  -9.918777e-2, 3.749518e-2,  8.985137e-1
+};
+
 #endif /* AVCODEC_QCELPDATA_H */
index 1ad7659..14bd43c 100644 (file)
@@ -103,6 +103,39 @@ static const float *do_pitchfilter(float memory[303],
     return memory + 143;
 }
 
+/**
+ * Interpolates LSP frequencies and computes LPC coefficients
+ * for a given framerate & pitch subframe.
+ *
+ * TIA/EIA/IS-733 2.4.3.3.4
+ *
+ * @param q the context
+ * @param curr_lspf LSP frequencies vector of the current frame
+ * @param lpc float vector for the resulting LPC
+ * @param subframe_num frame number in decoded stream
+ */
+void interpolate_lpc(QCELPContext *q,
+                     const float *curr_lspf,
+                     float *lpc,
+                     const int subframe_num) {
+    float interpolated_lspf[10];
+    float weight;
+
+    if (q->framerate >= RATE_QUARTER) {
+        weight = 0.25 * (subframe_num + 1);
+    } else if (q->framerate == RATE_OCTAVE && !subframe_num) {
+        weight = 0.625;
+    } else {
+        weight = 1.0;
+    }
+
+    if (weight != 1.0) {
+        weighted_vector_sumf(interpolated_lspf, curr_lspf, q->prev_lspf, weight, 1.0 - weight, 10);
+        lspf2lpc(q, interpolated_lspf, lpc);
+    } else if (q->framerate >= RATE_QUARTER || (q->framerate == I_F_Q && !subframe_num))
+        lspf2lpc(q, curr_lspf, lpc);
+}
+
 static int buf_size2framerate(const int buf_size) {
     switch (buf_size) {
     case 35:
@@ -123,3 +156,14 @@ static void warn_insufficient_frame_quality(AVCodecContext *avctx,
                                             const char *message) {
     av_log(avctx, AV_LOG_WARNING, "Frame #%d, IFQ: %s\n", avctx->frame_number, message);
 }
+
+AVCodec qcelp_decoder =
+{
+    .name   = "qcelp",
+    .type   = CODEC_TYPE_AUDIO,
+    .id     = CODEC_ID_QCELP,
+    .init   = qcelp_decode_init,
+    .decode = qcelp_decode_frame,
+    .priv_data_size = sizeof(QCELPContext),
+    .long_name = NULL_IF_CONFIG_SMALL("QCELP / PureVoice"),
+};