All pastes #1544908 Raw Edit

Miscellany

public text v1 · immutable
#1544908 ·published 2009-08-27 18:26 UTC
rendered paste body
Index: libavcodec/lsp.c
===================================================================
--- libavcodec/lsp.c	(revision 19727)
+++ libavcodec/lsp.c	(working copy)
@@ -29,6 +29,19 @@
 #include "lsp.h"
 #include "celp_math.h"
 
+void ff_acelp_stabilize_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min,
+                            int lsfq_max, int lp_order)
+{
+    int i;
+
+    for(i=0; i<lp_order; i++) {
+        lsfq[i] = FFMAX(lsfq[i], lsfq_min);
+        lsfq_min = lsfq[i] + lsfq_min_distance;
+    }
+    lsfq[lp_order-1] = FFMIN(lsfq[lp_order-1], lsfq_max);//Is warning required ?
+
+}
+
 void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, int lsfq_max, int lp_order)
 {
     int i, j;
@@ -39,12 +52,8 @@
         for(j=i; j>=0 && lsfq[j] > lsfq[j+1]; j--)
             FFSWAP(int16_t, lsfq[j], lsfq[j+1]);
 
-    for(i=0; i<lp_order; i++)
-    {
-        lsfq[i] = FFMAX(lsfq[i], lsfq_min);
-        lsfq_min = lsfq[i] + lsfq_min_distance;
-    }
-    lsfq[lp_order-1] = FFMIN(lsfq[lp_order-1], lsfq_max);//Is warning required ?
+    ff_acelp_stabilize_lsf(lsfq, lsfq_min_distance, lsfq_min, lsfq_max,
+                           lp_order);
 }
 
 void ff_acelp_lsf2lsp(int16_t *lsp, const int16_t *lsf, int lp_order)
@@ -101,6 +110,37 @@
     }
 }
 
+void ff_acelp_isp2lpc(int16_t *lp, const int16_t *isp, int lp_half_order)
+{
+    int f1[lp_half_order+1];
+    int f2[lp_half_order  ];
+    int i;
+    int reflection_coeff = isp[(lp_half_order<<1)-1];
+
+    lsp2poly(f1, isp  , lp_half_order  );
+    lsp2poly(f2, isp+1, lp_half_order-1);
+
+    for(i=lp_half_order-1; i>1; i--)
+        f2[i] -= f2[i-2];
+
+    for(i=0; i<lp_half_order; i++)
+    {
+        f1[i] = (((int64_t)f1[i]) * (32767 + reflection_coeff)) >> 15;
+        f2[i] = (((int64_t)f2[i]) * (32767 - reflection_coeff)) >> 15;
+    }
+    f1[lp_half_order] = (((int64_t)f1[lp_half_order]) * (32767 + reflection_coeff)) >> 15;
+
+    lp[0] = 4096;
+    for(i=1; i<lp_half_order; i++)
+    {
+        lp[i]                    = (f1[i] + f2[i]) >> 11;
+        lp[(lp_half_order<<1)-i] = (f1[i] - f2[i]) >> 11;
+    }
+    lp[lp_half_order     ] = f1[lp_half_order] >> 11;
+    lp[lp_half_order << 1] = reflection_coeff >> 3;
+}
+
+
 void ff_acelp_lp_decode(int16_t* lp_1st, int16_t* lp_2nd, const int16_t* lsp_2nd, const int16_t* lsp_prev, int lp_order)
 {
     int16_t lsp_1st[lp_order]; // (0.15)
Index: libavcodec/lsp.h
===================================================================
--- libavcodec/lsp.h	(revision 19727)
+++ libavcodec/lsp.h	(working copy)
@@ -25,6 +25,9 @@
 
 #include <stdint.h>
 
+void ff_acelp_stabilize_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min,
+                            int lsfq_max, int lp_order);
+
 /**
   (I.F) means fixed-point value with F fractional and I integer bits
 */
@@ -57,6 +60,14 @@
  */
 void ff_acelp_lsp2lpc(int16_t* lp, const int16_t* lsp, int lp_half_order);
 
+/*
+ * Compute LPC coefficients from ISP (Immittance Spectral Pairs).
+ * \param lp [out] decoded LP coefficients (-0x8000 <= (3.12) < 0x8000)
+ * \param lsp ISP coefficients (-0x8000 <= (0.15) < 0x8000)
+ * \param lp_half_order LP filter order, divided by 2
+ */
+void ff_acelp_isp2lpc(int16_t *lp, const int16_t *isp, int lp_half_order);
+
 /**
  * \brief Interpolate LSP for the first subframe and convert LSP -> LP for both subframes (3.2.5 and 3.2.6 of G.729)
  * \param lp_1st [out] decoded LP coefficients for first subframe (-0x8000 <= (3.12) < 0x8000)
@@ -67,14 +78,4 @@
  */
 void ff_acelp_lp_decode(int16_t* lp_1st, int16_t* lp_2nd, const int16_t* lsp_2nd, const int16_t* lsp_prev, int lp_order);
 
-/**
- * Reconstructs LPC coefficients from the line spectral pair frequencies.
- *
- * @param lsp line spectral pairs in cosine domain
- * @param lpc linear predictive coding coefficients
- *
- * TIA/EIA/IS-733 2.4.3.3.5
- */
-void ff_acelp_lspd2lpc(const double *lsp, float *lpc);
-
 #endif /* AVCODEC_LSP_H */
Index: libavcodec/acelp_vectors.c
===================================================================
--- libavcodec/acelp_vectors.c	(revision 19727)
+++ libavcodec/acelp_vectors.c	(working copy)
@@ -126,6 +126,28 @@
     fc_v[tab2[pulse_indexes]] += (pulse_signs & 1) ? 8191 : -8192;
 }
 
+void ff_acelp_two_pulses_per_track(
+        int16_t* fc_v,
+        const uint8_t *tab1,
+        const uint8_t *tab2,
+        int* pulse_indexes,
+        int pulse_count,
+        int bits)
+{
+    int i;
+    int mask = (1 << bits) - 1;
+
+    for(i=0; i<pulse_count; i++)
+    {
+        int index_1 = i + tab1[(pulse_indexes[i] >> bits) & mask];
+        int index_2 = i + tab2[ pulse_indexes[i]          & mask];
+        int pulse   = (pulse_indexes[i] & 0x100) ? -8192 : 8192;
+
+        fc_v[index_1] = pulse;
+        fc_v[index_2] += (index_2 <  index_1) ? -pulse : pulse;
+    }
+}
+
 void ff_acelp_weighted_vector_sum(
         int16_t* out,
         const int16_t *in_a,
Index: libavcodec/acelp_vectors.h
===================================================================
--- libavcodec/acelp_vectors.h	(revision 19727)
+++ libavcodec/acelp_vectors.h	(working copy)
@@ -126,6 +126,36 @@
         int bits);
 
 /**
+ * \brief Decode fixed-codebook vector (5.7.1 of AMR).
+ * \param fc_v [out] decoded fixed codebook vector (2.13)
+ * \param tab1 table used for pulses
+ * \param tab2 table used for last pulse
+ * \param pulse_indexes fixed codebook indexes
+ * \param pulse_count number of pulses decoded using first table
+ * \param bits number of bits per one pulse index
+ *
+ * \remark Two pulses and sign are packed as following (from MSB to LSB):
+ *
+ *  count | content
+ *  ------+------------------
+ *    1   | first pulse sign
+ *   bits | first pulse index
+ *   bits | second pulse index
+ *
+ * First and second pulse signs are the same if first index is less or equal
+ * to second and opposite - otherwise
+ *
+ * Used in SIPR @16k, AMR @12.2k
+ */
+void ff_acelp_two_pulses_per_track(
+        int16_t* fc_v,
+        const uint8_t *tab1,
+        const uint8_t *tab2,
+        int* pulse_indexes,
+        int pulse_count,
+        int bits);
+
+/**
  * weighted sum of two vectors with rounding.
  * @param out [out] result of addition
  * @param in_a first vector
Index: libavcodec/allcodecs.c
===================================================================
--- libavcodec/allcodecs.c	(revision 19727)
+++ libavcodec/allcodecs.c	(working copy)
@@ -222,6 +222,7 @@
     REGISTER_DECODER (RA_144, ra_144);
     REGISTER_DECODER (RA_288, ra_288);
     REGISTER_DECODER (SHORTEN, shorten);
+    REGISTER_DECODER (SIPR, sipr);
     REGISTER_DECODER (SMACKAUD, smackaud);
     REGISTER_ENCDEC  (SONIC, sonic);
     REGISTER_ENCODER (SONIC_LS, sonic_ls);
Index: libavcodec/siprdata.h
===================================================================
--- libavcodec/siprdata.h	(revision 0)
+++ libavcodec/siprdata.h	(revision 0)
@@ -0,0 +1,711 @@
+#ifndef FFMPEG_SIPRDATA_H
+#define FFMPEG_SIPRDATA_H
+
+/** Convert a constant to fixed point. Positive numbers only. */
+#define FIX(val, fix) ((int) ((val)*(1<<(fix))+.5))
+
+static const int16_t gain_prediction_coeff[2] = {FIX(0.2,15), FIX(0.15,15)};
+
+static const int16_t ma_pred[2]      = {FIX(      0.12, 15), FIX(     0.5, 15)};
+static const int16_t ma_pred_sum[2]  = {FIX(    1-0.12, 15), FIX(   1-0.5, 15)};
+static const int16_t ma_pred_sumi[2] = {FIX(1./(1-0.12),13), FIX(1/(1-0.5),13)};
+
+static const int16_t weight_pow[17] =
+{  32768, 16384, 8192, 4096, 2048, 1024, 512, 256,
+     128,    64,   32,   16,    8,    4,   2,   1,
+       0
+};
+
+static const int qua_gain_code[32] =
+{ /* (4.13) */
+   614,    867,   1157,   1543,
+  1942,   2308,   2681,   3078,
+  3454,   3876,   4348,   4879,
+  5475,   6143,   6892,   7733,
+  8677,   9736,  10924,  12257,
+ 13752,  15430,  17313,  19426,
+ 21796,  25025,  29066,  34545,
+ 43490,  57994,  77337, 109242,
+};
+
+static const int16_t qua_gain_pitch[16] =
+{ /* (1.14) */
+     0,  3277,  6554,  8192,  9830, 11469, 12288, 13107,
+ 13926, 14746, 15565, 16384, 17203, 18022, 18842, 19661,
+};
+
+static const int16_t pow_tab1[10] =
+{
+    FIX(0.55, 15),
+    FIX(0.55*0.55, 15),
+    FIX(0.55*0.55*0.55, 15),
+    FIX(0.55*0.55*0.55*0.55, 15),
+    FIX(0.55*0.55*0.55*0.55*0.55, 15),
+    FIX(0.55*0.55*0.55*0.55*0.55*0.55, 15),
+    FIX(0.55*0.55*0.55*0.55*0.55*0.55*0.55, 15),
+    FIX(0.55*0.55*0.55*0.55*0.55*0.55*0.55*0.55, 15),
+    FIX(0.55*0.55*0.55*0.55*0.55*0.55*0.55*0.55*0.55, 15),
+    FIX(0.55*0.55*0.55*0.55*0.55*0.55*0.55*0.55*0.55*0.55, 15)
+};
+
+static const int16_t pow_tab2[10] =
+{
+    FIX(0.7, 15),
+    FIX(0.7*0.7, 15),
+    FIX(0.7*0.7*0.7, 15),
+    FIX(0.7*0.7*0.7*0.7, 15),
+    FIX(0.7*0.7*0.7*0.7*0.7, 15),
+    FIX(0.7*0.7*0.7*0.7*0.7*0.7, 15),
+    FIX(0.7*0.7*0.7*0.7*0.7*0.7*0.7, 15),
+    FIX(0.7*0.7*0.7*0.7*0.7*0.7*0.7*0.7, 15),
+    FIX(0.7*0.7*0.7*0.7*0.7*0.7*0.7*0.7*0.7, 15),
+    FIX(0.7*0.7*0.7*0.7*0.7*0.7*0.7*0.7*0.7*0.7, 15)
+};
+
+static const int16_t cb_lsp_1st[128][3] =
+{ /* (2,13) */
+  {  340,   607,  1904},  {  302,   556,  2469},
+  {  615,   939,  2305},  {  657,   970,  1944},
+  {  572,   849,  1509},  {  737,  1072,  1691},
+  {  778,  1139,  2152},  {  880,  1295,  1898},
+  {  761,  1173,  2484},  {  611,   967,  2713},
+  {  906,  1390,  2234},  {  971,  1387,  2519},
+  {  809,  1225,  2801},  {  789,  1578,  2653},
+  {  964,  1717,  2429},  { 1037,  1486,  2852},
+  {  542,  1482,  2923},  {  884,  1352,  3127},
+  {  854,  1731,  3013},  { 1213,  1634,  2520},
+  { 1250,  1714,  2816},  { 1198,  1667,  3098},
+  { 1008,  1953,  2731},  { 1059,  1515,  3382},
+  { 1028,  1903,  3295},  { 1034,  2112,  3056},
+  { 1433,  1968,  3048},  { 1371,  1937,  2626},
+  { 1328,  1761,  3425},  { 1261,  2251,  3306},
+  { 1295,  2245,  2824},  { 1050,  1953,  3699},
+  {  864,  2163,  3486},  { 1561,  2107,  3509},
+  { 1438,  1860,  3820},  {  782,  1739,  3507},
+  { 1262,  2368,  3799},  {  668,  1888,  3749},
+  {  900,  2193,  3997},  { 1043,  1518,  3797},
+  {  799,  1878,  4100},  { 1210,  2025,  4085},
+  {  558,  1666,  4035},  {  523,  2070,  4047},
+  {  759,  2443,  3821},  {  479,  1407,  3787},
+  {  751,  1162,  3895},  {  478,  1408,  4243},
+  {  536,  1797,  4385},  {  462,  1027,  4160},
+  {  829,  1261,  4317},  {  385,   893,  3764},
+  {  578,  1026,  3445},  {  831,  1251,  3499},
+  {  557,  1485,  3359},  {  651,  1056,  3082},
+  {  327,   666,  3197},  {  503,  1025,  4649},
+  {  578,  1972,  3152},  { 1142,  1595,  4181},
+  {  499,  1578,  4795},  {  960,  1473,  4715},
+  {  601,  2262,  4332},  {  886,  2077,  4492},
+  {  603,  2206,  4786},  { 1319,  1875,  4565},
+  {  948,  2485,  4321},  { 1113,  2484,  4700},
+  { 1041,  2039,  5078},  { 1320,  2403,  4248},
+  { 1564,  2028,  4276},  { 1530,  2245,  4841},
+  { 1587,  2546,  4532},  { 1266,  2839,  4203},
+  { 1420,  2809,  4967},  { 1513,  3027,  4542},
+  { 1850,  2793,  4213},  { 1753,  2293,  3907},
+  { 1871,  2969,  4795},  { 1633,  3018,  3778},
+  { 1009,  2874,  3835},  { 1332,  2619,  3530},
+  { 1774,  2514,  3491},  { 1308,  2779,  3115},
+  { 1652,  2340,  3071},  {  756,  2614,  3335},
+  { 2140,  2841,  3185},  { 2341,  2901,  3757},
+  {  673,  2791,  4291},  {  970,  3056,  4595},
+  {  596,  2827,  4807},  {  891,  2675,  5136},
+  { 1188,  3368,  4830},  { 1690,  3504,  4457},
+  { 1826,  3406,  4951},  { 1355,  3293,  5321},
+  {  814,  3881,  4683},  {  593,  3404,  5447},
+  { 1355,  3902,  5391},  { 1755,  2973,  5411},
+  { 2124,  3549,  5314},  { 1467,  2543,  5347},
+  { 1057,  2955,  5727},  {  440,  2696,  5616},
+  { 1160,  2218,  5675},  { 1513,  2932,  6113},
+  {  432,  2056,  5406},  {  625,  1535,  5355},
+  {  542,  2086,  6302},  {  453,  1210,  5921},
+  {  488,  1071,  5193},  {  566,  3524,  6603},
+  {  728,  4110,  5723},  { 1176,  3802,  6178},
+  {  732,  4658,  6244},  { 1820,  3706,  5985},
+  { 1554,  4425,  5847},  { 2368,  4337,  5984},
+  { 2046,  4158,  4788},  { 1612,  4742,  6945},
+  { 2235,  5721,  6157},  { 1091,  5758,  6500},
+  {  644,  4940,  7314},  { 3107,  4181,  4821},
+  { 3591,  5439,  5689},  { 2440,  3242,  4545},
+  { 4188,  4413,  4716},  { 1161,  1568,  2141}
+}; // cb_lsp_1st
+
+static const int16_t cb_lsp_2nd[256][3] =
+{ /* (2,13) */
+  { 3534,  4377,  5629},  { 3537,  4806,  5567},
+  { 3449,  4272,  6067},  { 3385,  4423,  6458},
+  { 3325,  4908,  6200},  { 4124,  4757,  6219},
+  { 4162,  4735,  5469},  { 4052,  5200,  6032},
+  { 3910,  4642,  6729},  { 3828,  5131,  6634},
+  { 4321,  5137,  6596},  { 3949,  5602,  6330},
+  { 4606,  5209,  6156},  { 4469,  5072,  5712},
+  { 4349,  5531,  6515},  { 4736,  5313,  6635},
+  { 4218,  5393,  7066},  { 4633,  5222,  7066},
+  { 4559,  5570,  6950},  { 4123,  5738,  6880},
+  { 4242,  4946,  7079},  { 4447,  5224,  7399},
+  { 4439,  5910,  7099},  { 4433,  5597,  7474},
+  { 3879,  5629,  7220},  { 3897,  5117,  7229},
+  { 4146,  5830,  7421},  { 4090,  5399,  7579},
+  { 4243,  4975,  7589},  { 3534,  5267,  7505},
+  { 3692,  5629,  7696},  { 3856,  5164,  7845},
+  { 3657,  4799,  7584},  { 4000,  4663,  7423},
+  { 3296,  5215,  7820},  { 3138,  4807,  7493},
+  { 3463,  4790,  8000},  { 3442,  4874,  7014},
+  { 3611,  4368,  7305},  { 3562,  4297,  7902},
+  { 3199,  4363,  7059},  { 3000,  4068,  7639},
+  { 2819,  5152,  7561},  { 3145,  5390,  7252},
+  { 3543,  5368,  6992},  { 3408,  5780,  7320},
+  { 3193,  5669,  7668},  { 3117,  5511,  6588},
+  { 2754,  5905,  7646},  { 3291,  6102,  7634},
+  { 3213,  6249,  7137},  { 3655,  5914,  6790},
+  { 3728,  6059,  7439},  { 3660,  5963,  7977},
+  { 3075,  5912,  8161},  { 3383,  6299,  7998},
+  { 3430,  6555,  7623},  { 3965,  6303,  7684},
+  { 3978,  5888,  7786},  { 3882,  6346,  8194},
+  { 3843,  6669,  7932},  { 4001,  5893,  8304},
+  { 3477,  6106,  8460},  { 3494,  6674,  8260},
+  { 4269,  6446,  8002},  { 4297,  6002,  7844},
+  { 4316,  6244,  8362},  { 4433,  5852,  8147},
+  { 4161,  5556,  7917},  { 4301,  5434,  8263},
+  { 4422,  6281,  7657},  { 4693,  6201,  8032},
+  { 4614,  5560,  7873},  { 4709,  5895,  7771},
+  { 4823,  5819,  8132},  { 4525,  5223,  7846},
+  { 4689,  5401,  8284},  { 5006,  5515,  7890},
+  { 4763,  5739,  7450},  { 4814,  5381,  7495},
+  { 5129,  5733,  7559},  { 4818,  5767,  7139},
+  { 5086,  5514,  7212},  { 4853,  6138,  7572},
+  { 5159,  5925,  7224},  { 4856,  6115,  7185},
+  { 4519,  6027,  7454},  { 5075,  5625,  6836},
+  { 4752,  5855,  6742},  { 5278,  5971,  6737},
+  { 5048,  6385,  6993},  { 4513,  6322,  6922},
+  { 4341,  5926,  6575},  { 4881,  5699,  6347},
+  { 3971,  6287,  6874},  { 4167,  6228,  7257},
+  { 4636,  6469,  7313},  { 5188,  6256,  7498},
+  { 5001,  6564,  7441},  { 4221,  6664,  7425},
+  { 3716,  6529,  7225},  { 4606,  6871,  7517},
+  { 3776,  6794,  7527},  { 4666,  6532,  7828},
+  { 5018,  6366,  7851},  { 4857,  6869,  7910},
+  { 4240,  6852,  7946},  { 4083,  7125,  7703},
+  { 4512,  7224,  7842},  { 4536,  6886,  8188},
+  { 4625,  6510,  8350},  { 5008,  6598,  8219},
+  { 5239,  6638,  7845},  { 5074,  6997,  8311},
+  { 5267,  6993,  8003},  { 4666,  6936,  8563},
+  { 5026,  6681,  8618},  { 5334,  6818,  8491},
+  { 5388,  6513,  8143},  { 5573,  6829,  8241},
+  { 5345,  6406,  8541},  { 5385,  6920,  8781},
+  { 5172,  7148,  8635},  { 5484,  7167,  8419},
+  { 5719,  6979,  8598},  { 5741,  6529,  8512},
+  { 5543,  7212,  8746},  { 5568,  7519,  8595},
+  { 5809,  7357,  8673},  { 5460,  7230,  9083},
+  { 5621,  7487,  8913},  { 5857,  7279,  8983},
+  { 5758,  6919,  9006},  { 5279,  7489,  8828},
+  { 5862,  7660,  8821},  { 6054,  7568,  9083},
+  { 5669,  7689,  9249},  { 6282,  7525,  8808},
+  { 6113,  7209,  8583},  { 5906,  7486,  8278},
+  { 6289,  7033,  9015},  { 6389,  7624,  8416},
+  { 6266,  7315,  8140},  { 5913,  7014,  8236},
+  { 6333,  6927,  8306},  { 6575,  7165,  8580},
+  { 6116,  6762,  8643},  { 6013,  6605,  8281},
+  { 6408,  7004,  7901},  { 6087,  6681,  7940},
+  { 5966,  7077,  7827},  { 5674,  6697,  7909},
+  { 6181,  6844,  7557},  { 5838,  6663,  7485},
+  { 5802,  6318,  7821},  { 5763,  6415,  8143},
+  { 5530,  6959,  7630},  { 5475,  6407,  7713},
+  { 5706,  6290,  7439},  { 5386,  6613,  7339},
+  { 5427,  5988,  7610},  { 5444,  6154,  7943},
+  { 5445,  6091,  7227},  { 5607,  6343,  7011},
+  { 5133,  5936,  7850},  { 5143,  6206,  8199},
+  { 5318,  5859,  8192},  { 5607,  6175,  8294},
+  { 5297,  6005,  8709},  { 4812,  6112,  8484},
+  { 5024,  5620,  8413},  { 4436,  5776,  8584},
+  { 4773,  5592,  8966},  { 4676,  6367,  8934},
+  { 4317,  5184,  8666},  { 3761,  5686,  8714},
+  { 3966,  6312,  8802},  { 3816,  5360,  8274},
+  { 3641,  5102,  8725},  { 4031,  4735,  8621},
+  { 3758,  4889,  8321},  { 4275,  5018,  8136},
+  { 3234,  5063,  8415},  { 3967,  4669,  8002},
+  { 3503,  4410,  8560},  { 3424,  5569,  8151},
+  { 2913,  4551,  8223},  { 3128,  4839,  8931},
+  { 2770,  5238,  8068},  { 3151,  3948,  8535},
+  { 3058,  5657,  8668},  { 3629,  4431,  9219},
+  { 3347,  5442,  9270},  { 3968,  5062,  9256},
+  { 3124,  6316,  9103},  { 3007,  6475,  8469},
+  { 2874,  6449,  7829},  { 3518,  6968,  8790},
+  { 3199,  7260,  8336},  { 3258,  6979,  7858},
+  { 4101,  6836,  8453},  { 3746,  7181,  8046},
+  { 3670,  7699,  8596},  { 4261,  7487,  8167},
+  { 4244,  6919,  9122},  { 4625,  7439,  8756},
+  { 4818,  7398,  8106},  { 4291,  7997,  8570},
+  { 3953,  7610,  9303},  { 5252,  7464,  8198},
+  { 5000,  7948,  8398},  { 4970,  6992,  9071},
+  { 4600,  8291,  8937},  { 5331,  8149,  8997},
+  { 5568,  7960,  8364},  { 5086,  7503,  9588},
+  { 5330,  6583,  8975},  { 5605,  7252,  7990},
+  { 5111,  7070,  7568},  { 5897,  7207,  9530},
+  { 5918,  8294,  9092},  { 6157,  7996,  8520},
+  { 5827,  6348,  8871},  { 6043,  7748,  9565},
+  { 6256,  7904,  9153},  { 6414,  7399,  9333},
+  { 6704,  7416,  8970},  { 6637,  8010,  9430},
+  { 6698,  8058,  8732},  { 6613,  7566,  9746},
+  { 7036,  7705,  9284},  { 6956,  7652,  8602},
+  { 6744,  8460,  9278},  { 6732,  7358,  8225},
+  { 7258,  8148,  8879},  { 7077,  8284,  9749},
+  { 6292,  8180,  9707},  { 6729,  8748,  9864},
+  { 7507,  8584,  9370},  { 6046,  8713,  9656},
+  { 6438,  8337, 10307},  { 5663,  8165,  9897},
+  { 6056,  7657, 10263},  { 6168,  8989, 10488},
+  { 5051,  8700,  9440},  { 7450,  8972,  9968},
+  { 6913,  9169, 10510},  { 7459,  8495, 11208},
+  { 7918,  9605, 10556},  { 8555,  8944,  9242},
+  { 7554,  7824,  8046},  { 3828,  8486,  9313},
+  { 5681,  6155,  9531},  { 6812,  7132,  7296},
+  { 6244,  6588,  7202},  { 2950,  7339,  9355}
+}; // cb_lsp_2nd
+
+static const int16_t cb_lsp_3rd[128][3] =
+{ /* (2,13) */
+  { 7990,  9362, 11256},  { 8163,  9506, 11953},
+  { 7759,  9978, 11770},  { 8434, 10166, 11646},
+  { 8375, 10096, 10973},  { 8833,  9763, 11321},
+  { 8218, 10689, 11411},  { 8636, 10128, 12196},
+  { 8911, 10386, 11726},  { 9040,  9866, 11880},
+  { 8902, 10453, 11198},  { 9329, 10133, 11503},
+  { 8775, 10873, 11542},  { 9298, 10741, 11452},
+  { 8659, 10738, 12043},  { 9325, 10470, 11982},
+  { 8963, 10442, 12252},  { 9217, 10866, 12046},
+  { 9097, 11141, 11732},  { 9666, 10445, 11749},
+  { 9643, 11027, 11733},  { 9134, 10908, 12457},
+  { 9363, 10408, 12443},  { 9593, 10786, 12402},
+  { 9802, 10393, 12281},  { 9831, 11025, 12203},
+  { 9470, 11184, 12519},  { 9512, 10086, 12109},
+  { 9452, 11347, 12041},  { 9408, 10627, 12844},
+  { 9823, 10443, 12719},  { 9789, 10905, 12784},
+  { 9492, 10092, 12722},  { 9322, 11044, 12903},
+  { 9700, 11309, 12842},  { 8990, 10265, 12781},
+  { 8981, 11294, 12668},  { 8734, 10727, 12633},
+  { 8983, 10674, 13151},  { 9368, 11519, 12894},
+  { 8539, 11161, 12940},  { 9175, 11321, 13271},
+  { 8528, 11161, 12345},  { 8351, 10515, 12977},
+  { 8918, 11383, 12125},  { 8793, 11700, 13162},
+  { 8899, 11815, 12592},  { 8301, 11732, 12534},
+  { 8371, 11139, 11853},  { 7775, 11153, 12312},
+  { 8180, 10451, 12249},  { 9367, 11667, 12412},
+  { 9816, 11483, 12429},  {10003, 11163, 12612},
+  {10052, 11442, 11972},  {10327, 11127, 12238},
+  {10059, 10687, 11986},  {10173, 10747, 12532},
+  {10313, 11581, 12511},  {10403, 11184, 12722},
+  {10264, 11052, 11722},  {10068, 11502, 12877},
+  {10279, 10926, 13058},  {10093, 11278, 13109},
+  {10343, 11671, 13004},  {10096, 11616, 13204},
+  {10423, 11531, 13290},  { 9755, 11482, 13154},
+  { 9812, 11744, 12950},  {10287, 11797, 13293},
+  { 9901, 11422, 13454},  {10007, 11878, 13361},
+  {10255, 11542, 13546},  { 9473, 11792, 13300},
+  {10450, 11809, 13531},  {10141, 11869, 13772},
+  {10346, 12079, 13383},  {10594, 11867, 13240},
+  {10171, 12060, 13026},  {10597, 12110, 13625},
+  {10784, 11696, 13559},  {10803, 12303, 13219},
+  {10669, 11996, 12709},  {11050, 11787, 12963},
+  {10706, 11438, 12867},  {10709, 11488, 12273},
+  { 9981, 11890, 12548},  {11399, 11917, 13379},
+  {11632, 11864, 12509},  {11364, 12331, 13085},
+  {11342, 11654, 11963},  { 9472, 12114, 12823},
+  { 9695, 11072, 13173},  {10100, 10922, 13583},
+  { 9879, 10533, 13177},  { 9401, 10789, 13478},
+  { 9447, 10206, 13231},  { 9511, 11494, 13870},
+  { 9655, 10348, 13830},  { 8718, 11000, 13708},
+  { 8915,  9987, 13549},  { 9056,  9782, 12911},
+  { 9143,  9926, 12373},  { 8428,  9880, 12738},
+  { 8770,  9552, 12360},  { 9166, 10035, 10777},
+  { 9556, 10407, 11124},  { 8673,  9663, 10466},
+  { 9909, 10683, 11434},  { 9056, 12485, 13076},
+  { 9499, 12225, 13706},  {10153, 11037, 14222},
+  { 8475, 12374, 14024},  {10041, 12176, 14265},
+  {10206, 12597, 13642},  { 9242, 13022, 13900},
+  {10594, 12420, 14164},  {10525, 11819, 14180},
+  {11126, 12288, 14061},  {11026, 12614, 13738},
+  {10805, 12933, 14279},  {11389, 12727, 14195},
+  {11124, 12462, 14708},  {11721, 12528, 13638},
+  {11363, 13114, 14670},  {11924, 13015, 14120},
+  {11933, 13327, 14849},  { 8473, 11296, 14701}
+}; // cb_lsp_3rd
+
+static const int16_t cb_lsp_4th[128][3] =
+{ /* (2,13) */
+  {12644, 13402, 15386},  {12884, 13622, 16210},
+  {13117, 14184, 15730},  {13231, 14130, 15071},
+  {12600, 14573, 15478},  {12884, 14418, 16333},
+  {13443, 14270, 16200},  {12194, 13977, 16342},
+  {12877, 15010, 16026},  {13211, 14982, 15626},
+  {13676, 14611, 15861},  {13490, 14921, 16111},
+  {13414, 14694, 16590},  {13069, 15012, 16573},
+  {13531, 15092, 16564},  {13364, 15451, 16200},
+  {13897, 14716, 16448},  {13893, 15209, 16294},
+  {13826, 14926, 16918},  {13439, 15181, 17008},
+  {13748, 15411, 16733},  {13230, 15417, 16752},
+  {13788, 15717, 16445},  {13927, 15333, 17089},
+  {14260, 15093, 16718},  {14215, 15528, 16798},
+  {13632, 15618, 17150},  {13403, 15837, 16738},
+  {13934, 15849, 16952},  {14063, 15680, 17304},
+  {14264, 15559, 16333},  {14420, 15808, 17097},
+  {14340, 16019, 16703},  {14717, 15643, 16680},
+  {14402, 15237, 17181},  {14430, 15606, 17491},
+  {14369, 15954, 17462},  {14845, 15644, 17209},
+  {14433, 16296, 17141},  {14696, 16074, 17387},
+  {14076, 16092, 17385},  {14426, 16168, 17664},
+  {14532, 15869, 17829},  {14123, 15839, 17725},
+  {14866, 16074, 17654},  {14666, 16324, 17706},
+  {14322, 16474, 17700},  {14214, 16169, 17968},
+  {13861, 16213, 17679},  {14733, 16183, 17954},
+  {14509, 16392, 17998},  {14712, 16573, 17852},
+  {14966, 16438, 17829},  {14777, 16501, 17461},
+  {14841, 16391, 18166},  {14772, 16744, 18117},
+  {15230, 16197, 17946},  {15138, 16652, 18164},
+  {15041, 16843, 17786},  {14392, 16904, 17876},
+  {15536, 16708, 17888},  {15356, 16491, 17408},
+  {15295, 17094, 18199},  {15362, 16659, 18580},
+  {14769, 17121, 18492},  {15889, 17091, 18096},
+  {14247, 16576, 18539},  {15248, 17356, 18794},
+  {15660, 17456, 18506},  {15885, 17156, 18807},
+  {16216, 17518, 18586},  {15751, 17776, 19048},
+  {13747, 17496, 18626},  {16306, 17922, 19150},
+  {14732, 15688, 18442},  {13755, 16573, 18065},
+  {13661, 17115, 17720},  {13981, 15828, 18334},
+  {14010, 16614, 17386},  {13488, 15900, 17930},
+  {13814, 15739, 17550},  {13578, 15965, 17371},
+  {13633, 15396, 17849},  {13608, 15305, 17403},
+  {14022, 15297, 17507},  {13218, 15560, 17396},
+  {13082, 16047, 17546},  {13054, 15044, 17739},
+  {13402, 14796, 17274},  {12936, 15119, 17162},
+  {12427, 15253, 17479},  {12724, 15709, 17107},
+  {13038, 14596, 16981},  {12610, 14544, 17695},
+  {12384, 14523, 17002},  {12454, 15039, 16621},
+  {12825, 13915, 16945},  {13130, 14213, 17561},
+  {11795, 14168, 17339},  {13520, 14254, 16887},
+  {12444, 13617, 17714},  {12293, 13246, 16747},
+  {12409, 14171, 18335},  {11907, 15102, 17803},
+  {13586, 14632, 17980},  {12472, 15073, 18463},
+  {12766, 15661, 17965},  {13917, 14716, 17378},
+  {13518, 15316, 18491},  {14317, 15201, 17944},
+  {12967, 16443, 18046},  {13053, 16170, 18729},
+  {13130, 16163, 17003},  {13320, 16609, 17497},
+  {13759, 16288, 17009},  {12474, 16461, 17426},
+  {12121, 16311, 18134},  {11838, 15931, 17281},
+  {12809, 15659, 16515},  {12528, 17279, 18579},
+  {14970, 16166, 16995},  {15377, 15891, 17336},
+  {15348, 15757, 16638},  {14473, 15164, 16259},
+  {13775, 15302, 15711},  {14627, 15425, 15724},
+  {14121, 14964, 15856},  {13641, 14592, 15376}
+}; // cb_lsp_4th
+
+static const int16_t cb_lsp_5th[128][4] =
+{ /* (2,13) */
+  {17579, 18373, 20845, 21696},  {17469, 19411, 21302, 21744},
+  {17909, 18954, 21243, 22260},  {18154, 19526, 20992, 21960},
+  {17760, 19266, 20911, 22779},  {18110, 19205, 20215, 22222},
+  {18679, 19457, 20867, 22221},  {18545, 19297, 21417, 22173},
+  {18159, 19678, 21245, 22615},  {18182, 19554, 21662, 22371},
+  {18302, 19904, 21382, 22242},  {18199, 19163, 21496, 22953},
+  {18596, 19525, 20902, 23004},  {18629, 19780, 21715, 22389},
+  {18825, 19779, 21343, 22803},  {18396, 19676, 21852, 22989},
+  {18345, 20107, 21601, 22894},  {17981, 19812, 21523, 23195},
+  {17973, 19937, 22020, 23016},  {17464, 19524, 21534, 22906},
+  {18790, 20163, 21745, 23122},  {18804, 20030, 21988, 22690},
+  {18858, 19779, 22093, 23122},  {18548, 20134, 22156, 23090},
+  {18375, 20037, 21996, 23523},  {18525, 20496, 21895, 23118},
+  {18219, 20403, 22236, 23190},  {19018, 20253, 22232, 23097},
+  {18908, 20493, 21911, 22847},  {18899, 20467, 22253, 23393},
+  {18709, 20641, 22396, 23101},  {18670, 20337, 22613, 23331},
+  {18870, 20486, 21872, 23631},  {18891, 20835, 22054, 23329},
+  {19121, 20677, 22197, 23017},  {19182, 20535, 22425, 23219},
+  {19191, 20537, 21778, 23161},  {19432, 20560, 22147, 23087},
+  {19331, 20807, 22181, 23426},  {19191, 20802, 22597, 23352},
+  {19397, 20875, 22328, 23113},  {19490, 20656, 22479, 23270},
+  {19709, 20785, 22255, 23180},  {19393, 20266, 22299, 23394},
+  {19676, 20919, 22508, 23242},  {19480, 21047, 22535, 23379},
+  {19736, 20751, 22724, 23461},  {19341, 20425, 22762, 23440},
+  {20047, 20995, 22456, 23201},  {19741, 20305, 22282, 22869},
+  {19733, 20809, 22137, 22716},  {19743, 21315, 22361, 23062},
+  {19924, 21009, 22053, 23489},  {19348, 20946, 21925, 22885},
+  {19893, 20703, 21721, 22996},  {19372, 20488, 21933, 22635},
+  {20218, 21112, 22052, 22835},  {19882, 20720, 21565, 22384},
+  {19529, 20333, 21411, 22756},  {19297, 20129, 21869, 23006},
+  {19502, 20418, 21720, 23640},  {18883, 20295, 21440, 22736},
+  {19102, 20124, 21726, 22317},  {19174, 20615, 21334, 22128},
+  {19295, 20076, 20913, 22540},  {19214, 20133, 21200, 23231},
+  {18830, 19939, 21355, 21997},  {18964, 19902, 21604, 23423},
+  {18442, 20525, 21669, 22489},  {18576, 19983, 20601, 22501},
+  {19032, 20131, 20885, 21588},  {18650, 19807, 21250, 23773},
+  {18953, 20026, 22131, 23684},  {18503, 19331, 21785, 23436},
+  {18547, 19277, 22127, 22665},  {18568, 19516, 22515, 23381},
+  {18265, 19970, 22486, 23292},  {17892, 19371, 22161, 23140},
+  {17781, 19729, 22099, 23747},  {17967, 19023, 21910, 23555},
+  {18344, 19422, 22399, 24084},  {18100, 19155, 22805, 23563},
+  {17662, 19842, 22636, 23356},  {17286, 19584, 22080, 23081},
+  {17581, 20216, 22205, 23048},  {17185, 18784, 22305, 23381},
+  {17536, 18919, 21762, 22936},  {17133, 19549, 22890, 23623},
+  {16800, 20050, 22205, 23162},  {16746, 19221, 21691, 22963},
+  {17267, 20295, 21568, 22770},  {17142, 18241, 21537, 22745},
+  {17543, 18698, 21243, 23593},  {17543, 18887, 22031, 24295},
+  {17969, 18981, 21940, 22221},  {18032, 19083, 20828, 23498},
+  {18004, 18914, 21295, 24173},  {17864, 18848, 20091, 23084},
+  {17883, 18761, 20144, 23826},  {17587, 18497, 20528, 24268},
+  {18162, 18917, 20607, 24294},  {17537, 20016, 20398, 22412},
+  {18166, 19207, 20285, 21193},  {17779, 20279, 21104, 21608},
+  {16351, 20401, 21167, 21828},  {17882, 20877, 22149, 22884},
+  {17826, 20443, 22518, 23464},  {18565, 20479, 22327, 23847},
+  {18721, 21000, 22111, 22848},  {18324, 21104, 22522, 23268},
+  {18108, 20837, 22961, 23552},  {17143, 20620, 22904, 23598},
+  {17307, 21378, 22600, 23344},  {18924, 21142, 22856, 23446},
+  {18844, 20616, 22988, 23640},  {18517, 21639, 22942, 23489},
+  {18258, 20088, 23042, 23644},  {19036, 19965, 22696, 23463},
+  {19111, 20664, 22362, 23930},  {19102, 21281, 22448, 23093},
+  {19454, 20959, 23146, 23821},  {19478, 20989, 22350, 23931},
+  {19544, 21602, 22835, 23385},  {20018, 21227, 22776, 23449},
+  {19677, 21190, 22709, 24224},  {20475, 21412, 22481, 23214},
+  {20409, 21667, 22921, 23513},  {20247, 20737, 21048, 21642}
+}; // cb_lsp_5th
+
+static const uint16_t div_30[31]=
+{
+    FIX( 0/30., 15), FIX( 1/30., 15), FIX( 2/30., 15),
+    FIX( 3/30., 15), FIX( 4/30., 15), FIX( 5/30., 15),
+    FIX( 6/30., 15), FIX( 7/30., 15), FIX( 8/30., 15),
+    FIX( 9/30., 15), FIX(10/30., 15), FIX(11/30., 15),
+    FIX(12/30., 15), FIX(13/30., 15), FIX(14/30., 15),
+    FIX(15/30., 15), FIX(16/30., 15), FIX(17/30., 15),
+    FIX(18/30., 15), FIX(19/30., 15), FIX(20/30., 15),
+    FIX(21/30., 15), FIX(22/30., 15), FIX(23/30., 15),
+    FIX(24/30., 15), FIX(25/30., 15), FIX(26/30., 15),
+    FIX(27/30., 15), FIX(28/30., 15), FIX(29/30., 15),
+    FIX(30/30., 15)
+};
+
+/* 8k5 */
+static int16_t mean_isf_8k5[10] = {
+    3027,   4607,  7797, 11559, 14475,
+    18068, 20873, 24201, 26332,   772
+};
+
+static int16_t dico1_isf_8k5[64][2] = {
+    {   309,   -238}, {  1718,  -1143}, {  -699,  -2473}, {   561,  -1553},
+    { -1693,  -3201}, { -3134,  -4863}, {   516,   7171}, {  2434,   6391},
+    {  6998,   9446}, {  4646,   9862}, {  6885,  11535}, {  5957,  16214},
+    { 10163,  10936}, {  5585,   7608}, { -2352,  -5526}, { -4468,  -5077},
+    {  -865,  -1270}, {  -570,  -3741}, { -1632,  -4540}, {  -686,   2256},
+    {  2356,   2918}, {  2472,   4663}, {  4347,   5738}, {  3814,   3781},
+    {  1613,    250}, { -2713,  -3767}, { -4180,  -6983}, { -2429,  -2065},
+    {  6769,   5695}, {  8681,   7772}, {  2519,   1534}, {  5560,   3701},
+    {  -806,    551}, {   908,   3238}, {  8771,  18822}, {  8413,  13856},
+    {   499,  -2673}, {  3722,   7777}, {   795,   1518}, { -2066,   -539},
+    { -2336,   1179}, { 11877,  15133}, { -2178,   3429}, {  1034,  15291},
+    { 11001,  23082}, { -3881,   -503}, {  2057,   8674}, {  4124,   2009},
+    {  2951,  11545}, { -3427,  -6134}, { -1283,   5905}, {   518,  10467},
+    {  -388,   4187}, { -1612,   8351}, { -4026,   2242}, {   844,   5231},
+    { -1856,  -7268}, { -3355,   5579}, { -2374,  11930}, {  3432,  20580},
+    {  4964,  13298}, { -4183,  -2825}, {  2920,    193}, { -4798,  -8255}
+};
+
+static int16_t dico2_isf_8k5[128][2] = {
+    {  1035,    248}, { -2844,    434}, { -7169,  -7570}, { -5675,  -1956},
+    { -6362,  -5284}, { -6540,   2771}, {  8136,  10593}, { 10513,   9622},
+    { 14957,  12415}, { 10258,  12462}, { 16066,  15570}, { 18277,  13748},
+    { 13172,  17339}, {   626,   5045}, { -1091,   3418}, { -4570,  -3993},
+    { -9039,  -6572}, { -2038,  -3784}, { -8758, -16236}, { -4647,  -9835},
+    {  5621,   5657}, {  1285,   2678}, {  8505,   3453}, {  6432,   2344},
+    {  5083,    486}, { -1435,  -6291}, { -4299, -11874}, { -2994,  -8228},
+    { -9134, -11135}, { -6846,  -9791}, {-11066, -15673}, { -5084,    581},
+    {   172,  -4499}, {  3026,   -581}, {  2162,  -2798}, { -3671,  -5909},
+    { 12354,   8569}, { 16845,  11082}, { 14542,   9397}, { -1434,  -1164},
+    { -4790,   4690}, { -6487,   8898}, { -9378,   7045}, { -8807,  -4490},
+    { 12608,   4136}, { 10206,   4821}, { 11951,   6161}, {  -963,   1348},
+    {  3125,   4646}, {  5016,   3573}, { -2455,   5156}, { -9117,   -892},
+    { -9859, -13368}, {  8377,   6027}, { -3545,   2632}, {-11730, -11657},
+    { -7312, -14292}, { -8946,   1785}, { -8852,  10005}, {-11683,  -7374},
+    {  7035,   4589}, { -4295,   7206}, {   252,  -2098}, {  4066,   7184},
+    { -7604,  -2811}, {  6710,   7538}, { 21182,  15324}, { 21266,  21746},
+    { 19287,  17908}, {  8729,   8250}, { 23599,  19026}, { 12647,  11044},
+    { 10490,   2401}, {   975,  -6905}, {-10953,  -2629}, { -7097,     -8},
+    {-10936,  -9556}, {-12081,  10069}, {  4724,  -2941}, {-12373,   6074},
+    {-14169,   -448}, { -9120,  -8725}, {-11366, -18660}, {  5521,   9716},
+    { 12742,  13965}, {  2924,  -5130}, { 19799,  10611}, {  1529,   7325},
+    { 15951,   6394}, { 16188,  19738}, {-12575, -13951}, {-10984,  -5234},
+    { -3532,  -1787}, { 17158,   8700}, {  3358,   1997}, { -3580,   9702},
+    { 13808,   6769}, { -6804,   5994}, { -6813, -11982}, { 23986,  13376},
+    {  8445,    720}, { -5772,  11862}, { -5739,  15251}, {  1148,  13140},
+    { -9365,  13365}, { -2475, -10631}, {  -454,  10041}, { -2369,  12661},
+    { -5196,  -7596}, { -5237, -13644}, {-11567,   3167}, { -1287,   7375},
+    {-13418,  -4426}, { -8790,   4378}, {  7160,  13329}, { 10422,   7174},
+    {  9300,  16170}, {-15112,  -7541}, {-14470, -12240}, {  2513,   9885},
+    {  4257,  12549}, {-13039,  -9534}, {  3152,  16961}, {-13831, -16607},
+    {  -790,  -8764}, {  6854,  -1322}, { -1635,  16284}, {-11210,    335}
+};
+
+static int16_t dico3_isf_8k5[128][2] = {
+    {  1003,    253}, { -8826, -16223}, { -3651,  -8205}, { -4966, -12438},
+    {  1545,   2417}, {  9987,   9945}, { 10873,   7435}, { 13012,   8291},
+    { 14258,  10294}, { 16047,  11379}, { 18160,  10514}, { 15781,   8184},
+    { -1582,   5280}, {  -387,   3115}, {  -973,  -1149}, { -4772,  -5948},
+    { -7602,  -2155}, { -1395,  -3445}, { -3563,  -3888}, {-18470,  -7109},
+    {-14830,  -6038}, {-13625,  -8250}, { -9017,  -7388}, { -5343,  -2062},
+    { -4266,   4691}, {  7854,  11222}, {   578,   7914}, {  6283,   9247},
+    {  3424,   9035}, {  7718,   6705}, {  5327,   6966}, { -2722,   2565},
+    { -7219,  -5915}, {-10088,  -5287}, { -7655, -11967}, { -9943, -14043},
+    { -8274,  -9573}, {-11926,  -6455}, {  2648,  -1147}, {  6016,   3504},
+    {  4399,     92}, {  2904,   1122}, {   856,  -2029}, {-11085,  -8876},
+    { -2673,    341}, { -6145,  -7966}, {  -520,  -6144}, {  9719,   5566},
+    { 11887,   4646}, {  8258,   4225}, {  5744,   1538}, {-10485, -18024},
+    {-13065, -13027}, {-19912, -24595}, {-13004, -19142}, {   610,  -4118},
+    {  4164,   2721}, { -3105,  -1829}, {  3010,   6216}, {  2883,  -3722},
+    {  -682,   1109}, {  2901,   3951}, { -2484,  -5934}, {  4651,   4791},
+    {-11602,  -1186}, {-10308,  -3001}, { -8313,  -4013}, { -4665,     50},
+    { -9179,   -489}, { -9602,   3436}, {  6597,   5229}, {  1048,   4867},
+    {-10402, -11468}, {-16004,  -3904}, {  1598,  -6197}, {-12667,  -4043},
+    {-10951,   1316}, {-13859,    535}, {-14052,  -1840}, { -7677,  10822},
+    { -6854,    -38}, {    19,  12101}, { 10743,  15125}, { -5981,  -4002},
+    {-15750, -11507}, { -2890, -10412}, { 11948,  10299}, { 16637,  15798},
+    {-15561, -14624}, {-18890, -12857}, {-13188, -10531}, { 10188,   2901},
+    {-16512, -17510}, { -5531, -10238}, {  7612,   2452}, {  4756,  -2181},
+    {-16433,  -8977}, {-16874,   -860}, {-16985,   2045}, {-19153,  -3242},
+    {-12857,   8932}, {-11130,   5640}, { 10318,  12483}, {  7244,  14109},
+    {  8571,   8462}, {-13180,   3158}, { -7869,   1963}, {  4665,  11929},
+    { -5328,   2309}, { -6991, -14230}, {-15078, -21855}, {-12676, -15888},
+    { 13646,  14980}, { 14311,  17873}, { 21138,  13496}, { 17807,  13334},
+    { 12993,  12524}, { -1058,  -8424}, { 15209,  13259}, { 19292,  15867},
+    { 19498,  19475}, { 13559,   6267}, {  8642,  18430}, {  6581,   -457},
+    {  8530,    843}, { -3515,   8332}, {-15835,   5445}, { -7212,   5476}
+};
+
+static int16_t dico4_isf_8k5[128][2] = {
+    {  -146,   -915}, {  2879,   1154}, {-11831,   -747}, { -9147, -15088},
+    {-10983,  -5347}, { -5000, -10908}, {  7062,   5651}, {  6598,    843},
+    {  4551,    917}, {  3978,   2284}, {  5694,   2441}, {  2304,  -2061},
+    {  1479,    876}, { -2703,    502}, { -2729,   3917}, { -4892,  -3431},
+    {   457,   1932}, {  -523,  -2746}, { -4734,   5006}, { -1133,   1445},
+    { -1008,   2968}, { -1388,    -53}, {  3156,   3325}, {  5229,   5687},
+    {  7473,   3527}, { -6349,  -2191}, { -7758,   -759}, { -8253,  -2560},
+    {-15227, -11208}, {-16064,  -7599}, {-18974,  -8965}, {  2624,  -3904},
+    {-10677,  -8142}, { -6814,  -3846}, {  1980,   2346}, {  -290,   6865},
+    {  2075,   6374}, { -2478,   5993}, { -7003,   7978}, { -8920,   5640},
+    {-11022,   7977}, {-16535,   3082}, {-17935,   7879}, {-19759,   6421},
+    {-19580,   2739}, {-17795,  -4557}, { -1660,  -1645}, { -8243,  -6945},
+    { -6458,  -5482}, {-14534, -15424}, {-10953, -11809}, { -7680, -11787},
+    { -6036,  -7237}, { -2917,  -7787}, { -2130,  -6136}, {  -837,  -4735},
+    {  1613,   -513}, {-10928,   1740}, { -8546,   2829}, { -6884,   5073},
+    {-14800,   7671}, {-21388,  -1019}, { -4315,   -110}, {-10260,  -2527},
+    {-12650,  -3354}, {   597,   3387}, { -5562,   1349}, { -3005,  -1028},
+    {  4513,   3910}, {   117,    482}, { -3055,  -9965}, { -1916,  -3314},
+    { -7466,   1203}, { 10733,   8431}, { -6385,  -9371}, { -4572,  -8513},
+    { -4748,  -5019}, { -3015,  -4550}, {  1201,  -5605}, {  -399,  -6588},
+    {  -948,   4647}, {-13553,   1999}, {-16053,    758}, {-17664,  -1439},
+    {-15012,  -4401}, {-14269,  -1533}, {-13084,  -7274}, {   827,  -1975},
+    { -8577,  -9464}, { -3347,  -2666}, {  3339,   -381}, {  5981,   4155},
+    {  8719,   5080}, {  4083,  -2204}, { -4661,  -1687}, { -3978,   1510},
+    { -4060,  -6437}, { -8792,  -4749}, { -4364,   3109}, {  3449,   5137},
+    { 10041,   3726}, {  6522,   7682}, { 11160,  11375}, { 13055,   9475},
+    {  5407,   -774}, {   772,  -3735}, { -1307,  -8267}, {  8670,   7260},
+    {  8498,   9767}, {  2014,   4068}, { -5936,   -433}, { -5400, -13146},
+    {   801,   5158}, { 10626,   6019}, { -9485,    -44}, { -2030,   9207},
+    { -6306,   3122}, {  1835,   9021}, { 13079,   6586}, { -2542,   2183},
+    {  5388,  10050}, { 15997,  11078}, {-10780,   4170}, {-13331,   4955},
+    {-16283,   5070}, { -4414,   7300}, {  4090,   7445}, {  8306,   2017}
+};
+
+static int16_t dico5_isf_8k5[32][2] = {
+    { -1944,    326}, {   462,   2649}, {  -888,  -1417}, { -6005,    -51},
+    {   -64,    839}, { -3415,  -1181}, { -7240,   2691}, { -1762,  -6729},
+    {  2172,   3933}, { -3980,   4339}, {  -953,   4532}, { -5979,  -6493},
+    {  1110,   -481}, { -1758,   2350}, {   795,  -2531}, {  1059,   6622},
+    {  3744,    396}, { -4014,   1484}, {   559,  -4747}, {  2234,  -7374},
+    {  4869,   5247}, {  4823,  -5134}, {  2684,  -1260}, {  4913,  -1628},
+    { -2060,  -3609}, {  2043,   1352}, { -5283,  -3060}, { -9181,  -1639},
+    {  2878,  -3441}, {  3891,   2589}, {  6132,   1400}, {  7582,  -2822}
+};
+
+static float inter3_2_8k5[40] = { // @ 0x1a844
+   1.050000e-03,   2.780000e-03,  -3.658000e-03,  -5.027000e-03,
+   9.400000e-03,   9.029000e-03,  -1.934000e-02,  -1.375500e-02,
+   3.354300e-02,   1.677400e-02,  -5.083500e-02,  -1.416900e-02,
+   6.893600e-02,  -0.000000e+00,  -8.491900e-02,   3.695200e-02,
+   9.591500e-02,  -1.343330e-01,   8.985170e-01,   7.692710e-01,
+   9.591500e-02,   4.486350e-01,  -8.491900e-02,  -1.785280e-01,
+   6.893600e-02,   9.553300e-02,  -5.083500e-02,  -5.040400e-02,
+   3.354300e-02,   2.308300e-02,  -1.934000e-02,  -7.466000e-03,
+   9.400000e-03,   0.000000e+00,  -3.658000e-03,   2.381000e-03,
+   1.050000e-03,  -2.405000e-03,   0.000000e+00,   2.145000e-03,
+};
+
+static float t_qua_gain[128][2] = // @ 0x1e9ec
+{
+  { 3.523000e-02, 1.615400e-01, },   { 4.922300e-02, 4.483590e-01, },
+  { 5.744300e-02, 8.090430e-01, },   { 7.243400e-02, 1.760306e+00, },
+  { 1.114910e-01, 5.664180e-01, },   { 1.128200e-01, 1.098524e+00, },
+  { 1.434930e-01, 7.268560e-01, },   { 1.448400e-01, 3.478000e-01, },
+  { 1.803410e-01, 1.050010e+00, },   { 1.881710e-01, 2.197256e+00, },
+  { 1.897710e-01, 2.569470e-01, },   { 1.982600e-01, 4.846780e-01, },
+  { 2.106220e-01, 7.558250e-01, },   { 2.206940e-01, 5.907880e-01, },
+  { 2.370620e-01, 1.322214e+00, },   { 2.551750e-01, 3.387100e-01, },
+  { 2.989800e-01, 9.190510e-01, },   { 3.146270e-01, 5.209610e-01, },
+  { 3.371060e-01, 1.469863e+00, },   { 3.414220e-01, 2.804546e+00, },
+  { 3.632570e-01, 7.362220e-01, },   { 3.638810e-01, 3.676400e-01, },
+  { 3.698500e-01, 1.937934e+00, },   { 3.701360e-01, 1.075201e+00, },
+  { 3.971520e-01, 5.494100e-01, },   { 4.265570e-01, 8.760150e-01, },
+  { 4.506860e-01, 2.155880e-01, },   { 4.681160e-01, 6.718480e-01, },
+  { 4.704950e-01, 1.242034e+00, },   { 4.741800e-01, 1.739845e+00, },
+  { 4.848750e-01, 4.905640e-01, },   { 4.989170e-01, 9.712380e-01, },
+  { 5.309960e-01, 7.857650e-01, },   { 5.397680e-01, 2.130689e+00, },
+  { 5.460210e-01, 5.895440e-01, },   { 5.466320e-01, 3.050846e+00, },
+  { 5.523360e-01, 3.897750e-01, },   { 5.563020e-01, 1.400103e+00, },
+  { 5.596880e-01, 1.105421e+00, },   { 5.741400e-01, 6.675130e-01, },
+  { 5.955470e-01, 8.289430e-01, },   { 5.977710e-01, 4.969290e-01, },
+  { 6.170790e-01, 1.863075e+00, },   { 6.196570e-01, 1.221713e+00, },
+  { 6.211720e-01, 9.502750e-01, },   { 6.284260e-01, 6.307660e-01, },
+  { 6.286890e-01, 4.242164e+00, },   { 6.408990e-01, 1.529846e+00, },
+  { 6.458130e-01, 3.311270e-01, },   { 6.530560e-01, 7.481680e-01, },
+  { 6.629090e-01, 1.077438e+00, },   { 6.695050e-01, 2.631114e+00, },
+  { 6.815700e-01, 1.839298e+00, },   { 6.878440e-01, 9.034000e-01, },
+  { 6.886600e-01, 1.270830e+00, },   { 6.950700e-01, 5.782270e-01, },
+  { 6.979260e-01, 4.284400e-01, },   { 7.154540e-01, 8.123550e-01, },
+  { 7.299810e-01, 1.539357e+00, },   { 7.374340e-01, 1.106765e+00, },
+  { 7.402410e-01, 2.033374e+00, },   { 7.408710e-01, 5.684600e-01, },
+  { 7.526890e-01, 6.984610e-01, },   { 7.565870e-01, 8.930780e-01, },
+  { 7.677970e-01, 4.992460e-01, },   { 7.685160e-01, 3.712434e+00, },
+  { 7.731530e-01, 1.332360e+00, },   { 7.861250e-01, 1.042996e+00, },
+  { 7.887920e-01, 2.383880e-01, },   { 7.908610e-01, 2.273229e+00, },
+  { 7.953380e-01, 1.582767e+00, },   { 8.096210e-01, 5.955010e-01, },
+  { 8.210320e-01, 7.564600e-01, },   { 8.245900e-01, 9.229250e-01, },
+  { 8.260190e-01, 1.186793e+00, },   { 8.274260e-01, 1.885076e+00, },
+  { 8.300800e-01, 6.088666e+00, },   { 8.370280e-01, 2.819993e+00, },
+  { 8.455610e-01, 1.490623e+00, },   { 8.483230e-01, 4.104360e-01, },
+  { 8.565220e-01, 7.297250e-01, },   { 8.626360e-01, 9.668800e-01, },
+  { 8.745610e-01, 1.681660e+00, },   { 8.747510e-01, 1.177630e+00, },
+  { 8.792890e-01, 2.301300e+00, },   { 8.866710e-01, 6.130680e-01, },
+  { 8.967290e-01, 7.810970e-01, },   { 9.047770e-01, 3.484111e+00, },
+  { 9.060980e-01, 1.330892e+00, },   { 9.191820e-01, 1.877203e+00, },
+  { 9.199010e-01, 5.695110e-01, },   { 9.217720e-01, 1.034126e+00, },
+  { 9.224390e-01, 3.760000e-01, },   { 9.342210e-01, 1.485214e+00, },
+  { 9.388420e-01, 8.691350e-01, },   { 9.391660e-01, 2.378294e+00, },
+  { 9.589330e-01, 1.122722e+00, },   { 9.590420e-01, 6.940980e-01, },
+  { 9.609950e-01, 1.743430e+00, },   { 9.707630e-01, 2.884897e+00, },
+  { 9.828810e-01, 8.145060e-01, },   { 9.901410e-01, 1.330022e+00, },
+  { 9.964470e-01, 1.823381e+00, },   { 1.000013e+00, 9.674980e-01, },
+  { 1.000743e+00, 4.805970e-01, },   { 1.008020e+00, 5.095226e+00, },
+  { 1.013883e+00, 2.105435e+00, },   { 1.026438e+00, 6.913120e-01, },
+  { 1.027361e+00, 1.558169e+00, },   { 1.030123e+00, 3.586526e+00, },
+  { 1.033916e+00, 1.118036e+00, },   { 1.039315e+00, 2.543360e+00, },
+  { 1.068596e+00, 8.363800e-01, },   { 1.081023e+00, 1.318768e+00, },
+  { 1.093150e+00, 2.267843e+00, },   { 1.095607e+00, 1.712383e+00, },
+  { 1.102816e+00, 1.037334e+00, },   { 1.103231e+00, 3.536292e+00, },
+  { 1.107320e+00, 5.086150e-01, },   { 1.150000e+00, 7.999000e+00, },
+  { 1.156731e+00, 1.236772e+00, },   { 1.168428e+00, 2.268084e+00, },
+  { 1.184130e+00, 7.758390e-01, },   { 1.210609e+00, 1.511840e+00, },
+  { 1.220663e+00, 4.365683e+00, },   { 1.224016e+00, 9.831790e-01, },
+  { 1.252236e+00, 2.778535e+00, },   { 1.301176e+00, 1.923126e+00, },
+};
+
+static float pred_8k5[4] = // @ 0x1e8f8
+{
+  0.691,  0.504,  0.334,  0.200,
+};
+
+#endif // FFMPEG_SIPRDATA_H
Index: libavcodec/Makefile
===================================================================
--- libavcodec/Makefile	(revision 19727)
+++ libavcodec/Makefile	(working copy)
@@ -200,6 +200,7 @@
 OBJS-$(CONFIG_SGI_DECODER)             += sgidec.o
 OBJS-$(CONFIG_SGI_ENCODER)             += sgienc.o rle.o
 OBJS-$(CONFIG_SHORTEN_DECODER)         += shorten.o
+OBJS-$(CONFIG_SIPR_DECODER)            += sipr.o acelp_pitch_delay.o celp_math.o acelp_vectors.o acelp_filters.o celp_filters.o lsp.o
 OBJS-$(CONFIG_SMACKAUD_DECODER)        += smacker.o
 OBJS-$(CONFIG_SMACKER_DECODER)         += smacker.o
 OBJS-$(CONFIG_SMC_DECODER)             += smc.o
Index: libavcodec/sipr.c
===================================================================
--- libavcodec/sipr.c	(revision 0)
+++ libavcodec/sipr.c	(revision 0)
@@ -0,0 +1,966 @@
+#include <inttypes.h>
+#include <stdio.h>
+#include <math.h>
+#include <limits.h>
+#include <string.h>
+
+#include "avcodec.h"
+#include "libavutil/lfg.h"
+#define ALT_BITSTREAM_READER_LE
+#include "get_bits.h"
+
+#define FRAC_BITS 15
+#include "mathops.h"
+
+#include "lsp.h"
+#include "celp_math.h"
+#include "acelp_vectors.h"
+#include "acelp_pitch_delay.h"
+#include "acelp_filters.h"
+#include "celp_filters.h"
+#include "dsputil.h"
+
+#define LP_FILTER_ORDER   16
+#define L_INTERPOL        11
+#define L_SUBFR_16k0      80
+#define PITCH_MIN         30
+#define PITCH_MAX         281
+
+#define LSFQ_DIFF_MIN   FIX(50. * M_PI / 8000., 13)
+#define LSFQ_MIN        LSFQ_DIFF_MIN
+#define LSFQ_MAX        FIX(M_PI, 13)
+
+/* 8k5 */
+#define LP_FILTER_ORDER_8k5 10
+#define L_SUBFR_8k5         48
+#define PITCH_MIN_8k5       20
+#define PITCH_MAX_8k5       143
+
+#include "siprdata.h"
+
+typedef enum {
+    MODE_16k=0,
+    MODE_8k5,
+    MODE_6k5,
+    MODE_5k0,
+    MODE_COUNT
+} Sipr_Mode;
+
+typedef struct {
+    uint16_t bits_per_frame;
+    uint8_t subframe_size;
+    uint8_t subframe_count;
+    uint8_t frames_per_packet;
+    uint16_t treshpit;
+
+    /* bitstream parameters */
+    uint8_t number_of_fc_indexes;
+    uint8_t ma_predictor_bits;  ///< size in bits of the switched MA predictor
+
+    /** size in bits of the i-th stage vector of quantizer */
+    uint8_t vq_indexes_bits[5];
+
+    /** size in bits of the adaptive-codebook index for every subframe */
+    uint8_t pitch_delay_bits[5];
+
+    uint8_t gp_index_bits;
+    uint8_t fc_index_bits; ///< size in bits of the fixed codebook indexes
+    uint8_t gc_index_bits; ///< size in bits of the gain codebook indexes
+} Sipr_Mode_Param;
+
+static const Sipr_Mode_Param modes[MODE_COUNT] ={
+    // 16k
+    {
+        .bits_per_frame    = 160,
+        .subframe_size     = L_SUBFR_16k0,
+        .subframe_count    = 2,
+        .frames_per_packet = 1,
+        .treshpit          = FIX(0.00 ,15),
+
+        .number_of_fc_indexes = 5,
+        .ma_predictor_bits    = 1,
+        .vq_indexes_bits      = {7, 8, 7, 7, 7},
+        .pitch_delay_bits     = {9, 6},
+        .gp_index_bits        = 4,
+        .fc_index_bits        = 9,
+        .gc_index_bits        = 5
+    },{
+    // 8k5
+        .bits_per_frame    = 152,
+        .subframe_size     = L_SUBFR_8k5,
+        .subframe_count    = 3,
+        .frames_per_packet = 1,
+        .treshpit          = FIX(0.8, 15),
+
+        .number_of_fc_indexes = 3,
+        .ma_predictor_bits    = 0,
+        .vq_indexes_bits      = {6, 7, 7, 7, 5},
+        .pitch_delay_bits     = {8, 5, 5},
+        .gp_index_bits        = 0,
+        .fc_index_bits        = 9,
+        .gc_index_bits        = 7
+    },{
+    // 6k5
+        .bits_per_frame    = 232,
+        .subframe_size     = L_SUBFR_8k5,
+        .subframe_count    = 3,
+        .frames_per_packet = 2,
+        .treshpit          = FIX(0.8, 15),
+
+        .number_of_fc_indexes = 3,
+        .ma_predictor_bits    = 0,
+        .vq_indexes_bits      = {6, 7, 7, 7, 5},
+        .pitch_delay_bits     = {8, 5, 5},
+        .gp_index_bits        = 0,
+        .fc_index_bits        = 5,
+        .gc_index_bits        = 7
+    },{
+    // 5k0
+        .bits_per_frame    = 296,
+        .subframe_size     = L_SUBFR_8k5,
+        .subframe_count    = 5,
+        .frames_per_packet = 2,
+        .treshpit          = FIX(0.85, 15),
+
+        .number_of_fc_indexes = 1,
+        .ma_predictor_bits    = 0,
+        .vq_indexes_bits      = {6, 7, 7, 7, 5},
+        .pitch_delay_bits     = {8, 5, 8, 5, 5},
+        .gp_index_bits        = 0,
+        .fc_index_bits        = 10,
+        .gc_index_bits        = 7
+    }
+};
+
+typedef struct {
+    AVCodecContext *avctx;
+    Sipr_Mode_Param m;
+    Sipr_Mode mode;
+
+    AVLFG random_state;         ///< random number generator state
+    DSPContext dsp;
+
+    int pitch_delay_int_prev;
+
+    int16_t A_past[LP_FILTER_ORDER+1];   ///< FIXME: I don't know what is this
+    int16_t B_past[LP_FILTER_ORDER+1];   ///< FIXME: I don't know what is this
+
+    int16_t* exc;
+
+    int16_t past_gain_pit;
+    int16_t past_gain_code;
+    int16_t past_lsf_q[LP_FILTER_ORDER];
+    int16_t past_lsf[LP_FILTER_ORDER];
+    int16_t past_qua_en[2];
+    int16_t past_q_target[LP_FILTER_ORDER];
+    int ma_predictor_prev;
+
+    int16_t old_exc[L_INTERPOL + PITCH_MAX + 2 * L_SUBFR_16k0];
+
+    int16_t mem_preemph[LP_FILTER_ORDER];
+    int16_t mem_syn[LP_FILTER_ORDER + 2 * L_SUBFR_16k0];
+
+    /* 8k5 */
+    float past_gain_pit_8k5;
+    float past_gain_code_8k5;
+    float gain_har;
+    float old_pitch;
+    float dec_past_q_ener[4];
+    int16_t hpf_z[2];
+    int hpf_f[2];
+    float old_exc_8k5[PITCH_MAX_8k5 + L_INTERPOL];
+    DECLARE_ALIGNED_16(int16_t, code_fp[L_SUBFR_16k0]);
+    DECLARE_ALIGNED_16(int16_t, fc_v[L_SUBFR_16k0]);
+} Sipr_Context;
+
+typedef struct
+{
+    int bfi;              ///< bad frame indicator
+    int ma_pred_switch;   ///< switched MA predictor
+    int vq_indexes[5];
+    int pitch_delay[5];   ///< pitch delay
+    int gp_index[5];      ///< adaptive-codebook gain index
+    int fc_indexes[5][5]; ///< fixed-codebook index
+    int gc_index[5];      ///< fixed-codebook gain index
+} Sipr_Parameters;
+
+static void lsf_restore_from_previous(int16_t* lsf, int16_t *past_q_target,
+                                      int16_t* past_lsf_q, int k_prev)
+{
+    int i;
+
+    memcpy(lsf, past_lsf_q, LP_FILTER_ORDER * sizeof(int16_t));
+
+    for (i=0; i<LP_FILTER_ORDER; i++) {
+        int tmp  = lsf[i] - ((ma_pred[k_prev] * past_q_target[i]) >> 15);
+        past_q_target[i] = (tmp * ma_pred_sumi[k_prev]) >> 13;
+    }
+}
+
+static void lsf_decode(int16_t* past_q_target, int16_t* lsfq,
+                       int ma_pred_switch, const int* vq_indexes)
+{
+    int i;
+    int16_t lspq[LP_FILTER_ORDER];
+
+    lspq[0] = cb_lsp_1st[vq_indexes[0]][0];
+    lspq[1] = cb_lsp_1st[vq_indexes[0]][1];
+    lspq[2] = cb_lsp_1st[vq_indexes[0]][2];
+
+    lspq[3] = cb_lsp_2nd[vq_indexes[1]][0];
+    lspq[4] = cb_lsp_2nd[vq_indexes[1]][1];
+    lspq[5] = cb_lsp_2nd[vq_indexes[1]][2];
+
+    lspq[6] = cb_lsp_3rd[vq_indexes[2]][0];
+    lspq[7] = cb_lsp_3rd[vq_indexes[2]][1];
+    lspq[8] = cb_lsp_3rd[vq_indexes[2]][2];
+
+    lspq[9]  = cb_lsp_4th[vq_indexes[3]][0];
+    lspq[10] = cb_lsp_4th[vq_indexes[3]][1];
+    lspq[11] = cb_lsp_4th[vq_indexes[3]][2];
+
+    lspq[12] = cb_lsp_5th[vq_indexes[4]][0];
+    lspq[13] = cb_lsp_5th[vq_indexes[4]][1];
+    lspq[14] = cb_lsp_5th[vq_indexes[4]][2];
+    lspq[15] = cb_lsp_5th[vq_indexes[4]][3];
+
+    for (i=0; i<LP_FILTER_ORDER; i++) {
+        lsfq[i] = (lspq[i] * ma_pred_sum[ma_pred_switch] +
+                past_q_target[i] * ma_pred[ma_pred_switch]) >> 15;
+    }
+    memcpy(past_q_target, lspq, LP_FILTER_ORDER * sizeof(int16_t));
+}
+
+static void d_isf_ma_8k5(int16_t *isp, int16_t *past_q_target,
+                         int16_t *past_lsf_q, const Sipr_Parameters *parm,
+                         int bfi)
+{
+    int i;
+    int16_t isf_tmp[10];
+    int16_t isfnew[10];
+
+    if (bfi == 2) {
+        memset(isf_tmp, 0, 10 * sizeof(*isf_tmp));
+
+        for (i=0; i<10; i++)
+            isfnew[i] = past_lsf_q[i] * 0.9 + mean_isf_8k5[i] * 0.1;
+    } else {
+        isf_tmp[0] = dico1_isf_8k5[parm->vq_indexes[0]][0];
+        isf_tmp[1] = dico1_isf_8k5[parm->vq_indexes[0]][1];
+        isf_tmp[2] = dico2_isf_8k5[parm->vq_indexes[1]][0];
+        isf_tmp[3] = dico2_isf_8k5[parm->vq_indexes[1]][1];
+        isf_tmp[4] = dico3_isf_8k5[parm->vq_indexes[2]][0];
+        isf_tmp[5] = dico3_isf_8k5[parm->vq_indexes[2]][1];
+        isf_tmp[6] = dico4_isf_8k5[parm->vq_indexes[3]][0];
+        isf_tmp[7] = dico4_isf_8k5[parm->vq_indexes[3]][1];
+        isf_tmp[8] = dico5_isf_8k5[parm->vq_indexes[4]][0];
+        isf_tmp[9] = dico5_isf_8k5[parm->vq_indexes[4]][1];
+
+        if (!bfi) {
+            for (i=0; i < 10; i++)
+                isfnew[i] = (past_q_target[i] * FIX(0.33,13) +
+                             isf_tmp[i] *       FIX(1.  ,13) +
+                             mean_isf_8k5[i] *  FIX(4.  ,13)) >> 15;
+        } else {
+            for (i=0; i<10; i++) {
+                isfnew[i] = mean_isf_8k5[i] +
+                    (4 * past_lsf_q[i] - 4 * mean_isf_8k5[i] + isf_tmp[i] -
+                     past_q_target[i] * 0.1089) * (0.5988024 * 0.25);
+                isf_tmp[i] = isfnew[i] - past_q_target[i] * (0.33/4)  -
+                    mean_isf_8k5[i];
+            }
+        }
+
+        // Ugh, SIPR implement ff_acelp_reorder_lsf() in a buggy way
+        ff_acelp_reorder_lsf(isfnew, 50 * (1<<3), 50 * (1<<3), INT16_MAX, 9);
+        isfnew[9] = FFMIN(isfnew[9], 520 * (1<<3));
+    }
+
+    memcpy(past_q_target, isf_tmp, 10*sizeof(*isf_tmp));
+    memcpy(past_lsf_q, isfnew, 10*sizeof(*isfnew));
+
+    for (i=0; i < 9; i++)
+        isp[i] = ff_cos((isfnew[i]*FIX(1./4000., 26)) >> 15);
+
+    isp[9] = (isfnew[9] * FIX(1./325., 26)) >> 15;
+}
+
+static int dec_delay3_1st(int index)
+{
+    if (index < 390)
+        return index + 88;
+    else
+        return 3 * index - 690;
+}
+
+static int dec_delay3_2nd(int index, int pit_min, int pit_max,
+                          int pitch_delay_int_prev)
+{
+    int pitch_delay_min =
+        FFMIN(FFMAX(pitch_delay_int_prev - 10, pit_min), pit_max - 19) ;
+
+    if (index < 62)
+        return 3 * pitch_delay_min + index - 2;
+    else
+        return 3 * pitch_delay_int_prev;
+}
+
+/**
+ * main decoding routine
+ */
+static int decod_frame_16k(Sipr_Context * ctx, Sipr_Parameters *params, int16_t* out_data)
+{
+    int16_t *fc_v = ctx->fc_v;
+    int16_t gain_pitch, gain_code;
+    int16_t lp_filter_coeffs[2][LP_FILTER_ORDER + 1];
+    int16_t lsp[LP_FILTER_ORDER];
+    int16_t lsf[LP_FILTER_ORDER];
+    int16_t synth[LP_FILTER_ORDER + 2 * ctx->m.subframe_size];
+
+    int i, n, i_subfr;
+    int pitch_delay_3x, pitch_delay_int;
+    int16_t B[LP_FILTER_ORDER];           // FIXME: I don't know what is this
+    int16_t var348[LP_FILTER_ORDER + 30]; // FIXME: I don't know what is this
+
+    if (params->bfi) {
+        for (i=0; i<5; i++) {
+            params->fc_indexes[0][i] = av_lfg_get(&ctx->random_state) & 0x1ff;
+            params->fc_indexes[1][i] = av_lfg_get(&ctx->random_state) & 0x1ff;
+        }
+        lsf_restore_from_previous(lsf, ctx->past_q_target, ctx->past_lsf_q,
+                                  ctx->ma_predictor_prev);
+    } else {
+        lsf_decode(ctx->past_q_target, lsf, params->ma_pred_switch,
+                   params->vq_indexes);
+        ff_acelp_stabilize_lsf(lsf, LSFQ_DIFF_MIN, LSFQ_MIN, LSFQ_MAX,
+                               LP_FILTER_ORDER);
+
+        memcpy(ctx->past_lsf_q, lsf, LP_FILTER_ORDER * sizeof(int16_t));
+        ctx->ma_predictor_prev = params->ma_pred_switch;
+    }
+    ff_acelp_lsf2lsp(lsp, lsf, LP_FILTER_ORDER);
+
+    ff_acelp_lp_decode(lp_filter_coeffs[0], lp_filter_coeffs[1], lsp,
+                       ctx->past_lsf, LP_FILTER_ORDER);
+    memcpy(ctx->past_lsf, lsp, LP_FILTER_ORDER * sizeof(int16_t));
+
+    memcpy(synth, ctx->mem_syn, LP_FILTER_ORDER * sizeof(int16_t));
+    for (i=0, i_subfr=0; i < ctx->m.subframe_count; i++, i_subfr += ctx->m.subframe_size) {
+        if (params->bfi) {
+            pitch_delay_3x = 3 * (ctx->pitch_delay_int_prev + 1);
+        } else {
+            if (!i)
+                pitch_delay_3x = dec_delay3_1st(params->pitch_delay[i]);
+            else
+                pitch_delay_3x = dec_delay3_2nd(params->pitch_delay[i], PITCH_MIN, PITCH_MAX,  ctx->pitch_delay_int_prev);
+        }
+        pitch_delay_int = (pitch_delay_3x+1)/3;
+
+        if (params->bfi)
+            gain_pitch = (ctx->past_gain_pit * FIX(0.95, 14)) >> 14;
+        else
+            gain_pitch = qua_gain_pitch[params->gp_index[i]];
+        ctx->past_gain_pit = FFMIN(gain_pitch, 1<<14);
+
+        ff_acelp_interpolate(ctx->exc + i_subfr,
+                             ctx->exc + i_subfr - pitch_delay_3x/3,
+                             ff_acelp_interp_filter, 6, (pitch_delay_3x%3)<<1,
+                             10, ctx->m.subframe_size);
+
+
+        memset(fc_v, 0, ctx->m.subframe_size * sizeof(int16_t));
+        ff_acelp_two_pulses_per_track(fc_v, ff_fc_4pulses_8bits_tracks_13,
+                                      ff_fc_4pulses_8bits_tracks_13,
+                                      params->fc_indexes[i], 5, 4);
+
+        // enhance harmonics
+        ff_acelp_weighted_vector_sum(fc_v + pitch_delay_int,
+                                     fc_v + pitch_delay_int,
+                                     fc_v, 1 << 14, ctx->past_gain_pit, 0, 14,
+                                     ctx->m.subframe_size - pitch_delay_int);
+
+        if (params->bfi) {
+            ff_acelp_update_past_gain(ctx->past_qua_en, 0, 1, 1);
+            gain_code = (ctx->past_gain_code * FIX(0.8, 13)) >> 13;
+        } else {
+            int gain_corr_factor = qua_gain_code[params->gc_index[i]];
+            gain_code = ff_acelp_decode_gain_code(&ctx->dsp, gain_corr_factor,
+                                                  fc_v, 0xe8985,
+                                                  ctx->past_qua_en,
+                                                  gain_prediction_coeff,
+                                                  ctx->m.subframe_size, 2);
+            ff_acelp_update_past_gain(ctx->past_qua_en, gain_corr_factor, 1, 0);
+        }
+        ctx->past_gain_code = gain_code;
+
+        ff_acelp_weighted_vector_sum(&ctx->exc[i_subfr], &ctx->exc[i_subfr],
+                                     fc_v, gain_pitch, gain_code, 0x2000, 14,
+                                     ctx->m.subframe_size);
+
+        ff_celp_lp_synthesis_filter(&synth[i_subfr+16],
+                                    &lp_filter_coeffs[i_subfr?1:0][1],
+                                    &ctx->exc[i_subfr], ctx->m.subframe_size,
+                                    LP_FILTER_ORDER, 0, 0x800);
+
+        ctx->pitch_delay_int_prev = pitch_delay_int;
+    }
+    memcpy(ctx->mem_syn, synth + 2*ctx->m.subframe_size,
+           LP_FILTER_ORDER * sizeof(int16_t));
+    memmove(ctx->old_exc, ctx->old_exc + 2 * ctx->m.subframe_size,
+            (L_INTERPOL+PITCH_MAX) * sizeof(int16_t));
+
+
+    /* postfilter start */
+    memcpy(synth, ctx->mem_preemph, LP_FILTER_ORDER * sizeof(int16_t));
+    memcpy(var348, synth, LP_FILTER_ORDER * sizeof(int16_t));
+
+    for (n=0; n<LP_FILTER_ORDER + 1; n++)
+        B[n] = (ctx->A_past[n] * weight_pow[n] + 0x4000) >> 15;
+
+    ff_celp_lp_synthesis_filter(var348 + LP_FILTER_ORDER, ctx->B_past+1,
+                                synth  + LP_FILTER_ORDER, 30, LP_FILTER_ORDER,
+                                0, 0x800);
+    ff_celp_lp_synthesis_filter(synth + LP_FILTER_ORDER, B+1,
+                                synth + LP_FILTER_ORDER,
+                                2 * ctx->m.subframe_size, LP_FILTER_ORDER,
+                                0, 0x800);
+
+    for (i=0; i<30; i++)
+        synth[i + LP_FILTER_ORDER] =
+                (div_30[30-i] * var348[i + LP_FILTER_ORDER] +
+                 div_30[   i] *  synth[i + LP_FILTER_ORDER]) >> 15;
+
+    memcpy(ctx->B_past, B, LP_FILTER_ORDER * sizeof(int16_t));
+    memcpy(ctx->A_past, &lp_filter_coeffs[1][0],
+           (LP_FILTER_ORDER + 1) * sizeof(int16_t));
+    memcpy(ctx->mem_preemph, synth + 2 * ctx->m.subframe_size,
+           LP_FILTER_ORDER * sizeof(int16_t));
+    /* postfilter end */
+
+
+    for (i=0; i < ctx->m.subframe_size * ctx->m.subframe_count; i++)
+        out_data[i] = av_clip_int16(synth[i + LP_FILTER_ORDER]);
+
+    return ctx->m.subframe_size * ctx->m.subframe_count;
+}
+
+/**
+ * Extract decoding parameters from the input bitstream.
+ * @param parms          parameters structure
+ * @param pgb            pointer to initialized GetbitContext structure
+ */
+static void decode_parameters(Sipr_Parameters* parms, GetBitContext *pgb,
+                              const Sipr_Mode_Param *p)
+{
+    int i, j;
+
+    parms->bfi              = 0;
+#ifdef TEST_BFI
+    parms->bfi = (1.0 * av_lfg_get(&ctx->random_state) / 0xffffffffUL) > TEST_BFI;
+#endif
+
+    parms->ma_pred_switch   = get_bits(pgb, p->ma_predictor_bits);
+
+    for(i=0; i<5; i++)
+            parms->vq_indexes[i]    = get_bits(pgb, p->vq_indexes_bits[i]);
+
+    for(i=0; i < p->subframe_count; i++) {
+        parms->pitch_delay[i]   = get_bits(pgb, p->pitch_delay_bits[i]);
+        parms->gp_index[i]      = get_bits(pgb, p->gp_index_bits);
+        for(j=0; j < p->number_of_fc_indexes; j++)
+            parms->fc_indexes[i][j] = get_bits(pgb, p->fc_index_bits);
+        parms->gc_index[i]      = get_bits(pgb, p->gc_index_bits);
+    }
+}
+
+static void sipr_decode_lp(int16_t *lp_filter_coeff, const int16_t *isfnew, const int16_t *past_lsf, int num_subfr, int filter_order)
+{
+    int i,j,t;
+    int16_t isfint[filter_order];
+    int t0 = 32767 / num_subfr;
+    int16_t *pAz = lp_filter_coeff;
+
+    t = t0 >> 1;
+    for (i=0; i<num_subfr; i++) {
+        for (j=0;j<filter_order; j++)
+            isfint[j] = (past_lsf[j] * (32767 - t) + t * isfnew[j]) >> 15;
+
+        ff_acelp_isp2lpc(pAz, isfint, filter_order >> 1);
+        pAz += filter_order + 1;
+        t += t0;
+    }
+}
+
+static void dec_lag3_8k5(int index, int i_subfr, int third_as_first, int bfi, int *old_pitch, int *t0_first, int* T0, int* T0_frac)
+{
+    int i;
+
+    if (((i_subfr==0)||(i_subfr==2 && third_as_first)) && (bfi==0)) {
+        if (index < 197) {
+           *T0 = (index+2)/3 + 19;
+           *T0_frac = index - *T0*3 + 58;
+        } else {
+          *T0 = index - 112;
+          *T0_frac = 0;
+        }
+        *t0_first = *T0;
+    } else if ((i_subfr!=0) && (bfi==0)) {
+        i = (index + 2) / 3 - 1;
+        *T0 = i + FFMIN(FFMAX(*t0_first - 5, PITCH_MIN_8k5), PITCH_MAX_8k5 - 9);
+        *T0_frac = index - 3*i - 2;
+    } else if ((i_subfr==0) && (bfi==2)) {
+        *T0 = *old_pitch / 3 + 1;
+        if (*T0 > PITCH_MAX_8k5)
+            *T0 = PITCH_MAX_8k5;
+        *T0_frac = 0;
+        *t0_first = *T0;
+    } else if ((i_subfr!=0) && (bfi==2)) {
+        *T0 = *old_pitch / 3 + 1;
+        if (*T0 > PITCH_MAX_8k5)
+            *T0 = PITCH_MAX_8k5;
+        *T0_frac = 0;
+    }
+    *old_pitch = 3 * *T0 + *T0_frac;
+}
+
+static void interpol_8k5(float *in, float *out, float *filter, int filter_len,
+                         int frac, int length)
+{
+    float *C1,*X0;
+    int step,i,j;
+    int filter_len_2x = filter_len << 1;
+    if (frac < 0) {
+        C1 = &filter[2*filter_len_2x-1];
+        X0 = &in[-filter_len];
+        step = -2;
+   } else {
+        C1 = &filter[frac];
+        X0 = &in[-filter_len+1];
+        step = 2;
+    }
+
+    for (i=0; i<length; i++) {
+        float *ptr = C1;
+        float s = 0;
+        for (j=0; j<filter_len_2x; j++, ptr+=step)
+            s += X0[j] * ptr[0];
+
+        out[i] = s;
+        X0++;
+    }
+}
+
+static void find_F_fp(int16_t *Az_fp, int pitch_delay_int, int16_t *freq_fp,
+                      int16_t treshpit, int length)
+{
+    int i;
+    int16_t tmp[LP_FILTER_ORDER_8k5+1];
+
+    memset(freq_fp, 0, LP_FILTER_ORDER_8k5 * sizeof(int16_t));
+    memset(freq_fp + 2*LP_FILTER_ORDER_8k5, 0, (length-LP_FILTER_ORDER_8k5) * sizeof(int16_t));
+
+    freq_fp[LP_FILTER_ORDER_8k5] = tmp[0] = Az_fp[0];
+    for (i=1; i< LP_FILTER_ORDER_8k5+1; i++) {
+        tmp[i]                         = (pow_tab2[i-1] * Az_fp[i]) >> 15;
+        freq_fp[LP_FILTER_ORDER_8k5+i] = (pow_tab1[i-1] * Az_fp[i]) >> 15;
+    }
+    ff_celp_lp_synthesis_filter(freq_fp + LP_FILTER_ORDER_8k5, tmp+1,
+                                freq_fp + LP_FILTER_ORDER_8k5, length,
+                                LP_FILTER_ORDER_8k5, 0, 0);
+    /* Code Above looks like: A'(z) := A(z/gamma3)/A(z/gamma4) */
+
+    ff_acelp_weighted_vector_sum(
+        freq_fp+LP_FILTER_ORDER_8k5+pitch_delay_int,
+        freq_fp+LP_FILTER_ORDER_8k5+pitch_delay_int,
+        freq_fp+LP_FILTER_ORDER_8k5,
+        32767,
+        treshpit,
+        1<<14,
+        15,
+        length-pitch_delay_int);
+}
+
+static void dec_ACB_27(int *fc_indexes, int16_t *xf, int16_t *code, int length)
+{
+    int i,n;
+
+    for (n=0; n<3; n++) {
+        int index1 = 3 * ((fc_indexes[n] >> 4) & 0xf) + n;
+        int index2 = 3 * (fc_indexes[n] & 0xf) + n;
+        float X = (fc_indexes[n] & 0x100) ? -1.0: 1.0;
+
+        if (X < 0)
+            for (i=index1; i < length; i++)
+                code[i] -= xf[i-index1];
+        else
+            for (i=index1; i < length; i++)
+                code[i] += xf[i-index1];
+
+        if (index2 < index1)
+            X = -X;
+
+        if (X < 0)
+            for (i=index2; i < length; i++)
+                code[i] -= xf[i-index2];
+        else
+            for (i=index2; i < length; i++)
+                code[i] += xf[i-index2];
+    }
+}
+
+static void dec_ACB_15(int *fc_indexes, int16_t* xf, int16_t* code, int length)
+{
+    int i, j;
+    int index;
+
+    for (i=0; i<3; i++) {
+        index = 3 * (fc_indexes[i] & 0xf) + i;
+
+        if (fc_indexes[i] & 0x10) {
+            for (j=index; j < length; j++)
+                code[j] -= xf[j-index];
+        } else {
+            for (j=index; j < length; j++)
+                code[j] += xf[j-index];
+        }
+    }
+}
+
+static void dec_acb_2p10b(int fc_indexes, int16_t *xf, int16_t *code,
+                          int length)
+{
+    int index1, index2, offset, i;
+
+    offset = (fc_indexes >> 8) & 1;
+
+    index1 = ((fc_indexes >> 4) & 0xf) * 3 + offset;
+    index2 = (fc_indexes & 0xf) * 3 + offset + 1;
+
+    if (fc_indexes & 0x200)
+        FFSWAP(int, index1, index2);
+
+    for (i=index1; i<length; i++)
+        code[i] += xf[i-index1];
+
+    for (i=index2; i<length; i++)
+        code[i] -= xf[i-index2];
+}
+
+static void dec_acb_3p10b(int fc_indexes, int16_t *xf, int16_t *code,
+                          int length)
+{
+    int offset, i, j;
+
+    offset = (fc_indexes & 0x200) ? 2 : 0;
+
+    for (i=2; i>=0; i--) {
+        int index = (fc_indexes & 0x7) * 6 + i * 2;
+
+        if ((offset + index) & 0x3)
+            for (j=index; j<length; j++)
+                code[j] -= xf[j-index];
+        else
+            for (j=index; j<length; j++)
+                code[j] += xf[j-index];
+
+        fc_indexes >>= 3;
+    }
+}
+
+static float d_gain_8k5(DSPContext *dsp, int index, int subframe_len,
+                        const int16_t *code,  const float *dec_past_q_ener)
+{
+    int i;
+
+    float ener_code = 0.01;
+    float pred_code = 34.0;
+
+    ener_code = dsp->scalarproduct_int16(code, code, subframe_len, 8);
+    ener_code = 0.01 + ener_code / (1<<16);
+    ener_code = 10.0 * log10(ener_code / subframe_len);
+
+    for (i=0; i<4; i++)
+        pred_code += pred_8k5[i] * dec_past_q_ener[i];
+    pred_code -= ener_code;
+
+    return (float)pow(10, pred_code / 20) * t_qua_gain[index][1];
+}
+
+static int decod_frame_8k5(Sipr_Context * ctx, Sipr_Parameters *params,
+                           int16_t* out_data)
+{
+    int i_subfr, i, j;
+    int16_t Az_fp[(LP_FILTER_ORDER_8k5+1)*ctx->m.subframe_count];
+    int16_t isp[LP_FILTER_ORDER_8k5];
+    float exc_base[PITCH_MAX_8k5 + L_INTERPOL + ctx->m.subframe_size];
+    int16_t *pAz_fp;
+    float *exc;
+    int16_t xf_buf[ctx->m.subframe_size+LP_FILTER_ORDER_8k5];//FIXME: what is this?
+    int16_t *xf = xf_buf;
+    int16_t *code_fp = ctx->code_fp;
+    int T0,T0_frac,t0_first = 0;
+    float gain_pit, gain_code, gain_pit_inc;
+    int16_t synth_fp[ctx->m.subframe_size * ctx->m.subframe_count+LP_FILTER_ORDER_8k5];
+    float q_ener;
+
+    d_isf_ma_8k5(isp, ctx->past_q_target, ctx->past_lsf_q, params, 0);
+
+    sipr_decode_lp(Az_fp, isp, ctx->past_lsf, ctx->m.subframe_count, LP_FILTER_ORDER_8k5);
+    memcpy(ctx->past_lsf, isp, LP_FILTER_ORDER_8k5 * sizeof(int16_t));
+
+
+    exc = &exc_base[PITCH_MAX_8k5 + L_INTERPOL];
+    pAz_fp = Az_fp;
+
+    memcpy(synth_fp, ctx->mem_syn, LP_FILTER_ORDER_8k5 * sizeof(int16_t));
+    memmove(exc_base, ctx->old_exc_8k5, (PITCH_MAX_8k5 + L_INTERPOL) * sizeof(float));
+    for (i_subfr=0, i=0; i < ctx->m.subframe_count; i_subfr+=ctx->m.subframe_size, i++) {
+        dec_lag3_8k5(params->pitch_delay[i], i, ctx->mode == MODE_5k0, 0, &ctx->pitch_delay_int_prev, &t0_first, &T0, &T0_frac);
+
+        /* The following is pred_lt(exc, T0, T0_frac, ctx->m.subframe_size) */
+        interpol_8k5(exc-T0, exc, inter3_2_8k5, 10,-T0_frac, ctx->m.subframe_size);
+
+        find_F_fp(pAz_fp, T0, xf, ctx->m.treshpit, ctx->m.subframe_size);
+
+        xf += LP_FILTER_ORDER_8k5;
+
+        if (params->bfi) {
+            params->fc_indexes[i][0] = av_lfg_get(&ctx->random_state) & 0x1ff;
+            params->fc_indexes[i][1] = av_lfg_get(&ctx->random_state) & 0x1ff;
+            params->fc_indexes[i][2] = av_lfg_get(&ctx->random_state) & 0x1ff;
+        }
+
+        memset(code_fp, 0, ctx->m.subframe_size * sizeof(int16_t));
+        switch (ctx->mode) {
+        case MODE_6k5:
+            dec_ACB_15(params->fc_indexes[i], xf, code_fp,
+                       ctx->m.subframe_size);
+            break;
+        case MODE_8k5:
+            dec_ACB_27(params->fc_indexes[i], xf, code_fp,
+                       ctx->m.subframe_size);
+            break;
+        case MODE_5k0:
+            if (ctx->past_gain_pit_8k5 < 0.8)
+                dec_acb_3p10b(params->fc_indexes[i][0], xf, code_fp,
+                              ctx->m.subframe_size);
+            else
+                dec_acb_2p10b(params->fc_indexes[i][0], xf, code_fp,
+                              ctx->m.subframe_size);
+            break;
+        default:
+            av_log(ctx->avctx, AV_LOG_ERROR, "Fatal error: Mode %d is not supported by fixed-codevector decode routine\n", ctx->mode);
+            return 0;
+        }
+
+        if (params->bfi) {
+            if (params->bfi==1)
+                ctx->past_gain_pit_8k5 += gain_pit_inc;
+            else
+                ctx->past_gain_pit_8k5 =
+                    FFMIN(ctx->past_gain_pit_8k5 * 0.9, 1.0);
+
+            gain_pit = FFMIN(ctx->past_gain_pit_8k5, 1.0);
+
+            ctx->past_gain_code_8k5 = gain_code = 0.8 * ctx->past_gain_code_8k5;
+
+            q_ener = -14;
+            for (j=0; j<4; j++)
+                q_ener += ctx->dec_past_q_ener[j];
+            q_ener = 0.2 * q_ener;
+        } else {
+            ctx->past_gain_pit_8k5 = gain_pit =
+                t_qua_gain[params->gc_index[i]][0];
+
+            ctx->past_gain_code_8k5 = gain_code =
+                d_gain_8k5(&ctx->dsp, params->gc_index[i], ctx->m.subframe_size, code_fp, ctx->dec_past_q_ener);
+
+            q_ener = log10(t_qua_gain[params->gc_index[i]][1]) * 20.0;
+        }
+
+        ctx->dec_past_q_ener[3] = ctx->dec_past_q_ener[2];
+        ctx->dec_past_q_ener[2] = ctx->dec_past_q_ener[1];
+        ctx->dec_past_q_ener[1] = ctx->dec_past_q_ener[0];
+        ctx->dec_past_q_ener[0] = q_ener;
+
+        for (j=0; j<ctx->m.subframe_size; j++)
+            exc[j] = exc[j] * gain_pit + (code_fp[j] * gain_code) / (1<<12);
+
+        gain_pit *= 0.5 * gain_pit;
+        gain_pit = FFMIN(gain_pit, 0.4);
+
+        ctx->gain_har = 0.7 * ctx->gain_har + 0.3 * gain_pit;
+        ctx->gain_har = FFMIN(ctx->gain_har, gain_pit);
+        gain_code *= ctx->gain_har;
+
+        for (j=0; j < ctx->m.subframe_size; j++)
+            code_fp[j] = exc[j] - (gain_code * code_fp[j]) / (1<<12);
+
+        if (ff_celp_lp_synthesis_filter(&synth_fp[i_subfr+LP_FILTER_ORDER_8k5],
+                                        pAz_fp+1, code_fp,
+                                        ctx->m.subframe_size,
+                                        LP_FILTER_ORDER_8k5, 1, 0x800)) {
+            for (j=0; j<ctx->m.subframe_size; j++)
+                code_fp[i] >>= 1;
+            ff_celp_lp_synthesis_filter(&synth_fp[i_subfr+LP_FILTER_ORDER_8k5],
+                                        pAz_fp+1, code_fp,
+                                        ctx->m.subframe_size,
+                                        LP_FILTER_ORDER_8k5, 0, 0x800);
+        }
+
+        memmove(exc_base, exc_base + ctx->m.subframe_size,
+                (PITCH_MAX_8k5 + L_INTERPOL) * sizeof(float));
+        pAz_fp += LP_FILTER_ORDER_8k5+1;
+    }
+    memmove(ctx->old_exc_8k5, exc_base,
+            (PITCH_MAX_8k5 + L_INTERPOL) * sizeof(float));
+
+    memcpy(ctx->mem_syn,
+           &synth_fp[ctx->m.subframe_size * ctx->m.subframe_count],
+           LP_FILTER_ORDER_8k5 * sizeof(int16_t));
+
+    for (i=0; i < ctx->m.subframe_size * ctx->m.subframe_count; i++)
+        synth_fp[i+LP_FILTER_ORDER_8k5] >>= 1;
+
+    memcpy(synth_fp+LP_FILTER_ORDER_8k5 - 2, ctx->hpf_z, 2 * sizeof(int16_t));
+
+    ff_acelp_high_pass_filter(out_data, ctx->hpf_f,
+                              synth_fp+LP_FILTER_ORDER_8k5,
+                              ctx->m.subframe_size * ctx->m.subframe_count);
+
+    memcpy(ctx->hpf_z,
+           synth_fp+LP_FILTER_ORDER_8k5+ctx->m.subframe_size * ctx->m.subframe_count - 2, 2 * sizeof(int16_t));
+
+    return ctx->m.subframe_size * ctx->m.subframe_count;
+}
+
+static av_cold void init_decod_16k(Sipr_Context * ctx)
+{
+    int i;
+
+    ctx->past_qua_en[0] = -FIX(14., 10);
+    ctx->past_qua_en[1] = -FIX(14., 10);
+
+    ctx->exc = ctx->old_exc + L_INTERPOL + PITCH_MAX;
+
+    ctx->B_past[0] = ctx->A_past[0] = 4096;
+
+    for (i=0; i<LP_FILTER_ORDER; i++) {
+        ctx->past_lsf_q[i] = (i+1) * LSFQ_MAX / (LP_FILTER_ORDER + 1);
+        ctx->past_q_target[i] = (i+1) * LSFQ_MAX / (LP_FILTER_ORDER + 1);
+        ctx->past_lsf[i] = ff_cos((i+1) * 16384 / (LP_FILTER_ORDER + 1));
+    }
+
+}
+static av_cold void init_decod_8k5(Sipr_Context *ctx)
+{
+    int i;
+
+    ctx->old_pitch = 180;
+
+    for (i=0; i<LP_FILTER_ORDER_8k5; i++)
+        ctx->past_lsf[i] = ff_cos((i+1) * 16384 / (LP_FILTER_ORDER_8k5 + 1));
+
+    memcpy(ctx->past_lsf_q, mean_isf_8k5,
+           LP_FILTER_ORDER_8k5 * sizeof(int16_t));
+
+    ctx->dec_past_q_ener[0] = -14;
+    ctx->dec_past_q_ener[1] = -14;
+    ctx->dec_past_q_ener[2] = -14;
+    ctx->dec_past_q_ener[3] = -14;
+}
+
+static av_cold int ff_sipr_decoder_init(AVCodecContext * avctx)
+{
+    Sipr_Context *ctx = avctx->priv_data;
+    const char *m_name;
+
+    if (avctx->bit_rate > 12200) {
+        ctx->mode = MODE_16k;
+        init_decod_16k(ctx);
+        m_name = "16k";
+    } else if (avctx->bit_rate > 7500) {
+        ctx->mode = MODE_8k5;
+        init_decod_8k5(ctx);
+        m_name = "8k5";
+    } else if (avctx->bit_rate > 5750) {
+        ctx->mode = MODE_6k5;
+        init_decod_8k5(ctx);
+        m_name = "6k5";
+    } else {
+        av_log(avctx, AV_LOG_ERROR, "5k0 postfilter code not yet implemented, quality might suffer.\n");
+        ctx->mode = MODE_5k0;
+        init_decod_8k5(ctx);
+        m_name = "5k0";
+    }
+    ctx->m = modes[ctx->mode];
+    av_log(avctx, AV_LOG_ERROR, "Mode: %s\n", m_name);
+
+
+    dsputil_init(&ctx->dsp, avctx);
+    av_lfg_init(&ctx->random_state, 0x27425745);
+
+    return 0;
+}
+
+static int ff_sipr_decode_frame(AVCodecContext *avctx,
+                             void *datap, int *data_size,
+                             AVPacket *avpkt)
+{
+    Sipr_Context *ctx = avctx->priv_data;
+    const uint8_t *buf=avpkt->data;
+    int buf_size = avpkt->size;
+    Sipr_Parameters parm;
+    GetBitContext       gb;
+    int16_t *data = datap;
+    int i;
+
+    ctx->avctx = avctx;
+    if (buf_size < (ctx->m.bits_per_frame>>3)) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Error processing packet: packet size (%d) too small\n",
+               buf_size);
+
+        *data_size = 0;
+        return -1;
+    }
+    if (*data_size < ctx->m.subframe_size * ctx->m.subframe_count * 2) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Error processing packet: output buffer (%d) too small\n",
+               *data_size);
+
+        *data_size = 0;
+        return -1;
+    }
+
+    init_get_bits(&gb, buf, ctx->m.bits_per_frame);
+
+    *data_size = 0;
+    for (i=0; i < ctx->m.frames_per_packet; i++) {
+        int bytes_decoded;
+
+        decode_parameters(&parm, &gb, &ctx->m);
+
+        if (ctx->mode == MODE_16k)
+            bytes_decoded = decod_frame_16k(ctx, &parm, data) * 2;
+        else
+            bytes_decoded = decod_frame_8k5(ctx, &parm, data) * 2;
+        *data_size += bytes_decoded;
+        data += bytes_decoded/2;
+    }
+
+    return (ctx->m.bits_per_frame>>3);
+};
+
+AVCodec sipr_decoder =
+{
+    "sipr",
+    CODEC_TYPE_AUDIO,
+    CODEC_ID_SIPR,
+    sizeof(Sipr_Context),
+    ff_sipr_decoder_init,
+    NULL,
+    NULL,
+    ff_sipr_decode_frame,
+    .long_name = NULL_IF_CONFIG_SMALL("RealAudio sipr"),
+};