blob: a0718eb0e5bf2395619f8cb274b19f38888b508f
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 | static void tns_decode_coef(uint8_t order, uint8_t coef_res_bits, uint8_t coef_compress, |
40 | uint8_t *coef, real_t *a); |
41 | static void tns_ar_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, |
42 | uint8_t order); |
43 | static void tns_ma_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, |
44 | uint8_t order); |
45 | |
46 | |
47 | #ifdef _MSC_VER |
48 | #pragma warning(disable:4305) |
49 | #pragma warning(disable:4244) |
50 | #endif |
51 | static real_t tns_coef_0_3[] = { |
52 | COEF_CONST(0.0), COEF_CONST(0.4338837391), COEF_CONST(0.7818314825), COEF_CONST(0.9749279122), |
53 | COEF_CONST(-0.9848077530), COEF_CONST(-0.8660254038), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433), |
54 | COEF_CONST(-0.4338837391), COEF_CONST(-0.7818314825), COEF_CONST(-0.9749279122), COEF_CONST(-0.9749279122), |
55 | COEF_CONST(-0.9848077530), COEF_CONST(-0.8660254038), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433) |
56 | }; |
57 | static real_t tns_coef_0_4[] = { |
58 | COEF_CONST(0.0), COEF_CONST(0.2079116908), COEF_CONST(0.4067366431), COEF_CONST(0.5877852523), |
59 | COEF_CONST(0.7431448255), COEF_CONST(0.8660254038), COEF_CONST(0.9510565163), COEF_CONST(0.9945218954), |
60 | COEF_CONST(-0.9957341763), COEF_CONST(-0.9618256432), COEF_CONST(-0.8951632914), COEF_CONST(-0.7980172273), |
61 | COEF_CONST(-0.6736956436), COEF_CONST(-0.5264321629), COEF_CONST(-0.3612416662), COEF_CONST(-0.1837495178) |
62 | }; |
63 | static real_t tns_coef_1_3[] = { |
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) |
68 | }; |
69 | static real_t tns_coef_1_4[] = { |
70 | COEF_CONST(0.0), COEF_CONST(0.2079116908), COEF_CONST(0.4067366431), COEF_CONST(0.5877852523), |
71 | COEF_CONST(-0.6736956436), COEF_CONST(-0.5264321629), COEF_CONST(-0.3612416662), COEF_CONST(-0.1837495178), |
72 | COEF_CONST(0.9945218954), COEF_CONST(0.9510565163), COEF_CONST(0.8660254038), COEF_CONST(0.7431448255), |
73 | COEF_CONST(-0.6736956436), COEF_CONST(-0.5264321629), COEF_CONST(-0.3612416662), COEF_CONST(-0.1837495178) |
74 | }; |
75 | |
76 | |
77 | /* TNS decoding for one channel and frame */ |
78 | void tns_decode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index, |
79 | uint8_t object_type, real_t *spec, uint16_t frame_len) |
80 | { |
81 | uint8_t w, f, tns_order; |
82 | int8_t inc; |
83 | int16_t size; |
84 | uint16_t bottom, top, start, end; |
85 | uint16_t nshort = frame_len / 8; |
86 | real_t lpc[TNS_MAX_ORDER + 1]; |
87 | |
88 | if (!ics->tns_data_present) { |
89 | return; |
90 | } |
91 | |
92 | for (w = 0; w < ics->num_windows; w++) { |
93 | bottom = ics->num_swb; |
94 | |
95 | for (f = 0; f < tns->n_filt[w]; f++) { |
96 | top = bottom; |
97 | bottom = max(top - tns->length[w][f], 0); |
98 | tns_order = min(tns->order[w][f], TNS_MAX_ORDER); |
99 | if (!tns_order) { |
100 | continue; |
101 | } |
102 | |
103 | tns_decode_coef(tns_order, tns->coef_res[w] + 3, |
104 | tns->coef_compress[w][f], tns->coef[w][f], lpc); |
105 | |
106 | start = min(bottom, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); |
107 | start = min(start, ics->max_sfb); |
108 | start = min(ics->swb_offset[start], ics->swb_offset_max); |
109 | |
110 | end = min(top, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); |
111 | end = min(end, ics->max_sfb); |
112 | end = min(ics->swb_offset[end], ics->swb_offset_max); |
113 | |
114 | size = end - start; |
115 | if (size <= 0) { |
116 | continue; |
117 | } |
118 | |
119 | if (tns->direction[w][f]) { |
120 | inc = -1; |
121 | start = end - 1; |
122 | } else { |
123 | inc = 1; |
124 | } |
125 | |
126 | tns_ar_filter(&spec[(w * nshort) + start], size, inc, lpc, tns_order); |
127 | } |
128 | } |
129 | } |
130 | |
131 | /* TNS encoding for one channel and frame */ |
132 | void tns_encode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index, |
133 | uint8_t object_type, real_t *spec, uint16_t frame_len) |
134 | { |
135 | uint8_t w, f, tns_order; |
136 | int8_t inc; |
137 | int16_t size; |
138 | uint16_t bottom, top, start, end; |
139 | uint16_t nshort = frame_len / 8; |
140 | real_t lpc[TNS_MAX_ORDER + 1]; |
141 | |
142 | if (!ics->tns_data_present) { |
143 | return; |
144 | } |
145 | |
146 | for (w = 0; w < ics->num_windows; w++) { |
147 | bottom = ics->num_swb; |
148 | |
149 | for (f = 0; f < tns->n_filt[w]; f++) { |
150 | top = bottom; |
151 | bottom = max(top - tns->length[w][f], 0); |
152 | tns_order = min(tns->order[w][f], TNS_MAX_ORDER); |
153 | if (!tns_order) { |
154 | continue; |
155 | } |
156 | |
157 | tns_decode_coef(tns_order, tns->coef_res[w] + 3, |
158 | tns->coef_compress[w][f], tns->coef[w][f], lpc); |
159 | |
160 | start = min(bottom, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); |
161 | start = min(start, ics->max_sfb); |
162 | start = min(ics->swb_offset[start], ics->swb_offset_max); |
163 | |
164 | end = min(top, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); |
165 | end = min(end, ics->max_sfb); |
166 | end = min(ics->swb_offset[end], ics->swb_offset_max); |
167 | |
168 | size = end - start; |
169 | if (size <= 0) { |
170 | continue; |
171 | } |
172 | |
173 | if (tns->direction[w][f]) { |
174 | inc = -1; |
175 | start = end - 1; |
176 | } else { |
177 | inc = 1; |
178 | } |
179 | |
180 | tns_ma_filter(&spec[(w * nshort) + start], size, inc, lpc, tns_order); |
181 | } |
182 | } |
183 | } |
184 | |
185 | /* Decoder transmitted coefficients for one TNS filter */ |
186 | static void tns_decode_coef(uint8_t order, uint8_t coef_res_bits, uint8_t coef_compress, |
187 | uint8_t *coef, real_t *a) |
188 | { |
189 | uint8_t i, m; |
190 | real_t tmp2[TNS_MAX_ORDER + 1], b[TNS_MAX_ORDER + 1]; |
191 | |
192 | /* Conversion to signed integer */ |
193 | for (i = 0; i < order; i++) { |
194 | if (coef_compress == 0) { |
195 | if (coef_res_bits == 3) { |
196 | tmp2[i] = tns_coef_0_3[coef[i]]; |
197 | } else { |
198 | tmp2[i] = tns_coef_0_4[coef[i]]; |
199 | } |
200 | } else { |
201 | if (coef_res_bits == 3) { |
202 | tmp2[i] = tns_coef_1_3[coef[i]]; |
203 | } else { |
204 | tmp2[i] = tns_coef_1_4[coef[i]]; |
205 | } |
206 | } |
207 | } |
208 | |
209 | /* Conversion to LPC coefficients */ |
210 | a[0] = COEF_CONST(1.0); |
211 | for (m = 1; m <= order; m++) { |
212 | for (i = 1; i < m; i++) { /* loop only while i<m */ |
213 | b[i] = a[i] + MUL_C(tmp2[m - 1], a[m - i]); |
214 | } |
215 | |
216 | for (i = 1; i < m; i++) { /* loop only while i<m */ |
217 | a[i] = b[i]; |
218 | } |
219 | |
220 | a[m] = tmp2[m - 1]; /* changed */ |
221 | } |
222 | } |
223 | |
224 | static void tns_ar_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, |
225 | uint8_t order) |
226 | { |
227 | /* |
228 | - Simple all-pole filter of order "order" defined by |
229 | y(n) = x(n) - lpc[1]*y(n-1) - ... - lpc[order]*y(n-order) |
230 | - The state variables of the filter are initialized to zero every time |
231 | - The output data is written over the input data ("in-place operation") |
232 | - An input vector of "size" samples is processed and the index increment |
233 | to the next data sample is given by "inc" |
234 | */ |
235 | |
236 | uint8_t j; |
237 | uint16_t i; |
238 | real_t y; |
239 | /* state is stored as a double ringbuffer */ |
240 | real_t state[2 * TNS_MAX_ORDER] = {0}; |
241 | int8_t state_index = 0; |
242 | |
243 | for (i = 0; i < size; i++) { |
244 | y = *spectrum; |
245 | |
246 | for (j = 0; j < order; j++) { |
247 | y -= MUL_C(state[state_index + j], lpc[j + 1]); |
248 | } |
249 | |
250 | /* double ringbuffer state */ |
251 | state_index--; |
252 | if (state_index < 0) { |
253 | state_index = order - 1; |
254 | } |
255 | state[state_index] = state[state_index + order] = y; |
256 | |
257 | *spectrum = y; |
258 | spectrum += inc; |
259 | |
260 | //#define TNS_PRINT |
261 | #ifdef TNS_PRINT |
262 | //printf("%d\n", y); |
263 | printf("0x%.8X\n", y); |
264 | #endif |
265 | } |
266 | } |
267 | |
268 | static void tns_ma_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, |
269 | uint8_t order) |
270 | { |
271 | /* |
272 | - Simple all-zero filter of order "order" defined by |
273 | y(n) = x(n) + a(2)*x(n-1) + ... + a(order+1)*x(n-order) |
274 | - The state variables of the filter are initialized to zero every time |
275 | - The output data is written over the input data ("in-place operation") |
276 | - An input vector of "size" samples is processed and the index increment |
277 | to the next data sample is given by "inc" |
278 | */ |
279 | |
280 | uint8_t j; |
281 | uint16_t i; |
282 | real_t y; |
283 | /* state is stored as a double ringbuffer */ |
284 | real_t state[2 * TNS_MAX_ORDER] = {0}; |
285 | int8_t state_index = 0; |
286 | |
287 | for (i = 0; i < size; i++) { |
288 | y = *spectrum; |
289 | |
290 | for (j = 0; j < order; j++) { |
291 | y += MUL_C(state[state_index + j], lpc[j + 1]); |
292 | } |
293 | |
294 | /* double ringbuffer state */ |
295 | state_index--; |
296 | if (state_index < 0) { |
297 | state_index = order - 1; |
298 | } |
299 | state[state_index] = state[state_index + order] = *spectrum; |
300 | |
301 | *spectrum = y; |
302 | spectrum += inc; |
303 | } |
304 | } |
305 |