summaryrefslogtreecommitdiff
path: root/src/libfaad/filtbank.c
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2002-12-16 18:59:50 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2002-12-16 18:59:50 +0000
commit94ef6649dd5f4e95337af00dcede2337ea7cfb49 (patch)
tree07d679ce92b4e4517815abc42394480eebf44904 /src/libfaad/filtbank.c
parent48f4c5809db11a6df4a5e7285d5e60a2ed924e2a (diff)
downloadxine-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.c369
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;
}