/proc/self/cwd/libfaad/tns.c
Line | Count | Source |
1 | | /* |
2 | | ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding |
3 | | ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com |
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 | | ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 |
23 | | ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" |
24 | | ** |
25 | | ** Commercial non-GPL licensing of this software is possible. |
26 | | ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. |
27 | | ** |
28 | | ** $Id: tns.c,v 1.40 2007/11/01 12:33:40 menno Exp $ |
29 | | **/ |
30 | | |
31 | | #include "common.h" |
32 | | #include "structs.h" |
33 | | |
34 | | #include "syntax.h" |
35 | | #include "tns.h" |
36 | | |
37 | | |
38 | | /* static function declarations */ |
39 | | /* returns exp */ |
40 | | static uint8_t tns_decode_coef(uint8_t order, uint8_t coef_res_bits, |
41 | | uint8_t coef_compress, uint8_t *coef, real_t *a); |
42 | | static void tns_ar_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, |
43 | | uint8_t order, uint8_t exp); |
44 | | static void tns_ma_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, |
45 | | uint8_t order, uint8_t exp); |
46 | | |
47 | | |
48 | | #ifdef _MSC_VER |
49 | | #pragma warning(disable:4305) |
50 | | #pragma warning(disable:4244) |
51 | | #endif |
52 | | static real_t tns_coef_0_3[] = |
53 | | { |
54 | | COEF_CONST(0.0), COEF_CONST(0.4338837391), COEF_CONST(0.7818314825), COEF_CONST(0.9749279122), |
55 | | COEF_CONST(-0.9848077530), COEF_CONST(-0.8660254038), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433), |
56 | | COEF_CONST(-0.4338837391), COEF_CONST(-0.7818314825), COEF_CONST(-0.9749279122), COEF_CONST(-0.9749279122), |
57 | | COEF_CONST(-0.9848077530), COEF_CONST(-0.8660254038), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433) |
58 | | }; |
59 | | static real_t tns_coef_0_4[] = |
60 | | { |
61 | | COEF_CONST(0.0), COEF_CONST(0.2079116908), COEF_CONST(0.4067366431), COEF_CONST(0.5877852523), |
62 | | COEF_CONST(0.7431448255), COEF_CONST(0.8660254038), COEF_CONST(0.9510565163), COEF_CONST(0.9945218954), |
63 | | COEF_CONST(-0.9957341763), COEF_CONST(-0.9618256432), COEF_CONST(-0.8951632914), COEF_CONST(-0.7980172273), |
64 | | COEF_CONST(-0.6736956436), COEF_CONST(-0.5264321629), COEF_CONST(-0.3612416662), COEF_CONST(-0.1837495178) |
65 | | }; |
66 | | static real_t tns_coef_1_3[] = |
67 | | { |
68 | | COEF_CONST(0.0), COEF_CONST(0.4338837391), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433), |
69 | | COEF_CONST(0.9749279122), COEF_CONST(0.7818314825), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433), |
70 | | COEF_CONST(-0.4338837391), COEF_CONST(-0.7818314825), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433), |
71 | | COEF_CONST(-0.7818314825), COEF_CONST(-0.4338837391), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433) |
72 | | }; |
73 | | static real_t tns_coef_1_4[] = |
74 | | { |
75 | | COEF_CONST(0.0), COEF_CONST(0.2079116908), COEF_CONST(0.4067366431), COEF_CONST(0.5877852523), |
76 | | COEF_CONST(-0.6736956436), COEF_CONST(-0.5264321629), COEF_CONST(-0.3612416662), COEF_CONST(-0.1837495178), |
77 | | COEF_CONST(0.9945218954), COEF_CONST(0.9510565163), COEF_CONST(0.8660254038), COEF_CONST(0.7431448255), |
78 | | COEF_CONST(-0.6736956436), COEF_CONST(-0.5264321629), COEF_CONST(-0.3612416662), COEF_CONST(-0.1837495178) |
79 | | }; |
80 | | |
81 | | static real_t* all_tns_coefs[] = {tns_coef_0_3, tns_coef_0_4, tns_coef_1_3, tns_coef_1_4}; |
82 | | |
83 | | /* TNS decoding for one channel and frame */ |
84 | | void tns_decode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index, |
85 | | uint8_t object_type, real_t *spec, uint16_t frame_len) |
86 | 193k | { |
87 | 193k | uint8_t w, f, tns_order; |
88 | 193k | int8_t inc; |
89 | 193k | int16_t size; |
90 | 193k | uint16_t bottom, top, start, end; |
91 | 193k | uint16_t nshort = frame_len/8; |
92 | 193k | real_t lpc[TNS_MAX_ORDER+1]; |
93 | 193k | uint8_t exp; |
94 | | |
95 | 193k | if (!ics->tns_data_present) |
96 | 185k | return; |
97 | | |
98 | 19.5k | for (w = 0; w < ics->num_windows; w++) |
99 | 11.4k | { |
100 | 11.4k | bottom = ics->num_swb; |
101 | | |
102 | 19.0k | for (f = 0; f < tns->n_filt[w]; f++) |
103 | 7.67k | { |
104 | 7.67k | top = bottom; |
105 | 7.67k | bottom = max(top - tns->length[w][f], 0); |
106 | 7.67k | tns_order = min(tns->order[w][f], TNS_MAX_ORDER); |
107 | 7.67k | if (!tns_order) |
108 | 2.12k | continue; |
109 | | |
110 | 5.55k | exp = tns_decode_coef(tns_order, tns->coef_res[w]+3, |
111 | 5.55k | tns->coef_compress[w][f], tns->coef[w][f], lpc); |
112 | | |
113 | 5.55k | start = min(bottom, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); |
114 | 5.55k | start = min(start, ics->max_sfb); |
115 | 5.55k | start = min(ics->swb_offset[start], ics->swb_offset_max); |
116 | | |
117 | 5.55k | end = min(top, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); |
118 | 5.55k | end = min(end, ics->max_sfb); |
119 | 5.55k | end = min(ics->swb_offset[end], ics->swb_offset_max); |
120 | | |
121 | 5.55k | size = end - start; |
122 | 5.55k | if (size <= 0) |
123 | 4.34k | continue; |
124 | | |
125 | 1.21k | if (tns->direction[w][f]) |
126 | 786 | { |
127 | 786 | inc = -1; |
128 | 786 | start = end - 1; |
129 | 786 | } else { |
130 | 425 | inc = 1; |
131 | 425 | } |
132 | | |
133 | 1.21k | tns_ar_filter(&spec[(w*nshort)+start], size, inc, lpc, tns_order, exp); |
134 | 1.21k | } |
135 | 11.4k | } |
136 | 8.14k | } |
137 | | |
138 | | /* TNS encoding for one channel and frame */ |
139 | | void tns_encode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index, |
140 | | uint8_t object_type, real_t *spec, uint16_t frame_len) |
141 | 5.79k | { |
142 | 5.79k | uint8_t w, f, tns_order; |
143 | 5.79k | int8_t inc; |
144 | 5.79k | int16_t size; |
145 | 5.79k | uint16_t bottom, top, start, end; |
146 | 5.79k | uint16_t nshort = frame_len/8; |
147 | 5.79k | real_t lpc[TNS_MAX_ORDER+1]; |
148 | 5.79k | uint8_t exp; |
149 | | |
150 | 5.79k | if (!ics->tns_data_present) |
151 | 5.00k | return; |
152 | | |
153 | 1.58k | for (w = 0; w < ics->num_windows; w++) |
154 | 790 | { |
155 | 790 | bottom = ics->num_swb; |
156 | | |
157 | 2.86k | for (f = 0; f < tns->n_filt[w]; f++) |
158 | 2.07k | { |
159 | 2.07k | top = bottom; |
160 | 2.07k | bottom = max(top - tns->length[w][f], 0); |
161 | 2.07k | tns_order = min(tns->order[w][f], TNS_MAX_ORDER); |
162 | 2.07k | if (!tns_order) |
163 | 455 | continue; |
164 | | |
165 | 1.61k | exp = tns_decode_coef(tns_order, tns->coef_res[w]+3, |
166 | 1.61k | tns->coef_compress[w][f], tns->coef[w][f], lpc); |
167 | | |
168 | 1.61k | start = min(bottom, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); |
169 | 1.61k | start = min(start, ics->max_sfb); |
170 | 1.61k | start = min(ics->swb_offset[start], ics->swb_offset_max); |
171 | | |
172 | 1.61k | end = min(top, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); |
173 | 1.61k | end = min(end, ics->max_sfb); |
174 | 1.61k | end = min(ics->swb_offset[end], ics->swb_offset_max); |
175 | | |
176 | 1.61k | size = end - start; |
177 | 1.61k | if (size <= 0) |
178 | 1.15k | continue; |
179 | | |
180 | 460 | if (tns->direction[w][f]) |
181 | 259 | { |
182 | 259 | inc = -1; |
183 | 259 | start = end - 1; |
184 | 259 | } else { |
185 | 201 | inc = 1; |
186 | 201 | } |
187 | | |
188 | 460 | tns_ma_filter(&spec[(w*nshort)+start], size, inc, lpc, tns_order, exp); |
189 | 460 | } |
190 | 790 | } |
191 | 790 | } |
192 | | |
193 | | /* Decoder transmitted coefficients for one TNS filter */ |
194 | | static uint8_t tns_decode_coef(uint8_t order, uint8_t coef_res_bits, uint8_t coef_compress, |
195 | | uint8_t *coef, real_t *a) |
196 | 7.16k | { |
197 | 7.16k | uint8_t i, m; |
198 | 7.16k | real_t tmp2[TNS_MAX_ORDER+1], b[TNS_MAX_ORDER+1]; |
199 | 7.16k | uint8_t table_index = 2 * (coef_compress != 0) + (coef_res_bits != 3); |
200 | 7.16k | real_t* tns_coef = all_tns_coefs[table_index]; |
201 | 7.16k | uint8_t exp = 0; |
202 | | |
203 | | /* Conversion to signed integer */ |
204 | 52.4k | for (i = 0; i < order; i++) |
205 | 45.2k | tmp2[i] = tns_coef[coef[i]]; |
206 | | |
207 | | /* Conversion to LPC coefficients */ |
208 | 7.16k | a[0] = COEF_CONST(1.0); |
209 | 52.4k | for (m = 1; m <= order; m++) |
210 | 45.2k | { |
211 | 45.2k | a[m] = tmp2[m-1]; /* changed */ |
212 | 307k | for (i = 1; i < m; i++) /* loop only while i<m */ |
213 | 262k | b[i] = a[i] + MUL_C(a[m], a[m-i]); |
214 | | |
215 | 307k | for (i = 1; i < m; i++) /* loop only while i<m */ |
216 | 262k | a[i] = b[i]; |
217 | | |
218 | 45.2k | #ifdef FIXED_POINT |
219 | 45.2k | a[m] >>= exp; |
220 | | |
221 | | /* OK not to check after the last iteration. */ |
222 | 45.2k | if (m < order) |
223 | 38.1k | { |
224 | 38.1k | real_t sum_abs = COEF_CONST(0.0); |
225 | 300k | for (i = 1; i <= m; ++i) |
226 | 262k | { |
227 | 262k | sum_abs += (a[i] >= 0) ? a[i] : -a[i]; |
228 | 262k | } |
229 | | /* Next iteration would turn sum to 2*sum + 1; maximal "coef" is 7.999 */ |
230 | 38.1k | if (sum_abs >= COEF_CONST(3.5)) |
231 | 5.44k | { |
232 | 5.44k | exp++; |
233 | 61.2k | for (i = 1; i <= m; ++i) |
234 | 55.7k | { |
235 | 55.7k | a[i] >>= 1; |
236 | 55.7k | } |
237 | 5.44k | } |
238 | 38.1k | } |
239 | 45.2k | #endif |
240 | 45.2k | } |
241 | 7.16k | return exp; |
242 | 7.16k | } |
243 | | |
244 | | static void tns_ar_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, |
245 | | uint8_t order, uint8_t exp) |
246 | 1.21k | { |
247 | | /* |
248 | | - Simple all-pole filter of order "order" defined by |
249 | | y(n) = x(n) - lpc[1]*y(n-1) - ... - lpc[order]*y(n-order) |
250 | | - The state variables of the filter are initialized to zero every time |
251 | | - The output data is written over the input data ("in-place operation") |
252 | | - An input vector of "size" samples is processed and the index increment |
253 | | to the next data sample is given by "inc" |
254 | | */ |
255 | | |
256 | 1.21k | uint8_t j; |
257 | 1.21k | uint16_t i; |
258 | | /* state is stored as a double ringbuffer */ |
259 | 1.21k | real_t state[2*TNS_MAX_ORDER] = {0}; |
260 | 1.21k | int8_t state_index = 0; |
261 | 1.21k | int32_t mul = 1; |
262 | | |
263 | 1.21k | #ifdef FIXED_POINT |
264 | 1.21k | if (exp >= 4) |
265 | 296 | return; |
266 | 915 | mul = 1 << exp; |
267 | | #else |
268 | | (void)exp; |
269 | | #endif |
270 | | |
271 | 51.0k | for (i = 0; i < size; i++) |
272 | 50.1k | { |
273 | 50.1k | real_t y = REAL_CONST(0.0); |
274 | 496k | for (j = 0; j < order; j++) |
275 | 445k | y += MUL_C(state[state_index+j], lpc[j+1]); |
276 | 50.1k | y = *spectrum - (y * mul); |
277 | | |
278 | | /* double ringbuffer state */ |
279 | 50.1k | state_index--; |
280 | 50.1k | if (state_index < 0) |
281 | 12.2k | state_index = order-1; |
282 | 50.1k | state[state_index] = state[state_index + order] = y; |
283 | | |
284 | 50.1k | *spectrum = y; |
285 | 50.1k | spectrum += inc; |
286 | | |
287 | | //#define TNS_PRINT |
288 | | #ifdef TNS_PRINT |
289 | | //printf("%d\n", y); |
290 | | printf("0x%.8X\n", y); |
291 | | #endif |
292 | 50.1k | } |
293 | 915 | } |
294 | | |
295 | | static void tns_ma_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, |
296 | | uint8_t order, uint8_t exp) |
297 | 460 | { |
298 | | /* |
299 | | - Simple all-zero filter of order "order" defined by |
300 | | y(n) = x(n) + a(2)*x(n-1) + ... + a(order+1)*x(n-order) |
301 | | - The state variables of the filter are initialized to zero every time |
302 | | - The output data is written over the input data ("in-place operation") |
303 | | - An input vector of "size" samples is processed and the index increment |
304 | | to the next data sample is given by "inc" |
305 | | */ |
306 | | |
307 | 460 | uint8_t j; |
308 | 460 | uint16_t i; |
309 | | /* state is stored as a double ringbuffer */ |
310 | 460 | real_t state[2*TNS_MAX_ORDER] = {0}; |
311 | 460 | int8_t state_index = 0; |
312 | 460 | int32_t mul = 1; |
313 | | |
314 | 460 | #ifdef FIXED_POINT |
315 | 460 | if (exp >= 4) |
316 | 75 | return; |
317 | 385 | mul = 1 << exp; |
318 | | #else |
319 | | (void)exp; |
320 | | #endif |
321 | | |
322 | 10.7k | for (i = 0; i < size; i++) |
323 | 10.4k | { |
324 | 10.4k | real_t y = REAL_CONST(0.0); |
325 | 120k | for (j = 0; j < order; j++) |
326 | 110k | y += MUL_C(state[state_index+j], lpc[j+1]); |
327 | | |
328 | 10.4k | y = *spectrum + (y * mul); |
329 | | |
330 | | /* double ringbuffer state */ |
331 | 10.4k | state_index--; |
332 | 10.4k | if (state_index < 0) |
333 | 3.16k | state_index = order-1; |
334 | 10.4k | state[state_index] = state[state_index + order] = *spectrum; |
335 | | |
336 | 10.4k | *spectrum = y; |
337 | 10.4k | spectrum += inc; |
338 | 10.4k | } |
339 | 385 | } |