Mercurial > audlegacy
annotate Plugins/Input/aac/libfaad2/tns.c @ 1458:f12d7e208b43 trunk
[svn] Update FSF address in copyright notices. Update autotools templates.
author | chainsaw |
---|---|
date | Wed, 02 Aug 2006 15:44:07 -0700 |
parents | 1e6c0a3f2d15 |
children | 705d4c089fce |
rev | line source |
---|---|
61 | 1 /* |
2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding | |
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
3 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com |
61 | 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 | |
1458
f12d7e208b43
[svn] Update FSF address in copyright notices. Update autotools templates.
chainsaw
parents:
1021
diff
changeset
|
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. |
61 | 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 ** | |
1021 | 25 ** $Id: tns.c,v 1.35 2004/09/04 14:56:29 menno Exp $ |
61 | 26 **/ |
27 | |
28 #include "common.h" | |
29 #include "structs.h" | |
30 | |
31 #include "syntax.h" | |
32 #include "tns.h" | |
33 | |
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
34 |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
35 /* static function declarations */ |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
36 static void tns_decode_coef(uint8_t order, uint8_t coef_res_bits, uint8_t coef_compress, |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
37 uint8_t *coef, real_t *a); |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
38 static void tns_ar_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
39 uint8_t order); |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
40 static void tns_ma_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
41 uint8_t order); |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
42 |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
43 |
61 | 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 { | |
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) | |
54 }; | |
55 static real_t tns_coef_0_4[] = | |
56 { | |
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) | |
61 }; | |
62 static real_t tns_coef_1_3[] = | |
63 { | |
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 { | |
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) | |
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; | |
84 int16_t size; | |
85 uint16_t bottom, top, start, end; | |
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 | |
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]; | |
110 | |
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) | |
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; | |
138 int16_t size; | |
139 uint16_t bottom, top, start, end; | |
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 | |
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]; | |
164 | |
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) | |
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 */ | |
219 b[i] = a[i] + MUL_C(tmp2[m-1], a[m-i]); | |
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; | |
1021 | 242 real_t y; |
243 /* state is stored as a double ringbuffer */ | |
244 real_t state[2*TNS_MAX_ORDER] = {0}; | |
245 int8_t state_index = 0; | |
61 | 246 |
247 for (i = 0; i < size; i++) | |
248 { | |
249 y = *spectrum; | |
250 | |
251 for (j = 0; j < order; j++) | |
1021 | 252 y -= MUL_C(state[state_index+j], lpc[j+1]); |
61 | 253 |
1021 | 254 /* double ringbuffer state */ |
255 state_index--; | |
256 if (state_index < 0) | |
257 state_index = order-1; | |
258 state[state_index] = state[state_index + order] = y; | |
61 | 259 |
260 *spectrum = y; | |
261 spectrum += inc; | |
1021 | 262 |
263 //#define TNS_PRINT | |
264 #ifdef TNS_PRINT | |
265 //printf("%d\n", y); | |
266 printf("0x%.8X\n", y); | |
267 #endif | |
61 | 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; | |
1021 | 285 real_t y; |
286 /* state is stored as a double ringbuffer */ | |
287 real_t state[2*TNS_MAX_ORDER] = {0}; | |
288 int8_t state_index = 0; | |
61 | 289 |
290 for (i = 0; i < size; i++) | |
291 { | |
292 y = *spectrum; | |
293 | |
294 for (j = 0; j < order; j++) | |
295 y += MUL_C(state[j], lpc[j+1]); | |
296 | |
1021 | 297 /* double ringbuffer state */ |
298 state_index--; | |
299 if (state_index < 0) | |
300 state_index = order-1; | |
301 state[state_index] = state[state_index + order] = *spectrum; | |
61 | 302 |
303 *spectrum = y; | |
304 spectrum += inc; | |
305 } | |
306 } |