2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
3 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
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.
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.
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.
19 ** Any non-GPL usage of this software or parts of this software is strictly
22 ** Commercial non-GPL licensing of this software is possible.
23 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
25 ** $Id: filtbank.c,v 1.41 2004/09/08 09:43:11 gcp Exp $
47 fb_info
*filter_bank_init(uint16_t frame_len
)
49 uint16_t nshort
= frame_len
/8;
51 uint16_t frame_len_ld
= frame_len
/2;
54 fb_info
*fb
= (fb_info
*)faad_malloc(sizeof(fb_info
));
55 memset(fb
, 0, sizeof(fb_info
));
58 fb
->mdct256
= faad_mdct_init(2*nshort
);
59 fb
->mdct2048
= faad_mdct_init(2*frame_len
);
62 fb
->mdct1024
= faad_mdct_init(2*frame_len_ld
);
65 #ifdef ALLOW_SMALL_FRAMELENGTH
66 if (frame_len
== 1024)
69 fb
->long_window
[0] = sine_long_1024
;
70 fb
->short_window
[0] = sine_short_128
;
71 fb
->long_window
[1] = kbd_long_1024
;
72 fb
->short_window
[1] = kbd_short_128
;
74 fb
->ld_window
[0] = sine_mid_512
;
75 fb
->ld_window
[1] = ld_mid_512
;
77 #ifdef ALLOW_SMALL_FRAMELENGTH
78 } else /* (frame_len == 960) */ {
79 fb
->long_window
[0] = sine_long_960
;
80 fb
->short_window
[0] = sine_short_120
;
81 fb
->long_window
[1] = kbd_long_960
;
82 fb
->short_window
[1] = kbd_short_120
;
84 fb
->ld_window
[0] = sine_mid_480
;
85 fb
->ld_window
[1] = ld_mid_480
;
93 void filter_bank_end(fb_info
*fb
)
98 printf("FB: %I64d cycles\n", fb
->cycles
);
101 faad_mdct_end(fb
->mdct256
);
102 faad_mdct_end(fb
->mdct2048
);
104 faad_mdct_end(fb
->mdct1024
);
111 static INLINE
void imdct_long(fb_info
*fb
, real_t
*in_data
, real_t
*out_data
, uint16_t len
)
114 mdct_info
*mdct
= NULL
;
128 faad_imdct(mdct
, in_data
, out_data
);
130 faad_imdct(fb
->mdct2048
, in_data
, out_data
);
136 static INLINE
void mdct(fb_info
*fb
, real_t
*in_data
, real_t
*out_data
, uint16_t len
)
138 mdct_info
*mdct
= NULL
;
158 faad_mdct(mdct
, in_data
, out_data
);
162 void ifilter_bank(fb_info
*fb
, uint8_t window_sequence
, uint8_t window_shape
,
163 uint8_t window_shape_prev
, real_t
*freq_in
,
164 real_t
*time_out
, real_t
*overlap
,
165 uint8_t object_type
, uint16_t frame_len
)
168 ALIGN real_t transf_buf
[2*1024] = {0};
170 const real_t
*window_long
= NULL
;
171 const real_t
*window_long_prev
= NULL
;
172 const real_t
*window_short
= NULL
;
173 const real_t
*window_short_prev
= NULL
;
175 uint16_t nlong
= frame_len
;
176 uint16_t nshort
= frame_len
/8;
177 uint16_t trans
= nshort
/2;
179 uint16_t nflat_ls
= (nlong
-nshort
)/2;
182 int64_t count
= faad_get_ts();
185 /* select windows of current frame and previous frame (Sine or KBD) */
187 if (object_type
== LD
)
189 window_long
= fb
->ld_window
[window_shape
];
190 window_long_prev
= fb
->ld_window
[window_shape_prev
];
193 window_long
= fb
->long_window
[window_shape
];
194 window_long_prev
= fb
->long_window
[window_shape_prev
];
195 window_short
= fb
->short_window
[window_shape
];
196 window_short_prev
= fb
->short_window
[window_shape_prev
];
202 for (i
= 0; i
< 1024; i
++)
204 printf("%d\n", freq_in
[i
]);
209 printf("%d %d\n", window_sequence
, window_shape
);
212 switch (window_sequence
)
214 case ONLY_LONG_SEQUENCE
:
216 imdct_long(fb
, freq_in
, transf_buf
, 2*nlong
);
218 /* add second half output of previous frame to windowed output of current frame */
219 for (i
= 0; i
< nlong
; i
+=4)
221 time_out
[i
] = overlap
[i
] + MUL_F(transf_buf
[i
],window_long_prev
[i
]);
222 time_out
[i
+1] = overlap
[i
+1] + MUL_F(transf_buf
[i
+1],window_long_prev
[i
+1]);
223 time_out
[i
+2] = overlap
[i
+2] + MUL_F(transf_buf
[i
+2],window_long_prev
[i
+2]);
224 time_out
[i
+3] = overlap
[i
+3] + MUL_F(transf_buf
[i
+3],window_long_prev
[i
+3]);
227 /* window the second half and save as overlap for next frame */
228 for (i
= 0; i
< nlong
; i
+=4)
230 overlap
[i
] = MUL_F(transf_buf
[nlong
+i
],window_long
[nlong
-1-i
]);
231 overlap
[i
+1] = MUL_F(transf_buf
[nlong
+i
+1],window_long
[nlong
-2-i
]);
232 overlap
[i
+2] = MUL_F(transf_buf
[nlong
+i
+2],window_long
[nlong
-3-i
]);
233 overlap
[i
+3] = MUL_F(transf_buf
[nlong
+i
+3],window_long
[nlong
-4-i
]);
237 case LONG_START_SEQUENCE
:
239 imdct_long(fb
, freq_in
, transf_buf
, 2*nlong
);
241 /* add second half output of previous frame to windowed output of current frame */
242 for (i
= 0; i
< nlong
; i
+=4)
244 time_out
[i
] = overlap
[i
] + MUL_F(transf_buf
[i
],window_long_prev
[i
]);
245 time_out
[i
+1] = overlap
[i
+1] + MUL_F(transf_buf
[i
+1],window_long_prev
[i
+1]);
246 time_out
[i
+2] = overlap
[i
+2] + MUL_F(transf_buf
[i
+2],window_long_prev
[i
+2]);
247 time_out
[i
+3] = overlap
[i
+3] + MUL_F(transf_buf
[i
+3],window_long_prev
[i
+3]);
250 /* window the second half and save as overlap for next frame */
251 /* construct second half window using padding with 1's and 0's */
252 for (i
= 0; i
< nflat_ls
; i
++)
253 overlap
[i
] = transf_buf
[nlong
+i
];
254 for (i
= 0; i
< nshort
; i
++)
255 overlap
[nflat_ls
+i
] = MUL_F(transf_buf
[nlong
+nflat_ls
+i
],window_short
[nshort
-i
-1]);
256 for (i
= 0; i
< nflat_ls
; i
++)
257 overlap
[nflat_ls
+nshort
+i
] = 0;
260 case EIGHT_SHORT_SEQUENCE
:
261 /* perform iMDCT for each short block */
262 faad_imdct(fb
->mdct256
, freq_in
+0*nshort
, transf_buf
+2*nshort
*0);
263 faad_imdct(fb
->mdct256
, freq_in
+1*nshort
, transf_buf
+2*nshort
*1);
264 faad_imdct(fb
->mdct256
, freq_in
+2*nshort
, transf_buf
+2*nshort
*2);
265 faad_imdct(fb
->mdct256
, freq_in
+3*nshort
, transf_buf
+2*nshort
*3);
266 faad_imdct(fb
->mdct256
, freq_in
+4*nshort
, transf_buf
+2*nshort
*4);
267 faad_imdct(fb
->mdct256
, freq_in
+5*nshort
, transf_buf
+2*nshort
*5);
268 faad_imdct(fb
->mdct256
, freq_in
+6*nshort
, transf_buf
+2*nshort
*6);
269 faad_imdct(fb
->mdct256
, freq_in
+7*nshort
, transf_buf
+2*nshort
*7);
271 /* add second half output of previous frame to windowed output of current frame */
272 for (i
= 0; i
< nflat_ls
; i
++)
273 time_out
[i
] = overlap
[i
];
274 for(i
= 0; i
< nshort
; i
++)
276 time_out
[nflat_ls
+ i
] = overlap
[nflat_ls
+ i
] + MUL_F(transf_buf
[nshort
*0+i
],window_short_prev
[i
]);
277 time_out
[nflat_ls
+1*nshort
+i
] = overlap
[nflat_ls
+nshort
*1+i
] + MUL_F(transf_buf
[nshort
*1+i
],window_short
[nshort
-1-i
]) + MUL_F(transf_buf
[nshort
*2+i
],window_short
[i
]);
278 time_out
[nflat_ls
+2*nshort
+i
] = overlap
[nflat_ls
+nshort
*2+i
] + MUL_F(transf_buf
[nshort
*3+i
],window_short
[nshort
-1-i
]) + MUL_F(transf_buf
[nshort
*4+i
],window_short
[i
]);
279 time_out
[nflat_ls
+3*nshort
+i
] = overlap
[nflat_ls
+nshort
*3+i
] + MUL_F(transf_buf
[nshort
*5+i
],window_short
[nshort
-1-i
]) + MUL_F(transf_buf
[nshort
*6+i
],window_short
[i
]);
281 time_out
[nflat_ls
+4*nshort
+i
] = overlap
[nflat_ls
+nshort
*4+i
] + MUL_F(transf_buf
[nshort
*7+i
],window_short
[nshort
-1-i
]) + MUL_F(transf_buf
[nshort
*8+i
],window_short
[i
]);
284 /* window the second half and save as overlap for next frame */
285 for(i
= 0; i
< nshort
; i
++)
288 overlap
[nflat_ls
+4*nshort
+i
-nlong
] = MUL_F(transf_buf
[nshort
*7+i
],window_short
[nshort
-1-i
]) + MUL_F(transf_buf
[nshort
*8+i
],window_short
[i
]);
289 overlap
[nflat_ls
+5*nshort
+i
-nlong
] = MUL_F(transf_buf
[nshort
*9+i
],window_short
[nshort
-1-i
]) + MUL_F(transf_buf
[nshort
*10+i
],window_short
[i
]);
290 overlap
[nflat_ls
+6*nshort
+i
-nlong
] = MUL_F(transf_buf
[nshort
*11+i
],window_short
[nshort
-1-i
]) + MUL_F(transf_buf
[nshort
*12+i
],window_short
[i
]);
291 overlap
[nflat_ls
+7*nshort
+i
-nlong
] = MUL_F(transf_buf
[nshort
*13+i
],window_short
[nshort
-1-i
]) + MUL_F(transf_buf
[nshort
*14+i
],window_short
[i
]);
292 overlap
[nflat_ls
+8*nshort
+i
-nlong
] = MUL_F(transf_buf
[nshort
*15+i
],window_short
[nshort
-1-i
]);
294 for (i
= 0; i
< nflat_ls
; i
++)
295 overlap
[nflat_ls
+nshort
+i
] = 0;
298 case LONG_STOP_SEQUENCE
:
300 imdct_long(fb
, freq_in
, transf_buf
, 2*nlong
);
302 /* add second half output of previous frame to windowed output of current frame */
303 /* construct first half window using padding with 1's and 0's */
304 for (i
= 0; i
< nflat_ls
; i
++)
305 time_out
[i
] = overlap
[i
];
306 for (i
= 0; i
< nshort
; i
++)
307 time_out
[nflat_ls
+i
] = overlap
[nflat_ls
+i
] + MUL_F(transf_buf
[nflat_ls
+i
],window_short_prev
[i
]);
308 for (i
= 0; i
< nflat_ls
; i
++)
309 time_out
[nflat_ls
+nshort
+i
] = overlap
[nflat_ls
+nshort
+i
] + transf_buf
[nflat_ls
+nshort
+i
];
311 /* window the second half and save as overlap for next frame */
312 for (i
= 0; i
< nlong
; i
++)
313 overlap
[i
] = MUL_F(transf_buf
[nlong
+i
],window_long
[nlong
-1-i
]);
318 for (i
= 0; i
< 1024; i
++)
320 printf("%d\n", time_out
[i
]);
321 //printf("0x%.8X\n", time_out[i]);
327 count
= faad_get_ts() - count
;
334 /* only works for LTP -> no overlapping, no short blocks */
335 void filter_bank_ltp(fb_info
*fb
, uint8_t window_sequence
, uint8_t window_shape
,
336 uint8_t window_shape_prev
, real_t
*in_data
, real_t
*out_mdct
,
337 uint8_t object_type
, uint16_t frame_len
)
340 ALIGN real_t windowed_buf
[2*1024] = {0};
342 const real_t
*window_long
= NULL
;
343 const real_t
*window_long_prev
= NULL
;
344 const real_t
*window_short
= NULL
;
345 const real_t
*window_short_prev
= NULL
;
347 uint16_t nlong
= frame_len
;
348 uint16_t nshort
= frame_len
/8;
349 uint16_t nflat_ls
= (nlong
-nshort
)/2;
351 assert(window_sequence
!= EIGHT_SHORT_SEQUENCE
);
354 if (object_type
== LD
)
356 window_long
= fb
->ld_window
[window_shape
];
357 window_long_prev
= fb
->ld_window
[window_shape_prev
];
360 window_long
= fb
->long_window
[window_shape
];
361 window_long_prev
= fb
->long_window
[window_shape_prev
];
362 window_short
= fb
->short_window
[window_shape
];
363 window_short_prev
= fb
->short_window
[window_shape_prev
];
368 switch(window_sequence
)
370 case ONLY_LONG_SEQUENCE
:
371 for (i
= nlong
-1; i
>= 0; i
--)
373 windowed_buf
[i
] = MUL_F(in_data
[i
], window_long_prev
[i
]);
374 windowed_buf
[i
+nlong
] = MUL_F(in_data
[i
+nlong
], window_long
[nlong
-1-i
]);
376 mdct(fb
, windowed_buf
, out_mdct
, 2*nlong
);
379 case LONG_START_SEQUENCE
:
380 for (i
= 0; i
< nlong
; i
++)
381 windowed_buf
[i
] = MUL_F(in_data
[i
], window_long_prev
[i
]);
382 for (i
= 0; i
< nflat_ls
; i
++)
383 windowed_buf
[i
+nlong
] = in_data
[i
+nlong
];
384 for (i
= 0; i
< nshort
; i
++)
385 windowed_buf
[i
+nlong
+nflat_ls
] = MUL_F(in_data
[i
+nlong
+nflat_ls
], window_short
[nshort
-1-i
]);
386 for (i
= 0; i
< nflat_ls
; i
++)
387 windowed_buf
[i
+nlong
+nflat_ls
+nshort
] = 0;
388 mdct(fb
, windowed_buf
, out_mdct
, 2*nlong
);
391 case LONG_STOP_SEQUENCE
:
392 for (i
= 0; i
< nflat_ls
; i
++)
394 for (i
= 0; i
< nshort
; i
++)
395 windowed_buf
[i
+nflat_ls
] = MUL_F(in_data
[i
+nflat_ls
], window_short_prev
[i
]);
396 for (i
= 0; i
< nflat_ls
; i
++)
397 windowed_buf
[i
+nflat_ls
+nshort
] = in_data
[i
+nflat_ls
+nshort
];
398 for (i
= 0; i
< nlong
; i
++)
399 windowed_buf
[i
+nlong
] = MUL_F(in_data
[i
+nlong
], window_long
[nlong
-1-i
]);
400 mdct(fb
, windowed_buf
, out_mdct
, 2*nlong
);