Browse code

Avoid duplicating compute_lpc_coefs() function in both the RA288 and AAC decoders.

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

Vitor Sessak authored on 2008/09/04 20:03:14
Showing 4 changed files
... ...
@@ -79,6 +79,7 @@
79 79
 #include "avcodec.h"
80 80
 #include "bitstream.h"
81 81
 #include "dsputil.h"
82
+#include "lpc.h"
82 83
 
83 84
 #include "aac.h"
84 85
 #include "aactab.h"
... ...
@@ -634,7 +635,7 @@ static int decode_tns(AACContext * ac, TemporalNoiseShaping * tns,
634 634
                 tmp2_idx = 2*coef_compress + coef_res;
635 635
 
636 636
                 for (i = 0; i < tns->order[w][filt]; i++)
637
-                    tns->coef[w][filt][i] = tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)];
637
+                    tns->coef[w][filt][i] = -tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)];
638 638
             }
639 639
         }
640 640
     }
... ...
@@ -1124,20 +1125,8 @@ static void apply_tns(float coef[1024], TemporalNoiseShaping * tns, IndividualCh
1124 1124
             if (order == 0)
1125 1125
                 continue;
1126 1126
 
1127
-            /* tns_decode_coef
1128
-             * FIXME: This duplicates the functionality of some double code in lpc.c.
1129
-             */
1130
-            for (m = 0; m < order; m++) {
1131
-                float tmp;
1132
-                lpc[m] = tns->coef[w][filt][m];
1133
-                for (i = 0; i < m/2; i++) {
1134
-                    tmp = lpc[i];
1135
-                    lpc[i]     += lpc[m] * lpc[m-1-i];
1136
-                    lpc[m-1-i] += lpc[m] * tmp;
1137
-                }
1138
-                if(m & 1)
1139
-                    lpc[i]     += lpc[m] * lpc[i];
1140
-            }
1127
+            // tns_decode_coef
1128
+            compute_lpc_coefs(tns->coef[w][filt], order, lpc, 0, 0, 0);
1141 1129
 
1142 1130
             start = ics->swb_offset[FFMIN(bottom, mmm)];
1143 1131
             end   = ics->swb_offset[FFMIN(   top, mmm)];
... ...
@@ -21,45 +21,10 @@
21 21
 
22 22
 #include "libavutil/lls.h"
23 23
 #include "dsputil.h"
24
-#include "lpc.h"
25
-
26
-
27
-/**
28
- * Levinson-Durbin recursion.
29
- * Produces LPC coefficients from autocorrelation data.
30
- */
31
-static void compute_lpc_coefs(const double *autoc, int max_order,
32
-                              double lpc[][MAX_LPC_ORDER], double *ref)
33
-{
34
-    int i, j;
35
-    double err = autoc[0];
36
-    double lpc_tmp[MAX_LPC_ORDER];
37
-
38
-    for(i=0; i<max_order; i++) {
39
-        double r = -autoc[i+1];
40
-
41
-        for(j=0; j<i; j++)
42
-            r -= lpc_tmp[j] * autoc[i-j];
43 24
 
44
-        r /= err;
45
-        ref[i] = fabs(r);
46
-
47
-        err *= 1.0 - (r * r);
48
-
49
-        lpc_tmp[i] = r;
50
-        for(j=0; j < i>>1; j++) {
51
-            double tmp = lpc_tmp[j];
52
-            lpc_tmp[j] += r * lpc_tmp[i-1-j];
53
-            lpc_tmp[i-1-j] += r * tmp;
54
-        }
55
-
56
-        if(i & 1)
57
-            lpc_tmp[j] += lpc_tmp[j] * r;
25
+#define LPC_USE_DOUBLE
26
+#include "lpc.h"
58 27
 
59
-        for(j=0; j<=i; j++)
60
-            lpc[i][j] = -lpc_tmp[j];
61
-    }
62
-}
63 28
 
64 29
 /**
65 30
  * Quantize LPC coefficients
... ...
@@ -106,7 +71,7 @@ static void quantize_lpc_coefs(double *lpc_in, int order, int precision,
106 106
     /* output quantized coefficients and level shift */
107 107
     error=0;
108 108
     for(i=0; i<order; i++) {
109
-        error += lpc_in[i] * (1 << sh);
109
+        error -= lpc_in[i] * (1 << sh);
110 110
         lpc_out[i] = av_clip(lrintf(error), -qmax, qmax);
111 111
         error -= lpc_out[i];
112 112
     }
... ...
@@ -147,7 +112,10 @@ int ff_lpc_calc_coefs(DSPContext *s,
147 147
     if(use_lpc == 1){
148 148
         s->flac_compute_autocorr(samples, blocksize, max_order, autoc);
149 149
 
150
-        compute_lpc_coefs(autoc, max_order, lpc, ref);
150
+        compute_lpc_coefs(autoc, max_order, &lpc[0][0], MAX_LPC_ORDER, 0, 1);
151
+
152
+        for(i=0; i<max_order; i++)
153
+            ref[i] = fabs(lpc[i][i]);
151 154
     }else{
152 155
         LLSModel m[2];
153 156
         double var[MAX_LPC_ORDER+1], weight;
... ...
@@ -179,7 +147,7 @@ int ff_lpc_calc_coefs(DSPContext *s,
179 179
 
180 180
         for(i=0; i<max_order; i++){
181 181
             for(j=0; j<max_order; j++)
182
-                lpc[i][j]= m[(pass-1)&1].coeff[i][j];
182
+                lpc[i][j]=-m[(pass-1)&1].coeff[i][j];
183 183
             ref[i]= sqrt(m[(pass-1)&1].variance[i] / weight) * (blocksize - max_order) / 4000;
184 184
         }
185 185
         for(i=max_order-1; i>0; i--)
... ...
@@ -45,4 +45,58 @@ int ff_lpc_calc_coefs(DSPContext *s,
45 45
                       int32_t coefs[][MAX_LPC_ORDER], int *shift, int use_lpc,
46 46
                       int omethod, int max_shift, int zero_shift);
47 47
 
48
+#ifdef LPC_USE_DOUBLE
49
+#define LPC_type double
50
+#else
51
+#define LPC_type float
52
+#endif
53
+
54
+/**
55
+ * Levinson-Durbin recursion.
56
+ * Produces LPC coefficients from autocorrelation data.
57
+ */
58
+static inline int compute_lpc_coefs(const LPC_type *autoc, int max_order,
59
+                                    LPC_type *lpc, int lpc_stride, int fail,
60
+                                    int normalize)
61
+{
62
+    int i, j;
63
+    LPC_type err;
64
+    LPC_type *lpc_last = lpc;
65
+
66
+    if (normalize)
67
+        err = *autoc++;
68
+
69
+    if (fail && (autoc[max_order - 1] == 0 || err <= 0))
70
+        return -1;
71
+
72
+    for(i=0; i<max_order; i++) {
73
+        LPC_type r = -autoc[i];
74
+
75
+        if (normalize) {
76
+            for(j=0; j<i; j++)
77
+                r -= lpc_last[j] * autoc[i-j-1];
78
+
79
+            r /= err;
80
+            err *= 1.0 - (r * r);
81
+        }
82
+
83
+        lpc[i] = r;
84
+
85
+        for(j=0; j < (i+1)>>1; j++) {
86
+            LPC_type f = lpc_last[    j];
87
+            LPC_type b = lpc_last[i-1-j];
88
+            lpc[    j] = f + r * b;
89
+            lpc[i-1-j] = b + r * f;
90
+        }
91
+
92
+        if (fail && err < 0)
93
+            return -1;
94
+
95
+        lpc_last = lpc;
96
+        lpc += lpc_stride;
97
+    }
98
+
99
+    return 0;
100
+}
101
+
48 102
 #endif /* AVCODEC_LPC_H */
... ...
@@ -23,6 +23,7 @@
23 23
 #define ALT_BITSTREAM_READER_LE
24 24
 #include "bitstream.h"
25 25
 #include "ra288.h"
26
+#include "lpc.h"
26 27
 
27 28
 typedef struct {
28 29
     float sp_lpc[36];      ///< LPC coefficients for speech data (spec: A)
... ...
@@ -113,44 +114,6 @@ static void decode(RA288Context *ractx, float gain, int cb_coef)
113 113
         block[i] = av_clipf(block[i] + buffer[i], -4095, 4095);
114 114
 }
115 115
 
116
-/**
117
- * Converts autocorrelation coefficients to LPC coefficients using the
118
- * Levinson-Durbin algorithm. See blocks 37 and 50 of the G.728 specification.
119
- *
120
- * @return 0 if success, -1 if fail
121
- */
122
-static int eval_lpc_coeffs(const float *in, float *tgt, int n)
123
-{
124
-    int i, j;
125
-    double f0, f1, f2;
126
-
127
-    if (in[n] == 0)
128
-        return -1;
129
-
130
-    if ((f0 = *in) <= 0)
131
-        return -1;
132
-
133
-    in--; // To avoid a -1 subtraction in the inner loop
134
-
135
-    for (i=1; i <= n; i++) {
136
-        f1 = in[i+1];
137
-
138
-        for (j=0; j < i - 1; j++)
139
-            f1 += in[i-j]*tgt[j];
140
-
141
-        tgt[i-1] = f2 = -f1/f0;
142
-        for (j=0; j < i >> 1; j++) {
143
-            float temp = tgt[j] + tgt[i-j-2]*f2;
144
-            tgt[i-j-2] += tgt[j]*f2;
145
-            tgt[j] = temp;
146
-        }
147
-        if ((f0 += f1*f2) < 0)
148
-            return -1;
149
-    }
150
-
151
-    return 0;
152
-}
153
-
154 116
 static void convolve(float *tgt, const float *src, int len, int n)
155 117
 {
156 118
     for (; n >= 0; n--)
... ...
@@ -210,13 +173,13 @@ static void backward_filter(RA288Context *ractx)
210 210
     do_hybrid_window(36, 40, 35, ractx->sp_block+1, temp1, ractx->sp_hist,
211 211
                      ractx->sp_rec, syn_window);
212 212
 
213
-    if (!eval_lpc_coeffs(temp1, ractx->sp_lpc, 36))
213
+    if (!compute_lpc_coefs(temp1, 36, ractx->sp_lpc, 0, 1, 1))
214 214
         colmult(ractx->sp_lpc, ractx->sp_lpc, syn_bw_tab, 36);
215 215
 
216 216
     do_hybrid_window(10, 8, 20, ractx->gain_block+2, temp2, ractx->gain_hist,
217 217
                      ractx->gain_rec, gain_window);
218 218
 
219
-    if (!eval_lpc_coeffs(temp2, ractx->gain_lpc, 10))
219
+    if (!compute_lpc_coefs(temp2, 10, ractx->gain_lpc, 0, 1, 1))
220 220
         colmult(ractx->gain_lpc, ractx->gain_lpc, gain_bw_tab, 10);
221 221
 }
222 222