Originally committed as revision 15193 to svn://svn.ffmpeg.org/ffmpeg/trunk
Vitor Sessak authored on 2008/09/04 20:03:14... | ... |
@@ -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 |
|