Mercurial > mplayer.hg
annotate libfaad2/tns.c @ 21221:7124c26f3db3
Add generic target that allow compiling without any assembler or otherwise
architecture specific code (except endiannes of course).
Usage example: ./configure --target=generic-linux
author | reimar |
---|---|
date | Sat, 25 Nov 2006 17:58:33 +0000 |
parents | 59b6fa5b4201 |
children | e83eef58b30a |
rev | line source |
---|---|
10725 | 1 /* |
2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding | |
12527 | 3 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com |
10725 | 4 ** |
5 ** This program is free software; you can redistribute it and/or modify | |
6 ** it under the terms of the GNU General Public License as published by | |
7 ** the Free Software Foundation; either version 2 of the License, or | |
8 ** (at your option) any later version. | |
9 ** | |
10 ** This program is distributed in the hope that it will be useful, | |
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 ** GNU General Public License for more details. | |
14 ** | |
15 ** You should have received a copy of the GNU General Public License | |
16 ** along with this program; if not, write to the Free Software | |
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
18 ** | |
19 ** Any non-GPL usage of this software or parts of this software is strictly | |
20 ** forbidden. | |
21 ** | |
22 ** Commercial non-GPL licensing of this software is possible. | |
23 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. | |
24 ** | |
18141 | 25 ** $Id: tns.c,v 1.35 2004/09/04 14:56:29 menno Exp $ |
10725 | 26 **/ |
27 | |
28 #include "common.h" | |
29 #include "structs.h" | |
30 | |
31 #include "syntax.h" | |
32 #include "tns.h" | |
33 | |
12527 | 34 |
35 /* static function declarations */ | |
36 static void tns_decode_coef(uint8_t order, uint8_t coef_res_bits, uint8_t coef_compress, | |
37 uint8_t *coef, real_t *a); | |
38 static void tns_ar_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, | |
39 uint8_t order); | |
40 static void tns_ma_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, | |
41 uint8_t order); | |
42 | |
43 | |
10725 | 44 #ifdef _MSC_VER |
45 #pragma warning(disable:4305) | |
46 #pragma warning(disable:4244) | |
47 #endif | |
48 static real_t tns_coef_0_3[] = | |
49 { | |
10989 | 50 COEF_CONST(0.0), COEF_CONST(0.4338837391), COEF_CONST(0.7818314825), COEF_CONST(0.9749279122), |
51 COEF_CONST(-0.9848077530), COEF_CONST(-0.8660254038), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433), | |
52 COEF_CONST(-0.4338837391), COEF_CONST(-0.7818314825), COEF_CONST(-0.9749279122), COEF_CONST(-0.9749279122), | |
53 COEF_CONST(-0.9848077530), COEF_CONST(-0.8660254038), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433) | |
10725 | 54 }; |
55 static real_t tns_coef_0_4[] = | |
56 { | |
10989 | 57 COEF_CONST(0.0), COEF_CONST(0.2079116908), COEF_CONST(0.4067366431), COEF_CONST(0.5877852523), |
58 COEF_CONST(0.7431448255), COEF_CONST(0.8660254038), COEF_CONST(0.9510565163), COEF_CONST(0.9945218954), | |
59 COEF_CONST(-0.9957341763), COEF_CONST(-0.9618256432), COEF_CONST(-0.8951632914), COEF_CONST(-0.7980172273), | |
60 COEF_CONST(-0.6736956436), COEF_CONST(-0.5264321629), COEF_CONST(-0.3612416662), COEF_CONST(-0.1837495178) | |
10725 | 61 }; |
62 static real_t tns_coef_1_3[] = | |
63 { | |
10989 | 64 COEF_CONST(0.0), COEF_CONST(0.4338837391), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433), |
65 COEF_CONST(0.9749279122), COEF_CONST(0.7818314825), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433), | |
66 COEF_CONST(-0.4338837391), COEF_CONST(-0.7818314825), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433), | |
67 COEF_CONST(-0.7818314825), COEF_CONST(-0.4338837391), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433) | |
10725 | 68 }; |
69 static real_t tns_coef_1_4[] = | |
70 { | |
10989 | 71 COEF_CONST(0.0), COEF_CONST(0.2079116908), COEF_CONST(0.4067366431), COEF_CONST(0.5877852523), |
72 COEF_CONST(-0.6736956436), COEF_CONST(-0.5264321629), COEF_CONST(-0.3612416662), COEF_CONST(-0.1837495178), | |
73 COEF_CONST(0.9945218954), COEF_CONST(0.9510565163), COEF_CONST(0.8660254038), COEF_CONST(0.7431448255), | |
74 COEF_CONST(-0.6736956436), COEF_CONST(-0.5264321629), COEF_CONST(-0.3612416662), COEF_CONST(-0.1837495178) | |
10725 | 75 }; |
76 | |
77 | |
78 /* TNS decoding for one channel and frame */ | |
79 void tns_decode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index, | |
80 uint8_t object_type, real_t *spec, uint16_t frame_len) | |
81 { | |
82 uint8_t w, f, tns_order; | |
83 int8_t inc; | |
12527 | 84 int16_t size; |
85 uint16_t bottom, top, start, end; | |
10725 | 86 uint16_t nshort = frame_len/8; |
87 real_t lpc[TNS_MAX_ORDER+1]; | |
88 | |
89 if (!ics->tns_data_present) | |
90 return; | |
91 | |
92 for (w = 0; w < ics->num_windows; w++) | |
93 { | |
94 bottom = ics->num_swb; | |
95 | |
96 for (f = 0; f < tns->n_filt[w]; f++) | |
97 { | |
98 top = bottom; | |
99 bottom = max(top - tns->length[w][f], 0); | |
100 tns_order = min(tns->order[w][f], TNS_MAX_ORDER); | |
101 if (!tns_order) | |
102 continue; | |
103 | |
104 tns_decode_coef(tns_order, tns->coef_res[w]+3, | |
105 tns->coef_compress[w][f], tns->coef[w][f], lpc); | |
106 | |
12527 | 107 start = min(bottom, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); |
108 start = min(start, ics->max_sfb); | |
109 start = ics->swb_offset[start]; | |
10725 | 110 |
12527 | 111 end = min(top, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); |
112 end = min(end, ics->max_sfb); | |
113 end = ics->swb_offset[end]; | |
114 | |
115 size = end - start; | |
116 if (size <= 0) | |
10725 | 117 continue; |
118 | |
119 if (tns->direction[w][f]) | |
120 { | |
121 inc = -1; | |
122 start = end - 1; | |
123 } else { | |
124 inc = 1; | |
125 } | |
126 | |
127 tns_ar_filter(&spec[(w*nshort)+start], size, inc, lpc, tns_order); | |
128 } | |
129 } | |
130 } | |
131 | |
132 /* TNS encoding for one channel and frame */ | |
133 void tns_encode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index, | |
134 uint8_t object_type, real_t *spec, uint16_t frame_len) | |
135 { | |
136 uint8_t w, f, tns_order; | |
137 int8_t inc; | |
12527 | 138 int16_t size; |
139 uint16_t bottom, top, start, end; | |
10725 | 140 uint16_t nshort = frame_len/8; |
141 real_t lpc[TNS_MAX_ORDER+1]; | |
142 | |
143 if (!ics->tns_data_present) | |
144 return; | |
145 | |
146 for (w = 0; w < ics->num_windows; w++) | |
147 { | |
148 bottom = ics->num_swb; | |
149 | |
150 for (f = 0; f < tns->n_filt[w]; f++) | |
151 { | |
152 top = bottom; | |
153 bottom = max(top - tns->length[w][f], 0); | |
154 tns_order = min(tns->order[w][f], TNS_MAX_ORDER); | |
155 if (!tns_order) | |
156 continue; | |
157 | |
158 tns_decode_coef(tns_order, tns->coef_res[w]+3, | |
159 tns->coef_compress[w][f], tns->coef[w][f], lpc); | |
160 | |
12527 | 161 start = min(bottom, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); |
162 start = min(start, ics->max_sfb); | |
163 start = ics->swb_offset[start]; | |
10725 | 164 |
12527 | 165 end = min(top, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); |
166 end = min(end, ics->max_sfb); | |
167 end = ics->swb_offset[end]; | |
168 | |
169 size = end - start; | |
170 if (size <= 0) | |
10725 | 171 continue; |
172 | |
173 if (tns->direction[w][f]) | |
174 { | |
175 inc = -1; | |
176 start = end - 1; | |
177 } else { | |
178 inc = 1; | |
179 } | |
180 | |
181 tns_ma_filter(&spec[(w*nshort)+start], size, inc, lpc, tns_order); | |
182 } | |
183 } | |
184 } | |
185 | |
186 /* Decoder transmitted coefficients for one TNS filter */ | |
187 static void tns_decode_coef(uint8_t order, uint8_t coef_res_bits, uint8_t coef_compress, | |
188 uint8_t *coef, real_t *a) | |
189 { | |
190 uint8_t i, m; | |
191 real_t tmp2[TNS_MAX_ORDER+1], b[TNS_MAX_ORDER+1]; | |
192 | |
193 /* Conversion to signed integer */ | |
194 for (i = 0; i < order; i++) | |
195 { | |
196 if (coef_compress == 0) | |
197 { | |
198 if (coef_res_bits == 3) | |
199 { | |
200 tmp2[i] = tns_coef_0_3[coef[i]]; | |
201 } else { | |
202 tmp2[i] = tns_coef_0_4[coef[i]]; | |
203 } | |
204 } else { | |
205 if (coef_res_bits == 3) | |
206 { | |
207 tmp2[i] = tns_coef_1_3[coef[i]]; | |
208 } else { | |
209 tmp2[i] = tns_coef_1_4[coef[i]]; | |
210 } | |
211 } | |
212 } | |
213 | |
214 /* Conversion to LPC coefficients */ | |
215 a[0] = COEF_CONST(1.0); | |
216 for (m = 1; m <= order; m++) | |
217 { | |
218 for (i = 1; i < m; i++) /* loop only while i<m */ | |
12527 | 219 b[i] = a[i] + MUL_C(tmp2[m-1], a[m-i]); |
10725 | 220 |
221 for (i = 1; i < m; i++) /* loop only while i<m */ | |
222 a[i] = b[i]; | |
223 | |
224 a[m] = tmp2[m-1]; /* changed */ | |
225 } | |
226 } | |
227 | |
228 static void tns_ar_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, | |
229 uint8_t order) | |
230 { | |
231 /* | |
232 - Simple all-pole filter of order "order" defined by | |
233 y(n) = x(n) - lpc[1]*y(n-1) - ... - lpc[order]*y(n-order) | |
234 - The state variables of the filter are initialized to zero every time | |
235 - The output data is written over the input data ("in-place operation") | |
236 - An input vector of "size" samples is processed and the index increment | |
237 to the next data sample is given by "inc" | |
238 */ | |
239 | |
240 uint8_t j; | |
241 uint16_t i; | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
242 real_t y; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
243 /* state is stored as a double ringbuffer */ |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
244 real_t state[2*TNS_MAX_ORDER] = {0}; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
245 int8_t state_index = 0; |
10725 | 246 |
247 for (i = 0; i < size; i++) | |
248 { | |
249 y = *spectrum; | |
250 | |
251 for (j = 0; j < order; j++) | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
252 y -= MUL_C(state[state_index+j], lpc[j+1]); |
10725 | 253 |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
254 /* double ringbuffer state */ |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
255 state_index--; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
256 if (state_index < 0) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
257 state_index = order-1; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
258 state[state_index] = state[state_index + order] = y; |
10725 | 259 |
260 *spectrum = y; | |
261 spectrum += inc; | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
262 |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
263 //#define TNS_PRINT |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
264 #ifdef TNS_PRINT |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
265 //printf("%d\n", y); |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
266 printf("0x%.8X\n", y); |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
267 #endif |
10725 | 268 } |
269 } | |
270 | |
271 static void tns_ma_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, | |
272 uint8_t order) | |
273 { | |
274 /* | |
275 - Simple all-zero filter of order "order" defined by | |
276 y(n) = x(n) + a(2)*x(n-1) + ... + a(order+1)*x(n-order) | |
277 - The state variables of the filter are initialized to zero every time | |
278 - The output data is written over the input data ("in-place operation") | |
279 - An input vector of "size" samples is processed and the index increment | |
280 to the next data sample is given by "inc" | |
281 */ | |
282 | |
283 uint8_t j; | |
284 uint16_t i; | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
285 real_t y; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
286 /* state is stored as a double ringbuffer */ |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
287 real_t state[2*TNS_MAX_ORDER] = {0}; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
288 int8_t state_index = 0; |
10725 | 289 |
290 for (i = 0; i < size; i++) | |
291 { | |
292 y = *spectrum; | |
293 | |
294 for (j = 0; j < order; j++) | |
12527 | 295 y += MUL_C(state[j], lpc[j+1]); |
10725 | 296 |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
297 /* double ringbuffer state */ |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
298 state_index--; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
299 if (state_index < 0) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
300 state_index = order-1; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
301 state[state_index] = state[state_index + order] = *spectrum; |
10725 | 302 |
303 *spectrum = y; | |
304 spectrum += inc; | |
305 } | |
306 } |