Commit 6ab6f7ac authored by Renaud Dartus's avatar Renaud Dartus
Browse files

* Follow of the new ac3_decoder ;)

  - New ac3_imdct
  - New ac3_downmix
parent cd74cb2c
......@@ -70,6 +70,8 @@ AC3_DECODER = src/ac3_decoder/ac3_decoder_thread.o \
src/ac3_decoder/ac3_mantissa.o \
src/ac3_decoder/ac3_rematrix.o \
src/ac3_decoder/ac3_imdct.o \
src/ac3_decoder/ac3_imdct_c.o \
src/ac3_decoder/ac3_srfft.o \
src/ac3_decoder/ac3_downmix.o \
src/ac3_decoder/ac3_downmix_c.o
......
......@@ -2,7 +2,7 @@
* ac3_decoder.c: core ac3 decoder
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder.c,v 1.29 2001/04/20 12:14:34 reno Exp $
* $Id: ac3_decoder.c,v 1.30 2001/04/30 21:04:20 reno Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@zoy.org>
......@@ -45,6 +45,10 @@
#include <stdio.h>
void imdct_init (imdct_t * p_imdct);
void downmix_init (downmix_t * p_downmix);
static float cmixlev_lut[4] = { 0.707, 0.595, 0.500, 0.707 };
static float smixlev_lut[4] = { 0.707, 0.500, 0.0 , 0.500 };
int ac3_init (ac3dec_t * p_ac3dec)
{
......@@ -52,6 +56,7 @@ int ac3_init (ac3dec_t * p_ac3dec)
// p_ac3dec->bit_stream.i_available = 0;
p_ac3dec->mantissa.lfsr_state = 1; /* dither_gen initialization */
imdct_init(&p_ac3dec->imdct);
downmix_init(&p_ac3dec->downmix);
return 0;
}
......@@ -67,8 +72,28 @@ int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer)
parse_auxdata (p_ac3dec);
return 1;
}
/* compute downmix parameters
* downmix to tow channels for now */
p_ac3dec->dm_par.clev = 0.0;
p_ac3dec->dm_par.slev = 0.0;
p_ac3dec->dm_par.unit = 1.0;
if (p_ac3dec->bsi.acmod & 0x1) /* have center */
p_ac3dec->dm_par.clev = cmixlev_lut[p_ac3dec->bsi.cmixlev];
if (p_ac3dec->bsi.acmod & 0x4) /* have surround channels */
p_ac3dec->dm_par.slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
p_ac3dec->dm_par.unit /= 1.0 + p_ac3dec->dm_par.clev + p_ac3dec->dm_par.slev;
p_ac3dec->dm_par.clev *= p_ac3dec->dm_par.unit;
p_ac3dec->dm_par.slev *= p_ac3dec->dm_par.unit;
for (i = 0; i < 6; i++) {
/* Initialize freq/time sample storage */
memset(p_ac3dec->samples, 0, sizeof(float) * 256 *
(p_ac3dec->bsi.nfchans + p_ac3dec->bsi.lfeon));
if ((p_ac3dec_t->p_fifo->b_die) && (p_ac3dec_t->p_fifo->b_error))
{
return 1;
......
......@@ -2,7 +2,7 @@
* ac3_decoder.h : ac3 decoder interface
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder.h,v 1.6 2001/04/26 00:12:19 reno Exp $
* $Id: ac3_decoder.h,v 1.7 2001/04/30 21:04:20 reno Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Renaud Dartus <reno@videolan.org>
......@@ -308,6 +308,7 @@ typedef struct audblk_s {
} audblk_t;
/* Everything you wanted to know about band structure */
/*
* The entire frequency domain is represented by 256 real
* floating point fourier coefficients. Only the lower 253
......@@ -326,17 +327,6 @@ typedef struct audblk_s {
* approximate a 1/6 octave scale.
*/
typedef struct stream_coeffs_s
{
float fbw[5][256];
float lfe[256];
} stream_coeffs_t;
typedef struct stream_samples_s
{
float channel[6][256];
} stream_samples_t;
typedef struct bit_allocate_s
{
s16 psd[256];
......@@ -375,6 +365,7 @@ typedef struct imdct_s
/* Delay buffer for time domain interleaving */
float delay[6][256];
float delay1[6][256];
/* Twiddle factors for IMDCT */
float xcos1[N/4];
......@@ -392,8 +383,32 @@ typedef struct imdct_s
complex_t w_32[32];
complex_t w_64[64];
float xcos_sin_sse[128 * 4] __attribute__((aligned(16)));
/* Functions */
void (*fft_64p) (complex_t *a);
void (*imdct_do_512)(struct imdct_s * p_imdct, float data[], float delay[]);
void (*imdct_do_512_nol)(struct imdct_s * p_imdct, float data[], float delay[]);
} imdct_t;
typedef struct dm_par_s {
float unit;
float clev;
float slev;
} dm_par_t;
typedef struct downmix_s {
void (*downmix_3f_2r_to_2ch)(float *samples, dm_par_t * dm_par);
void (*downmix_3f_1r_to_2ch)(float *samples, dm_par_t * dm_par);
void (*downmix_2f_2r_to_2ch)(float *samples, dm_par_t * dm_par);
void (*downmix_2f_1r_to_2ch)(float *samples, dm_par_t * dm_par);
void (*downmix_3f_0r_to_2ch)(float *samples, dm_par_t * dm_par);
void (*stream_sample_2ch_to_s16)(s16 *s16_samples, float *left, float *right);
void (*stream_sample_1ch_to_s16)(s16 *s16_samples, float *center);
} downmix_t;
struct ac3dec_s
{
/*
......@@ -412,10 +427,12 @@ struct ac3dec_s
bsi_t bsi;
audblk_t audblk;
stream_coeffs_t coeffs;
stream_samples_t samples;
float samples[6][256];
dm_par_t dm_par;
bit_allocate_t bit_allocate;
mantissa_t mantissa;
imdct_t imdct;
downmix_t downmix;
};
......@@ -2,7 +2,7 @@
* ac3_decoder_thread.c: ac3 decoder thread
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder_thread.c,v 1.29 2001/04/25 10:22:32 massiot Exp $
* $Id: ac3_decoder_thread.c,v 1.30 2001/04/30 21:04:20 reno Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
*
......@@ -170,13 +170,22 @@ static void RunThread (ac3dec_thread_t * p_ac3dec_t)
{
s16 * buffer;
ac3_sync_info_t sync_info;
int ptr;
if (!sync) {
do {
GetBits(&p_ac3dec_t->ac3_decoder.bit_stream,8);
} while ((!p_ac3dec_t->sync_ptr) && (!p_ac3dec_t->p_fifo->b_die)
&& (!p_ac3dec_t->p_fifo->b_error));
ptr = p_ac3dec_t->sync_ptr;
while(ptr-- && (!p_ac3dec_t->p_fifo->b_die)
&& (!p_ac3dec_t->p_fifo->b_error))
{
p_ac3dec_t->ac3_decoder.bit_stream.p_byte++;
}
/* we are in sync now */
sync = 1;
}
......
......@@ -2,7 +2,7 @@
* ac3_downmix.c: ac3 downmix functions
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_downmix.c,v 1.20 2001/04/20 12:14:34 reno Exp $
* $Id: ac3_downmix.c,v 1.21 2001/04/30 21:04:20 reno Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
......@@ -29,72 +29,36 @@
#include "threads.h"
#include "mtime.h"
#include "tests.h"
#include "stream_control.h"
#include "input_ext-dec.h"
#include "ac3_decoder.h"
#include "ac3_internal.h"
#include "ac3_downmix.h"
/* Pre-scaled downmix coefficients */
static const float cmixlev_lut[4] = { 0.2928, 0.2468, 0.2071, 0.2468 };
static const float smixlev_lut[4] = { 0.2928, 0.2071, 0.0 , 0.2071 };
/* Downmix into _two_ channels...other downmix modes aren't implemented
* to reduce complexity. Realistically, there aren't many machines around
* with > 2 channel output anyways */
int __inline__ downmix (ac3dec_t * p_ac3dec, float * channel, s16 * out_buf)
void downmix_init (downmix_t * p_downmix)
{
dm_par_t dm_par;
dm_par.clev = 0.0;
dm_par.slev = 0.0;
dm_par.unit = 1.0;
if (p_ac3dec->bsi.acmod & 0x1) /* have center */
dm_par.clev = cmixlev_lut[p_ac3dec->bsi.cmixlev];
if (p_ac3dec->bsi.acmod & 0x4) /* have surround channels */
dm_par.slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
dm_par.unit /= 1.0 + dm_par.clev + dm_par.slev;
dm_par.clev *= dm_par.unit;
dm_par.slev *= dm_par.unit;
/*
if (p_ac3dec->bsi.acmod > 7)
intf_ErrMsg( "ac3dec: (downmix) invalid acmod number" );
*/
switch(p_ac3dec->bsi.acmod)
#if 0
if ( TestCPU (CPU_CAPABILITY_MMX) )
{
case 7: // 3/2
downmix_3f_2r_to_2ch_c (channel, &dm_par);
break;
case 6: // 2/2
downmix_2f_2r_to_2ch_c (channel, &dm_par);
break;
case 5: // 3/1
downmix_3f_1r_to_2ch_c (channel, &dm_par);
break;
case 4: // 2/1
downmix_2f_1r_to_2ch_c (channel, &dm_par);
break;
case 3: // 3/0
downmix_3f_0r_to_2ch_c (channel, &dm_par);
break;
case 2:
break;
default: // 1/0
/* FIXME
if (p_ac3dec->bsi.acmod == 1)
center = p_ac3dec->samples.channel[0];
else if (p_ac3dec->bsi.acmod == 0)
center = p_ac3dec->samples.channel[0]; */
return 1;
fprintf(stderr,"Using MMX for downmix\n");
p_downmix->downmix_3f_2r_to_2ch = downmix_3f_2r_to_2ch_kni;
p_downmix->downmix_2f_2r_to_2ch = downmix_2f_2r_to_2ch_kni;
p_downmix->downmix_3f_1r_to_2ch = downmix_3f_1r_to_2ch_kni;
p_downmix->downmix_2f_1r_to_2ch = downmix_2f_1r_to_2ch_kni;
p_downmix->downmix_3f_0r_to_2ch = downmix_3f_0r_to_2ch_kni;
p_downmix->stream_sample_2ch_to_s16 = stream_sample_2ch_to_s16_kni;
p_downmix->stream_sample_1ch_to_s16 = stream_sample_1ch_to_s16_kni;
} else
#endif
{
p_downmix->downmix_3f_2r_to_2ch = downmix_3f_2r_to_2ch_c;
p_downmix->downmix_2f_2r_to_2ch = downmix_2f_2r_to_2ch_c;
p_downmix->downmix_3f_1r_to_2ch = downmix_3f_1r_to_2ch_c;
p_downmix->downmix_2f_1r_to_2ch = downmix_2f_1r_to_2ch_c;
p_downmix->downmix_3f_0r_to_2ch = downmix_3f_0r_to_2ch_c;
p_downmix->stream_sample_2ch_to_s16 = stream_sample_2ch_to_s16_c;
p_downmix->stream_sample_1ch_to_s16 = stream_sample_1ch_to_s16_c;
}
return 0;
}
......@@ -2,7 +2,7 @@
* ac3_downmix.h: ac3 downmix functions
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: ac3_downmix.h,v 1.5 2001/03/21 13:42:34 sam Exp $
* $Id: ac3_downmix.h,v 1.6 2001/04/30 21:04:20 reno Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
*
......@@ -21,18 +21,22 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define NORM 16384
typedef struct dm_par_s {
float unit;
float clev;
float slev;
} dm_par_t;
/* C functions */
void downmix_3f_2r_to_2ch_c(float *samples, dm_par_t * dm_par);
void downmix_3f_1r_to_2ch_c(float *samples, dm_par_t * dm_par);
void downmix_2f_2r_to_2ch_c(float *samples, dm_par_t * dm_par);
void downmix_2f_1r_to_2ch_c(float *samples, dm_par_t * dm_par);
void downmix_3f_0r_to_2ch_c(float *samples, dm_par_t * dm_par);
void stream_sample_2ch_to_s16_c(s16 *s16_samples, float *left, float *right);
void stream_sample_1ch_to_s16_c(s16 *s16_samples, float *center);
void stream_sample_1ch_to_s16_c(s16 *s16_samples, float *center);
#if 0
/* Kni functions */
void downmix_3f_2r_to_2ch_kni(float *samples, dm_par_t * dm_par);
void downmix_3f_1r_to_2ch_kni(float *samples, dm_par_t * dm_par);
void downmix_2f_2r_to_2ch_kni(float *samples, dm_par_t * dm_par);
void downmix_2f_1r_to_2ch_kni(float *samples, dm_par_t * dm_par);
void downmix_3f_0r_to_2ch_kni(float *samples, dm_par_t * dm_par);
void stream_sample_2ch_to_s16_kni(s16 *s16_samples, float *left, float *right);
void stream_sample_1ch_to_s16_kni(s16 *s16_samples, float *center);
#endif
......@@ -2,7 +2,7 @@
* ac3_downmix_c.c: ac3 downmix functions
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_downmix_c.c,v 1.5 2001/04/20 12:14:34 reno Exp $
* $Id: ac3_downmix_c.c,v 1.6 2001/04/30 21:04:20 reno Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
......@@ -36,6 +36,7 @@
#include "ac3_internal.h"
#include "ac3_downmix.h"
void __inline__ downmix_3f_2r_to_2ch_c (float *samples, dm_par_t *dm_par)
{
int i;
......@@ -137,8 +138,8 @@ void __inline__ stream_sample_2ch_to_s16_c (s16 *out_buf, float *left, float *ri
{
int i;
for (i=0; i < 256; i++) {
*out_buf++ = (s16) (*left++ * NORM);
*out_buf++ = (s16) (*right++ * NORM);
*out_buf++ = (s16) (*left++);
*out_buf++ = (s16) (*right++);
}
}
......@@ -149,7 +150,7 @@ void __inline__ stream_sample_1ch_to_s16_c (s16 *out_buf, float *center)
float tmp;
for (i=0; i < 256; i++) {
*out_buf++ = tmp = (s16) (0.7071f * *center++ * NORM);
*out_buf++ = tmp = (s16) (0.7071f * *center++);
*out_buf++ = tmp;
}
}
......@@ -2,7 +2,7 @@
* ac3_imdct.c: ac3 DCT
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_imdct.c,v 1.16 2001/04/26 11:23:16 sam Exp $
* $Id: ac3_imdct.c,v 1.17 2001/04/30 21:04:20 reno Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
......@@ -40,383 +40,235 @@
#include "ac3_internal.h"
#include "ac3_downmix.h"
#include "ac3_imdct_c.h"
#if 0
#include "ac3_imdct_kni.h"
#endif
#include "tests.h"
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
void imdct_do_256(imdct_t * p_imdct, float x[],float y[], int id);
void imdct_do_512(imdct_t * p_imdct, float x[],float y[], int id);
/* 128 point bit-reverse LUT */
static const u8 bit_reverse_512[] = {
0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70,
0x08, 0x48, 0x28, 0x68, 0x18, 0x58, 0x38, 0x78,
0x04, 0x44, 0x24, 0x64, 0x14, 0x54, 0x34, 0x74,
0x0c, 0x4c, 0x2c, 0x6c, 0x1c, 0x5c, 0x3c, 0x7c,
0x02, 0x42, 0x22, 0x62, 0x12, 0x52, 0x32, 0x72,
0x0a, 0x4a, 0x2a, 0x6a, 0x1a, 0x5a, 0x3a, 0x7a,
0x06, 0x46, 0x26, 0x66, 0x16, 0x56, 0x36, 0x76,
0x0e, 0x4e, 0x2e, 0x6e, 0x1e, 0x5e, 0x3e, 0x7e,
0x01, 0x41, 0x21, 0x61, 0x11, 0x51, 0x31, 0x71,
0x09, 0x49, 0x29, 0x69, 0x19, 0x59, 0x39, 0x79,
0x05, 0x45, 0x25, 0x65, 0x15, 0x55, 0x35, 0x75,
0x0d, 0x4d, 0x2d, 0x6d, 0x1d, 0x5d, 0x3d, 0x7d,
0x03, 0x43, 0x23, 0x63, 0x13, 0x53, 0x33, 0x73,
0x0b, 0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, 0x7b,
0x07, 0x47, 0x27, 0x67, 0x17, 0x57, 0x37, 0x77,
0x0f, 0x4f, 0x2f, 0x6f, 0x1f, 0x5f, 0x3f, 0x7f};
static const u8 bit_reverse_256[] = {
0x00, 0x20, 0x10, 0x30, 0x08, 0x28, 0x18, 0x38,
0x04, 0x24, 0x14, 0x34, 0x0c, 0x2c, 0x1c, 0x3c,
0x02, 0x22, 0x12, 0x32, 0x0a, 0x2a, 0x1a, 0x3a,
0x06, 0x26, 0x16, 0x36, 0x0e, 0x2e, 0x1e, 0x3e,
0x01, 0x21, 0x11, 0x31, 0x09, 0x29, 0x19, 0x39,
0x05, 0x25, 0x15, 0x35, 0x0d, 0x2d, 0x1d, 0x3d,
0x03, 0x23, 0x13, 0x33, 0x0b, 0x2b, 0x1b, 0x3b,
0x07, 0x27, 0x17, 0x37, 0x0f, 0x2f, 0x1f, 0x3f};
/* Windowing function for Modified DCT - Thank you acroread */
static float window[] = {
0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130,
0.00157, 0.00187, 0.00220, 0.00256, 0.00297, 0.00341, 0.00390, 0.00443,
0.00501, 0.00564, 0.00632, 0.00706, 0.00785, 0.00871, 0.00962, 0.01061,
0.01166, 0.01279, 0.01399, 0.01526, 0.01662, 0.01806, 0.01959, 0.02121,
0.02292, 0.02472, 0.02662, 0.02863, 0.03073, 0.03294, 0.03527, 0.03770,
0.04025, 0.04292, 0.04571, 0.04862, 0.05165, 0.05481, 0.05810, 0.06153,
0.06508, 0.06878, 0.07261, 0.07658, 0.08069, 0.08495, 0.08935, 0.09389,
0.09859, 0.10343, 0.10842, 0.11356, 0.11885, 0.12429, 0.12988, 0.13563,
0.14152, 0.14757, 0.15376, 0.16011, 0.16661, 0.17325, 0.18005, 0.18699,
0.19407, 0.20130, 0.20867, 0.21618, 0.22382, 0.23161, 0.23952, 0.24757,
0.25574, 0.26404, 0.27246, 0.28100, 0.28965, 0.29841, 0.30729, 0.31626,
0.32533, 0.33450, 0.34376, 0.35311, 0.36253, 0.37204, 0.38161, 0.39126,
0.40096, 0.41072, 0.42054, 0.43040, 0.44030, 0.45023, 0.46020, 0.47019,
0.48020, 0.49022, 0.50025, 0.51028, 0.52031, 0.53033, 0.54033, 0.55031,
0.56026, 0.57019, 0.58007, 0.58991, 0.59970, 0.60944, 0.61912, 0.62873,
0.63827, 0.64774, 0.65713, 0.66643, 0.67564, 0.68476, 0.69377, 0.70269,
0.71150, 0.72019, 0.72877, 0.73723, 0.74557, 0.75378, 0.76186, 0.76981,
0.77762, 0.78530, 0.79283, 0.80022, 0.80747, 0.81457, 0.82151, 0.82831,
0.83496, 0.84145, 0.84779, 0.85398, 0.86001, 0.86588, 0.87160, 0.87716,
0.88257, 0.88782, 0.89291, 0.89785, 0.90264, 0.90728, 0.91176, 0.91610,
0.92028, 0.92432, 0.92822, 0.93197, 0.93558, 0.93906, 0.94240, 0.94560,
0.94867, 0.95162, 0.95444, 0.95713, 0.95971, 0.96217, 0.96451, 0.96674,
0.96887, 0.97089, 0.97281, 0.97463, 0.97635, 0.97799, 0.97953, 0.98099,
0.98236, 0.98366, 0.98488, 0.98602, 0.98710, 0.98811, 0.98905, 0.98994,
0.99076, 0.99153, 0.99225, 0.99291, 0.99353, 0.99411, 0.99464, 0.99513,
0.99558, 0.99600, 0.99639, 0.99674, 0.99706, 0.99736, 0.99763, 0.99788,
0.99811, 0.99831, 0.99850, 0.99867, 0.99882, 0.99895, 0.99908, 0.99919,
0.99929, 0.99938, 0.99946, 0.99953, 0.99959, 0.99965, 0.99969, 0.99974,
0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993,
0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999,
0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000 };
static __inline__ void swap_cmplx(complex_t *a, complex_t *b)
{
complex_t tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
static __inline__ complex_t cmplx_mult(complex_t a, complex_t b)
{
complex_t ret;
ret.real = a.real * b.real - a.imag * b.imag;
ret.imag = a.real * b.imag + a.imag * b.real;
return ret;
}
void imdct_init(imdct_t * p_imdct)
{
int i,k;
complex_t angle_step;
complex_t current_angle;
/* Twiddle factors to turn IFFT into IMDCT */
for (i=0; i < N/4; i++) {
p_imdct->xcos1[i] = -cos(2 * M_PI * (8*i+1)/(8*N)) ;
p_imdct->xsin1[i] = -sin(2 * M_PI * (8*i+1)/(8*N)) ;
}
int i;
float scale = 255.99609372;
/* More twiddle factors to turn IFFT into IMDCT */
for (i=0; i < N/8; i++) {
p_imdct->xcos2[i] = -cos(2 * M_PI * (8*i+1)/(4*N)) ;
p_imdct->xsin2[i] = -sin(2 * M_PI * (8*i+1)/(4*N)) ;
#if 0
if ( TestCPU (CPU_CAPABILITY_MMX) )
{
imdct_init_kni (p_imdct);
} else
#endif
{
imdct_init_c (p_imdct);
}
/* Canonical twiddle factors for FFT */
p_imdct->w[0] = p_imdct->w_1;
p_imdct->w[1] = p_imdct->w_2;
p_imdct->w[2] = p_imdct->w_4;
p_imdct->w[3] = p_imdct->w_8;
p_imdct->w[4] = p_imdct->w_16;
p_imdct->w[5] = p_imdct->w_32;
p_imdct->w[6] = p_imdct->w_64;
for (i = 0; i < 7; i++) {
angle_step.real = cos(-2.0f * M_PI / (1 << (i+1)));
angle_step.imag = sin(-2.0f * M_PI / (1 << (i+1)));
current_angle.real = 1.0f;
current_angle.imag = 0.0f;
for (k = 0; k < 1 << i; k++) {
p_imdct->w[i][k] = current_angle;
current_angle = cmplx_mult(current_angle,angle_step);
}
}
/* More twiddle factors to turn IFFT into IMDCT */
for (i=0; i < 64; i++) {
p_imdct->xcos2[i] = cos(2.0f * M_PI * (8*i+1)/(4*N)) * scale;
p_imdct->xsin2[i] = sin(2.0f * M_PI * (8*i+1)/(4*N)) * scale;
}
}
void imdct (ac3dec_t * p_ac3dec, s16 * buffer)
{
int i, i_stream_done;
int doable = 0;
void (*do_imdct)(imdct_t * p_imdct, float x[],float y[], int id);
/* Test if dm in frequency is doable */
if ( !(doable = p_ac3dec->audblk.blksw[0]) )
do_imdct = imdct_do_512;
else
do_imdct = imdct_do_256;
/* Downmix in the frequency domain if all the channes use the same imdct */
for (i=0; i < p_ac3dec->bsi.nfchans; i++)
int i;
int doable = 0;
float *center=NULL, *left, *right, *left_sur, *right_sur;
float *delay_left, *delay_right;
float *delay1_left, *delay1_right, *delay1_center, *delay1_sr, *delay1_sl;
float right_tmp, left_tmp;
void (*do_imdct)(imdct_t * p_imdct, float data[], float delay[]);
/* test if dm in frequency is doable */
if (!(doable = p_ac3dec->audblk.blksw[0]))
{
if ( doable != p_ac3dec->audblk.blksw[i] )
{
do_imdct = NULL;
break;
}
do_imdct = p_ac3dec->imdct.imdct_do_512;
}
if (do_imdct)
else
{
i_stream_done = downmix(p_ac3dec, p_ac3dec->coeffs.fbw[0], buffer);
do_imdct(&p_ac3dec->imdct,p_ac3dec->coeffs.fbw[0],p_ac3dec->samples.channel[0], 0);
do_imdct(&p_ac3dec->imdct, p_ac3dec->coeffs.fbw[1],p_ac3dec->samples.channel[1], 1);
} else {
for (i=0; i<p_ac3dec->bsi.nfchans;i++) {
if (p_ac3dec->audblk.blksw[i])
imdct_do_256(&p_ac3dec->imdct, p_ac3dec->coeffs.fbw[i],p_ac3dec->samples.channel[i], i);
else
imdct_do_512(&p_ac3dec->imdct, p_ac3dec->coeffs.fbw[i],p_ac3dec->samples.channel[i], i);
}
i_stream_done = downmix(p_ac3dec, p_ac3dec->samples.channel[0], buffer);
do_imdct = imdct_do_256; /* There is only a C function */
}
if ( !i_stream_done ) /* We have to stream sample */
/* downmix in the frequency domain if all the channels
* use the same imdct */
for (i=0; i < p_ac3dec->bsi.nfchans; i++)
{
stream_sample_2ch_to_s16_c(buffer, p_ac3dec->samples.channel[0],
p_ac3dec->samples.channel[1]);