diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2002-12-16 18:59:50 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2002-12-16 18:59:50 +0000 |
commit | 94ef6649dd5f4e95337af00dcede2337ea7cfb49 (patch) | |
tree | 07d679ce92b4e4517815abc42394480eebf44904 /src/libfaad/filtbank.c | |
parent | 48f4c5809db11a6df4a5e7285d5e60a2ed924e2a (diff) | |
download | xine-lib-94ef6649dd5f4e95337af00dcede2337ea7cfb49.tar.gz xine-lib-94ef6649dd5f4e95337af00dcede2337ea7cfb49.tar.bz2 |
updated libfaad
CVS patchset: 3560
CVS date: 2002/12/16 18:59:50
Diffstat (limited to 'src/libfaad/filtbank.c')
-rw-r--r-- | src/libfaad/filtbank.c | 369 |
1 files changed, 126 insertions, 243 deletions
diff --git a/src/libfaad/filtbank.c b/src/libfaad/filtbank.c index 8ba293686..24cc03780 100644 --- a/src/libfaad/filtbank.c +++ b/src/libfaad/filtbank.c @@ -16,148 +16,79 @@ ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** -** $Id: filtbank.c,v 1.2 2002/08/09 22:36:36 miguelfreitas Exp $ +** $Id: filtbank.c,v 1.3 2002/12/16 19:00:02 miguelfreitas Exp $ **/ #include "common.h" +#include "structs.h" #include <stdlib.h> +#include <string.h> +#ifdef _WIN32_WCE +#define assert(x) +#else #include <assert.h> +#endif + #include "filtbank.h" +#include "decoder.h" #include "syntax.h" #include "kbd_win.h" +#include "sine_win.h" #include "mdct.h" -void filter_bank_init(fb_info *fb, uint16_t frame_len) +fb_info *filter_bank_init(uint16_t frame_len) { - uint16_t i; uint16_t nshort = frame_len/8; #ifdef LD_DEC uint16_t frame_len_ld = frame_len/2; #endif - /* normal */ - faad_mdct_init(&(fb->mdct256), 2*nshort); - faad_mdct_init(&(fb->mdct2048), 2*frame_len); - - fb->long_window[0] = malloc(frame_len*sizeof(real_t)); - fb->short_window[0] = malloc(nshort*sizeof(real_t)); - fb->long_window[1] = kbd_long; - fb->short_window[1] = kbd_short; - - /* calculate the sine windows */ - for (i = 0; i < frame_len; i++) - fb->long_window[0][i] = (real_t)sin(M_PI / (2.0 * frame_len) * (i + 0.5)); - for (i = 0; i < nshort; i++) - fb->short_window[0][i] = (real_t)sin(M_PI / (2.0 * nshort) * (i + 0.5)); + fb_info *fb = (fb_info*)malloc(sizeof(fb_info)); + memset(fb, 0, sizeof(fb_info)); + /* normal */ + fb->mdct256 = faad_mdct_init(2*nshort); + fb->mdct2048 = faad_mdct_init(2*frame_len); #ifdef LD_DEC /* LD */ - faad_mdct_init(&(fb->mdct1024), frame_len_ld); - - fb->ld_window[0] = malloc(frame_len_ld*sizeof(real_t)); - fb->ld_window[1] = malloc(frame_len_ld*sizeof(real_t)); - - /* calculate the sine windows */ - for (i = 0; i < frame_len_ld; i++) - fb->ld_window[0][i] = (real_t)sin(M_PI / (2.0 * frame_len_ld) * (i + 0.5)); - - /* low overlap window */ - for (i = 0; i < 3*(frame_len_ld>>3); i++) - fb->ld_window[1][i] = 0.0; - for (; i < 5*(frame_len_ld>>3); i++) - fb->ld_window[1][i] = (real_t)sin((i-3*(frame_len_ld>>3)+0.5) * M_PI / (frame_len_ld>>1)); - for (; i < frame_len_ld; i++) - fb->ld_window[1][i] = 1.0; + fb->mdct1024 = faad_mdct_init(2*frame_len_ld); #endif -} - -void filter_bank_end(fb_info *fb) -{ - faad_mdct_end(&(fb->mdct256)); - faad_mdct_end(&(fb->mdct2048)); - - if (fb->long_window[0]) free(fb->long_window[0]); - if (fb->short_window[0]) free(fb->short_window[0]); + if (frame_len == 1024) + { + fb->long_window[0] = sine_long_1024; + fb->short_window[0] = sine_short_128; + fb->long_window[1] = kbd_long_1024; + fb->short_window[1] = kbd_short_128; #ifdef LD_DEC - faad_mdct_end(&(fb->mdct1024)); - - if (fb->ld_window[0]) free(fb->ld_window[0]); - if (fb->ld_window[1]) free(fb->ld_window[1]); + fb->ld_window[0] = sine_mid_512; + fb->ld_window[1] = ld_mid_512; +#endif + } else /* (frame_len == 960) */ { + fb->long_window[0] = sine_long_960; + fb->short_window[0] = sine_short_120; + fb->long_window[1] = kbd_long_960; + fb->short_window[1] = kbd_short_120; +#ifdef LD_DEC + fb->ld_window[0] = sine_mid_480; + fb->ld_window[1] = ld_mid_480; #endif -} - -static INLINE void vcopy(real_t *src, real_t *dest, uint16_t vlen) -{ - int16_t i; - - assert(vlen % 4 == 0); - - for (i = vlen/4-1; i >= 0; --i) - { - *dest++ = *src++; *dest++ = *src++; *dest++ = *src++; *dest++ = *src++; - } -} - -static INLINE void vzero(real_t *dest, uint16_t vlen) -{ - int16_t i; - - assert(vlen % 4 == 0); - - for (i = vlen/4-1; i >= 0; --i) - { - *dest-- = 0; *dest-- = 0; *dest-- = 0; *dest-- = 0; - } -} - -static INLINE void vmult1(real_t *src1, real_t *src2, real_t *dest, uint16_t vlen) -{ - int16_t i; - - assert(vlen % 4 == 0); - - for (i = vlen/4-1; i >= 0 ; --i) - { - *dest++ = MUL(*src1++, *src2++); *dest++ = MUL(*src1++, *src2++); - *dest++ = MUL(*src1++, *src2++); *dest++ = MUL(*src1++, *src2++); } -} -static INLINE void vmult2(real_t *src1, real_t *src2, real_t *dest, uint16_t vlen) -{ - int16_t i; - - assert(vlen % 4 == 0); - - for (i = vlen/4-1; i >= 0 ; --i) - { - *dest++ = MUL(*src1++, *src2--); *dest++ = MUL(*src1++, *src2--); - *dest++ = MUL(*src1++, *src2--); *dest++ = MUL(*src1++, *src2--); - } + return fb; } -static INLINE void vadd(real_t *src1, real_t *src2, real_t *dest, uint16_t vlen) +void filter_bank_end(fb_info *fb) { - int16_t i; - - assert(vlen % 4 == 0); + faad_mdct_end(fb->mdct256); + faad_mdct_end(fb->mdct2048); +#ifdef LD_DEC + faad_mdct_end(fb->mdct1024); +#endif - for (i = vlen/4-1; i >= 0; --i) - { - *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++; - *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++; -/* - *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++; - *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++; - *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++; - *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++; - *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++; - *dest++ = *src1++ + *src2++; *dest++ = *src1++ + *src2++; -*/ - } + if (fb) free(fb); } static INLINE void imdct(fb_info *fb, real_t *in_data, real_t *out_data, uint16_t len) @@ -168,16 +99,16 @@ static INLINE void imdct(fb_info *fb, real_t *in_data, real_t *out_data, uint16_ { case 2048: case 1920: - mdct = &(fb->mdct2048); + mdct = fb->mdct2048; break; case 256: case 240: - mdct = &(fb->mdct256); + mdct = fb->mdct256; break; #ifdef LD_DEC case 1024: case 960: - mdct = &(fb->mdct1024); + mdct = fb->mdct1024; break; #endif } @@ -194,16 +125,16 @@ static INLINE void mdct(fb_info *fb, real_t *in_data, real_t *out_data, uint16_t { case 2048: case 1920: - mdct = &(fb->mdct2048); + mdct = fb->mdct2048; break; case 256: - case 120: - mdct = &(fb->mdct256); + case 240: + mdct = fb->mdct256; break; #ifdef LD_DEC case 1024: case 960: - mdct = &(fb->mdct1024); + mdct = fb->mdct1024; break; #endif } @@ -213,26 +144,24 @@ static INLINE void mdct(fb_info *fb, real_t *in_data, real_t *out_data, uint16_t #endif void ifilter_bank(fb_info *fb, uint8_t window_sequence, uint8_t window_shape, - uint8_t window_shape_prev, real_t *freq_in, real_t *time_buff, + uint8_t window_shape_prev, real_t *freq_in, real_t *time_out, uint8_t object_type, uint16_t frame_len) { - real_t *o_buf, *transf_buf; - real_t *obuf_temp; + int16_t i; + real_t *transf_buf; real_t *window_long; real_t *window_long_prev; real_t *window_short; real_t *window_short_prev; - real_t *window_short_prev_ptr; - real_t *fp; - int8_t win; uint16_t nlong = frame_len; uint16_t nshort = frame_len/8; + uint16_t trans = nshort/2; uint16_t nflat_ls = (nlong-nshort)/2; - transf_buf = malloc(2*nlong*sizeof(real_t)); + transf_buf = (real_t*)malloc(2*nlong*sizeof(real_t)); #ifdef LD_DEC if (object_type == LD) @@ -249,136 +178,96 @@ void ifilter_bank(fb_info *fb, uint8_t window_sequence, uint8_t window_shape, } #endif - /* pointer to previous window function */ - window_short_prev_ptr = window_short_prev; - - vcopy(time_buff, time_out, nlong); - o_buf = time_out; - switch (window_sequence) { case ONLY_LONG_SEQUENCE: - /* inverse transform */ imdct(fb, freq_in, transf_buf, 2*nlong); - - /* window function (previous) on first half of the new data */ - vmult1(transf_buf, window_long_prev, transf_buf, nlong); - - /* overlap and add second half of the old data with first half - of the new data */ - vadd(transf_buf, o_buf, o_buf, nlong); - - /* reversed window function on second half of the new data */ - vmult2(transf_buf+nlong, window_long+nlong-1, o_buf+nlong, nlong); + for (i = nlong-1; i >= 0; i--) + { + time_out[i] = time_out[nlong+i] + MUL_R_C(transf_buf[i],window_long_prev[i]); + time_out[nlong+i] = MUL_R_C(transf_buf[nlong+i],window_long[nlong-1-i]); + } break; case LONG_START_SEQUENCE: - /* inverse transform */ imdct(fb, freq_in, transf_buf, 2*nlong); - - /* window function (previous) on first half of the new data */ - vmult1(transf_buf, window_long_prev, transf_buf, nlong); - - /* overlap and add second half of the old data with first half - of the new data */ - vadd(transf_buf, o_buf, o_buf, nlong); - - /* copy data from nlong upto (3*nlong-nshort)/4; (window function = 1.0) */ - vcopy(transf_buf+nlong, o_buf+nlong, nflat_ls); - - /* reversed window function on part of second half of the new data */ - vmult2(transf_buf+nlong+nflat_ls, window_short+nshort-1, - o_buf+nlong+nflat_ls, nshort); - - /* zero rest of the data; (window function = 0.0) */ - vzero(o_buf+2*nlong-1, nflat_ls); + for (i = 0; i < nlong; i++) + time_out[i] = time_out[nlong+i] + MUL_R_C(transf_buf[i],window_long_prev[i]); + for (i = 0; i < nflat_ls; i++) + time_out[nlong+i] = transf_buf[nlong+i]; + for (i = 0; i < nshort; i++) + time_out[nlong+nflat_ls+i] = MUL_R_C(transf_buf[nlong+nflat_ls+i],window_short[nshort-i-1]); + for (i = 0; i < nflat_ls; i++) + time_out[nlong+nflat_ls+nshort+i] = 0; break; case EIGHT_SHORT_SEQUENCE: - obuf_temp = malloc(2*nlong*sizeof(real_t)); - vzero(obuf_temp+2*nlong-1, 2*nlong); - - fp = obuf_temp; - vcopy(time_buff+nflat_ls, fp, nshort); - - for (win = 8-1; win >= 0; --win) + imdct(fb, freq_in+0*nshort, transf_buf+2*nshort*0, 2*nshort); + imdct(fb, freq_in+1*nshort, transf_buf+2*nshort*1, 2*nshort); + imdct(fb, freq_in+2*nshort, transf_buf+2*nshort*2, 2*nshort); + imdct(fb, freq_in+3*nshort, transf_buf+2*nshort*3, 2*nshort); + imdct(fb, freq_in+4*nshort, transf_buf+2*nshort*4, 2*nshort); + imdct(fb, freq_in+5*nshort, transf_buf+2*nshort*5, 2*nshort); + imdct(fb, freq_in+6*nshort, transf_buf+2*nshort*6, 2*nshort); + imdct(fb, freq_in+7*nshort, transf_buf+2*nshort*7, 2*nshort); + for (i = 0; i < nflat_ls; i++) + time_out[i] = time_out[nlong+i]; + for(i = nshort-1; i >= 0; i--) { - /* inverse transform */ - imdct(fb, freq_in, transf_buf, 2*nshort); - - /* window function (previous) on first half of the new data */ - vmult1(transf_buf, window_short_prev_ptr, transf_buf, nshort); - - /* overlap and add second half of the old data with first half - of the new data */ - vadd(transf_buf, fp, fp, nshort); - - /* reversed window function on second half of the new data */ - vmult2(transf_buf+nshort, window_short+nshort-1, fp+nshort, nshort); - - /* shift to next short block */ - freq_in += nshort; - fp += nshort; - window_short_prev_ptr = window_short; + time_out[nflat_ls+ i] = time_out[nlong+nflat_ls+ i] + MUL_R_C(transf_buf[nshort*0+i],window_short_prev[i]); + time_out[nflat_ls+1*nshort+i] = time_out[nlong+nflat_ls+nshort*1+i] + MUL_R_C(transf_buf[nshort*1+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*2+i],window_short[i]); + time_out[nflat_ls+2*nshort+i] = time_out[nlong+nflat_ls+nshort*2+i] + MUL_R_C(transf_buf[nshort*3+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*4+i],window_short[i]); + time_out[nflat_ls+3*nshort+i] = time_out[nlong+nflat_ls+nshort*3+i] + MUL_R_C(transf_buf[nshort*5+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*6+i],window_short[i]); + if (i < trans) + time_out[nflat_ls+4*nshort+i] = time_out[nlong+nflat_ls+nshort*4+i] + MUL_R_C(transf_buf[nshort*7+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*8+i],window_short[i]); + else + time_out[nflat_ls+4*nshort+i] = MUL_R_C(transf_buf[nshort*7+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*8+i],window_short[i]); + time_out[nflat_ls+5*nshort+i] = MUL_R_C(transf_buf[nshort*9+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*10+i],window_short[i]); + time_out[nflat_ls+6*nshort+i] = MUL_R_C(transf_buf[nshort*11+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*12+i],window_short[i]); + time_out[nflat_ls+7*nshort+i] = MUL_R_C(transf_buf[nshort*13+i],window_short[nshort-1-i]) + MUL_R_C(transf_buf[nshort*14+i],window_short[i]); + time_out[nflat_ls+8*nshort+i] = MUL_R_C(transf_buf[nshort*15+i],window_short[nshort-1-i]); } - - vcopy(obuf_temp, o_buf + nflat_ls, nlong*2-nflat_ls); - vzero(o_buf+2*nlong-1, nflat_ls); - - free(obuf_temp); + for (i = 0; i < nflat_ls; i++) + time_out[nlong+nflat_ls+nshort+i] = 0; break; case LONG_STOP_SEQUENCE: - /* inverse transform */ imdct(fb, freq_in, transf_buf, 2*nlong); - - /* zero first part of first half of the data (window function = 0.0) */ - vzero(transf_buf+nflat_ls-1, nflat_ls); - - /* window function (previous) on part of the first half of - the new data */ - vmult1(transf_buf+nflat_ls, window_short_prev_ptr, - transf_buf+nflat_ls, nshort); - - /* third part of the stop sequence window is window function = 1, - so no need to actually apply that */ - - /* overlap and add second half of the old data with first half - of the new data */ - vadd(transf_buf, o_buf, o_buf, nlong); - - /* reversed window function on second half of the new data */ - vmult2(transf_buf+nlong, window_long+nlong-1, o_buf+nlong, nlong); + for (i = 0; i < nflat_ls; i++) + time_out[i] = time_out[nlong+i]; + for (i = 0; i < nshort; i++) + time_out[nflat_ls+i] = time_out[nlong+nflat_ls+i] + MUL_R_C(transf_buf[nflat_ls+i],window_short_prev[i]); + for (i = 0; i < nflat_ls; i++) + time_out[nflat_ls+nshort+i] = time_out[nlong+nflat_ls+nshort+i] + transf_buf[nflat_ls+nshort+i]; + for (i = 0; i < nlong; i++) + time_out[nlong+i] = MUL_R_C(transf_buf[nlong+i],window_long[nlong-1-i]); break; } - /* save second half of data */ - vcopy(o_buf+nlong, time_buff, nlong); - free(transf_buf); } #ifdef LTP_DEC -/* only works for LTP -> no overlapping */ +/* only works for LTP -> no overlapping, no short blocks */ void filter_bank_ltp(fb_info *fb, uint8_t window_sequence, uint8_t window_shape, uint8_t window_shape_prev, real_t *in_data, real_t *out_mdct, uint8_t object_type, uint16_t frame_len) { - int8_t win; + int16_t i; real_t *windowed_buf; - real_t *p_o_buf; real_t *window_long; real_t *window_long_prev; real_t *window_short; real_t *window_short_prev; - real_t *window_short_prev_ptr; uint16_t nlong = frame_len; uint16_t nshort = frame_len/8; uint16_t nflat_ls = (nlong-nshort)/2; - windowed_buf = malloc(nlong*2*sizeof(real_t)); + assert(window_sequence != EIGHT_SHORT_SEQUENCE); + + windowed_buf = (real_t*)malloc(nlong*2*sizeof(real_t)); #ifdef LD_DEC if (object_type == LD) @@ -395,44 +284,38 @@ void filter_bank_ltp(fb_info *fb, uint8_t window_sequence, uint8_t window_shape, } #endif - window_short_prev_ptr = window_short_prev; - - p_o_buf = in_data; - switch(window_sequence) { case ONLY_LONG_SEQUENCE: - vmult1(p_o_buf, window_long_prev, windowed_buf, nlong); - vmult2(p_o_buf+nlong, window_long+nlong-1, windowed_buf+nlong, nlong); + for (i = nlong-1; i >= 0; i--) + { + windowed_buf[i] = MUL_R_C(in_data[i], window_long_prev[i]); + windowed_buf[i+nlong] = MUL_R_C(in_data[i+nlong], window_long[nlong-1-i]); + } mdct(fb, windowed_buf, out_mdct, 2*nlong); break; case LONG_START_SEQUENCE: - vmult1(p_o_buf, window_long_prev, windowed_buf, nlong); - vcopy(p_o_buf+nlong, windowed_buf+nlong, nflat_ls); - vmult2(p_o_buf+nlong+nflat_ls, window_short+nshort-1, windowed_buf+nlong+nflat_ls, nshort); - vzero(windowed_buf+2*nlong-1, nflat_ls); + for (i = 0; i < nlong; i++) + windowed_buf[i] = MUL_R_C(in_data[i], window_long_prev[i]); + for (i = 0; i < nflat_ls; i++) + windowed_buf[i+nlong] = in_data[i+nlong]; + for (i = 0; i < nshort; i++) + windowed_buf[i+nlong+nflat_ls] = MUL_R_C(in_data[i+nlong+nflat_ls], window_short[nshort-1-i]); + for (i = 0; i < nflat_ls; i++) + windowed_buf[i+nlong+nflat_ls+nshort] = 0; mdct(fb, windowed_buf, out_mdct, 2*nlong); break; - case EIGHT_SHORT_SEQUENCE: - for (win = 8-1; win >= 0; --win) - { - vmult1(p_o_buf, window_short_prev_ptr, windowed_buf, nshort); - vmult2(p_o_buf+nshort, window_short+nshort-1, windowed_buf+nshort, nshort); - mdct(fb, windowed_buf, out_mdct, 2*nshort); - - out_mdct += nshort; - p_o_buf += 2*nshort; - window_short_prev_ptr = window_short; - } - break; - case LONG_STOP_SEQUENCE: - vzero(windowed_buf+nflat_ls-1, nflat_ls); - vmult1(p_o_buf+nflat_ls, window_short_prev_ptr, windowed_buf+nflat_ls, nshort); - vcopy(p_o_buf+nflat_ls+nshort, windowed_buf+nflat_ls+nshort, nflat_ls); - vmult2(p_o_buf+nlong, window_long+nlong-1, windowed_buf+nlong, nlong); + for (i = 0; i < nflat_ls; i++) + windowed_buf[i] = 0; + for (i = 0; i < nshort; i++) + windowed_buf[i+nflat_ls] = MUL_R_C(in_data[i+nflat_ls], window_short_prev[i]); + for (i = 0; i < nflat_ls; i++) + windowed_buf[i+nflat_ls+nshort] = in_data[i+nflat_ls+nshort]; + for (i = 0; i < nlong; i++) + windowed_buf[i+nlong] = MUL_R_C(in_data[i+nlong], window_long[nlong-1-i]); mdct(fb, windowed_buf, out_mdct, 2*nlong); break; } |