Commit 501cb1ba authored by Sam Hocevar's avatar Sam Hocevar

  * AC3 IMDCT and downmix functions are now in plugins, --imdct and
    --downmix options added.
parent 32ef13cf
......@@ -13,7 +13,7 @@
#
PLUGINS_DIR := alsa beos darwin dsp dummy \
dvd esd fb ggi glide gnome gtk \
idct \
downmix idct imdct \
macosx mga \
motion \
mpeg null qt sdl \
......@@ -24,7 +24,9 @@ PLUGINS_DIR := alsa beos darwin dsp dummy \
#
PLUGINS_TARGETS := alsa/alsa beos/beos darwin/darwin dsp/dsp dummy/dummy \
dvd/dvd esd/esd fb/fb ggi/ggi glide/glide gnome/gnome gtk/gtk \
downmix/downmix downmix/downmixsse downmix/downmix3dn \
idct/idct idct/idctclassic idct/idctmmx idct/idctmmxext \
imdct/imdct imdct/imdctsse \
macosx/macosx mga/mga \
motion/motion motion/motionmmx motion/motionmmxext \
mpeg/es mpeg/ps mpeg/ts null/null qt/qt sdl/sdl \
......@@ -69,11 +71,7 @@ AC3_DECODER = src/ac3_decoder/ac3_decoder_thread.o \
src/ac3_decoder/ac3_bit_allocate.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
src/ac3_decoder/ac3_imdct.o
AC3_SPDIF = src/ac3_spdif/ac3_spdif.o \
src/ac3_spdif/ac3_iec958.o
......
......@@ -3162,7 +3162,7 @@ fi
ARCH=${host_cpu}
BUILTINS="${BUILTINS} es ps ts yuv idct idctclassic motion"
BUILTINS="${BUILTINS} es ps ts yuv idct idctclassic motion imdct downmix"
case x$host_os in
xmingw32msvc)
......@@ -3195,8 +3195,8 @@ else
fi
rm -f conftest*
echo $ac_n "checking if \$CC groks MMX EXT (SSE) inline assembly""... $ac_c" 1>&6
echo "configure:3200: checking if \$CC groks MMX EXT (SSE) inline assembly" >&5
echo $ac_n "checking if \$CC groks MMX EXT or SSE inline assembly""... $ac_c" 1>&6
echo "configure:3200: checking if \$CC groks MMX EXT or SSE inline assembly" >&5
cat > conftest.$ac_ext <<EOF
#line 3202 "configure"
#include "confdefs.h"
......@@ -3207,7 +3207,7 @@ int main() {
EOF
if { (eval echo configure:3209: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ACCEL_PLUGINS="${ACCEL_PLUGINS} idctmmxext motionmmxext"
ACCEL_PLUGINS="${ACCEL_PLUGINS} idctmmxext motionmmxext imdctsse downmix3dn downmixsse"
echo "$ac_t""yes" 1>&6
else
echo "configure: failed program was:" >&5
......
......@@ -135,7 +135,7 @@ ARCH=${host_cpu}
dnl
dnl default modules
dnl
BUILTINS="${BUILTINS} es ps ts yuv idct idctclassic motion"
BUILTINS="${BUILTINS} es ps ts yuv idct idctclassic motion imdct downmix"
dnl
dnl Accelerated modules
......@@ -154,9 +154,9 @@ AC_TRY_COMPILE([void quux(){void *p;asm("packuswb %%mm1,%%mm2"::"r"(p));}],,
ACCEL_PLUGINS="${ACCEL_PLUGINS} ${MMX_PLUGINS}"
AC_MSG_RESULT(yes), AC_MSG_RESULT(no))
AC_MSG_CHECKING([if \$CC groks MMX EXT (SSE) inline assembly])
AC_MSG_CHECKING([if \$CC groks MMX EXT or SSE inline assembly])
AC_TRY_COMPILE([void quux(){void *p;asm("maskmovq %%mm1,%%mm2"::"r"(p));}],,
ACCEL_PLUGINS="${ACCEL_PLUGINS} idctmmxext motionmmxext"
ACCEL_PLUGINS="${ACCEL_PLUGINS} idctmmxext motionmmxext imdctsse downmix3dn downmixsse"
AC_MSG_RESULT(yes), AC_MSG_RESULT(no))
dnl
......
......@@ -52,6 +52,12 @@ Choose stereo or mono audio output.
.B \-\-spdif
Activate hardware AC3 pass-through mode.
.TP
.B \-\-downmix <module>
Specify a module for AC3 downmix: "downmix", "downmixsse", for instance.
.TP
.B \-\-imdct <module>
Specify a module for AC3 IMDCT: "imdct", "imdctsse", for instance.
.TP
.B \-\-novideo
Disable video output.
.TP
......@@ -145,11 +151,13 @@ also accepts a lot of parameters to customize its behaviour.
vlc_channels=<filename> channels list
.TP
.B Audio parameters:
vlc_aout=<method name> audio method
vlc_dsp=<filename> dsp device path
vlc_stereo={1|0} stereo or mono output
vlc_spdif={1|0} AC3 pass-through mode
vlc_audio_rate=<rate> output rate
vlc_aout=<method name> audio method
vlc_dsp=<filename> dsp device path
vlc_stereo={1|0} stereo or mono output
vlc_spdif={1|0} AC3 pass-through mode
vlc_downmix=<method name> AC3 downmix method
vlc_imdct=<method name> AC3 IMDCT method
vlc_audio_rate=<rate> output rate
.TP
.B Video parameters:
vlc_vout=<method name> display method
......@@ -160,6 +168,7 @@ also accepts a lot of parameters to customize its behaviour.
vlc_grayscale={1|0} grayscale or color
vlc_fullscreen={1|0} full screen
vlc_overlay={1|0} overlay
vlc_motion=<method name> motion compensation method
vlc_idct=<method name> IDCT method
vlc_yuv=<method name> YUV method
vlc_synchro={I|I+|IP|IP+|IPB} synchro algorithm
......
/*****************************************************************************
* ac3_downmix.h : AC3 downmix types
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_downmix.h,v 1.3 2001/05/15 16:19:42 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Renaud Dartus <reno@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
typedef struct dm_par_s {
float unit;
float clev;
float slev;
} dm_par_t;
typedef struct downmix_s {
/* Module used and shortcuts */
struct module_s * p_module;
void (*pf_downmix_3f_2r_to_2ch)(float *, dm_par_t * dm_par);
void (*pf_downmix_3f_1r_to_2ch)(float *, dm_par_t * dm_par);
void (*pf_downmix_2f_2r_to_2ch)(float *, dm_par_t * dm_par);
void (*pf_downmix_2f_1r_to_2ch)(float *, dm_par_t * dm_par);
void (*pf_downmix_3f_0r_to_2ch)(float *, dm_par_t * dm_par);
void (*pf_stream_sample_2ch_to_s16)(s16 *, float *left, float *right);
void (*pf_stream_sample_1ch_to_s16)(s16 *, float *center);
} downmix_t;
/*****************************************************************************
* ac3_downmix.c: ac3 downmix functions
* ac3_imdct.h : AC3 IMDCT types
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_downmix.c,v 1.23 2001/05/14 15:58:03 reno Exp $
* $Id: ac3_imdct.h,v 1.3 2001/05/15 16:19:42 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
* Renaud Dartus <reno@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
......@@ -22,58 +21,48 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include "defs.h"
#include <string.h> /* memcpy() */
typedef struct complex_s {
float real;
float imag;
} complex_t;
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#define N 512
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#include "tests.h"
typedef struct imdct_s
{
complex_t buf[N/4];
#include "stream_control.h"
#include "input_ext-dec.h"
/* Delay buffer for time domain interleaving */
float delay[6][256];
float delay1[6][256];
#include "ac3_decoder.h"
#include "ac3_downmix.h"
/* Twiddle factors for IMDCT */
float xcos1[N/4];
float xsin1[N/4];
float xcos2[N/8];
float xsin2[N/8];
/* Twiddle factor LUT */
complex_t *w[7];
complex_t w_1[1];
complex_t w_2[2];
complex_t w_4[4];
complex_t w_8[8];
complex_t w_16[16];
complex_t w_32[32];
complex_t w_64[64];
float xcos_sin_sse[128 * 4] __attribute__((aligned(16)));
/* Module used and shortcuts */
struct module_s * p_module;
void (*pf_imdct_init) (struct imdct_s *);
//void (*pf_fft_64p) (complex_t *a);
void (*pf_imdct_256)(struct imdct_s *, float data[], float delay[]);
void (*pf_imdct_256_nol)(struct imdct_s *, float data[], float delay[]);
void (*pf_imdct_512)(struct imdct_s *, float data[], float delay[]);
void (*pf_imdct_512_nol)(struct imdct_s *, float data[], float delay[]);
} imdct_t;
void downmix_init (downmix_t * p_downmix)
{
#if 0
if ( TestCPU (CPU_CAPABILITY_SSE) )
{
intf_WarnMsg (1,"ac3dec: using MMX_SSE for downmix");
p_downmix->downmix_3f_2r_to_2ch = downmix_3f_2r_to_2ch_sse;
p_downmix->downmix_2f_2r_to_2ch = downmix_2f_2r_to_2ch_sse;
p_downmix->downmix_3f_1r_to_2ch = downmix_3f_1r_to_2ch_sse;
p_downmix->downmix_2f_1r_to_2ch = downmix_2f_1r_to_2ch_sse;
p_downmix->downmix_3f_0r_to_2ch = downmix_3f_0r_to_2ch_sse;
p_downmix->stream_sample_2ch_to_s16 = stream_sample_2ch_to_s16_sse;
p_downmix->stream_sample_1ch_to_s16 = stream_sample_1ch_to_s16_sse;
}
else if ( TestCPU (CPU_CAPABILITY_3DNOW) )
{
intf_WarnMsg (1,"ac3dec: using MMX_3DNOW for downmix");
p_downmix->downmix_3f_2r_to_2ch = downmix_3f_2r_to_2ch_3dn;
p_downmix->downmix_2f_2r_to_2ch = downmix_2f_2r_to_2ch_3dn;
p_downmix->downmix_3f_1r_to_2ch = downmix_3f_1r_to_2ch_3dn;
p_downmix->downmix_2f_1r_to_2ch = downmix_2f_1r_to_2ch_3dn;
p_downmix->downmix_3f_0r_to_2ch = downmix_3f_0r_to_2ch_3dn;
p_downmix->stream_sample_2ch_to_s16 = stream_sample_2ch_to_s16_3dn;
p_downmix->stream_sample_1ch_to_s16 = stream_sample_1ch_to_s16_3dn;
}
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;
}
}
......@@ -264,6 +264,12 @@
#define AOUT_SPDIF_VAR "vlc_spdif"
#define AOUT_SPDIF_DEFAULT 0
/* Environment variable containing the AC3 downmix method */
#define DOWNMIX_METHOD_VAR "vlc_downmix"
/* Environment variable containing the AC3 IMDCT method */
#define IMDCT_METHOD_VAR "vlc_imdct"
/* Volume */
#define VOLUME_DEFAULT 512
#define VOLUME_STEP 128
......
......@@ -2,7 +2,7 @@
* modules.h : Module management functions.
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: modules.h,v 1.23 2001/05/06 04:32:02 sam Exp $
* $Id: modules.h,v 1.24 2001/05/15 16:19:42 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -65,16 +65,19 @@ typedef void * module_handle_t;
#define MODULE_CAPABILITY_DECAPS 1 << 3 /* Decaps */
#define MODULE_CAPABILITY_ADEC 1 << 4 /* Audio decoder */
#define MODULE_CAPABILITY_VDEC 1 << 5 /* Video decoder */
#define MODULE_CAPABILITY_MOTION 1 << 6 /* Video decoder */
#define MODULE_CAPABILITY_MOTION 1 << 6 /* Motion compensation */
#define MODULE_CAPABILITY_IDCT 1 << 7 /* IDCT transformation */
#define MODULE_CAPABILITY_AOUT 1 << 8 /* Audio output */
#define MODULE_CAPABILITY_VOUT 1 << 9 /* Video output */
#define MODULE_CAPABILITY_YUV 1 << 10 /* YUV colorspace conversion */
#define MODULE_CAPABILITY_AFX 1 << 11 /* Audio effects */
#define MODULE_CAPABILITY_VFX 1 << 12 /* Video effects */
#define MODULE_CAPABILITY_IMDCT 1 << 11 /* IMDCT transformation */
#define MODULE_CAPABILITY_DOWNMIX 1 << 12 /* AC3 downmix */
/* FIXME: kludge */
struct input_area_s;
struct imdct_s;
struct complex_s;
struct dm_par_s;
/* FIXME: not yet used */
typedef struct probedata_s
......@@ -190,6 +193,35 @@ typedef struct function_list_s
void ( * pf_end ) ( struct vout_thread_s * );
} yuv;
/* IMDCT plugin */
struct
{
void ( * pf_imdct_init ) ( struct imdct_s * );
void ( * pf_imdct_256 ) ( struct imdct_s *,
float data[], float delay[] );
void ( * pf_imdct_256_nol )( struct imdct_s *,
float data[], float delay[] );
void ( * pf_imdct_512 ) ( struct imdct_s *,
float data[], float delay[] );
void ( * pf_imdct_512_nol )( struct imdct_s *,
float data[], float delay[] );
// void ( * pf_fft_64p ) ( struct complex_s * );
} imdct;
/* AC3 downmix plugin */
struct
{
void ( * pf_downmix_3f_2r_to_2ch ) ( float *, struct dm_par_s * );
void ( * pf_downmix_3f_1r_to_2ch ) ( float *, struct dm_par_s * );
void ( * pf_downmix_2f_2r_to_2ch ) ( float *, struct dm_par_s * );
void ( * pf_downmix_2f_1r_to_2ch ) ( float *, struct dm_par_s * );
void ( * pf_downmix_3f_0r_to_2ch ) ( float *, struct dm_par_s * );
void ( * pf_stream_sample_2ch_to_s16 ) ( s16 *, float *, float * );
void ( * pf_stream_sample_1ch_to_s16 ) ( s16 *, float * );
} downmix;
} functions;
} function_list_t;
......@@ -208,8 +240,8 @@ typedef struct module_functions_s
function_list_t aout;
function_list_t vout;
function_list_t yuv;
function_list_t afx;
function_list_t vfx;
function_list_t imdct;
function_list_t downmix;
} module_functions_t;
......
###############################################################################
# vlc (VideoLAN Client) downmix module makefile
# (c)2001 VideoLAN
###############################################################################
#
# Objects
#
PLUGIN_DOWNMIX = downmix.o ac3_downmix_c.o
PLUGIN_DOWNMIXSSE = downmixsse.o ac3_downmix_sse.o
PLUGIN_DOWNMIX3DN = downmix3dn.o ac3_downmix_3dn.o
BUILTIN_DOWNMIX = $(PLUGIN_DOWNMIX:%.o=BUILTIN_DOWNMIX_%.o)
BUILTIN_DOWNMIXSSE = $(PLUGIN_DOWNMIXSSE:%.o=BUILTIN_DOWNMIXSSE_%.o)
BUILTIN_DOWNMIX3DN = $(PLUGIN_DOWNMIX3DN:%.o=BUILTIN_DOWNMIX3DN_%.o)
PLUGIN_C = $(PLUGIN_DOWNMIX) $(PLUGIN_DOWNMIXSSE) $(PLUGIN_DOWNMIX3DN)
ALL_OBJ = $(PLUGIN_C) $(BUILTIN_DOWNMIX) $(BUILTIN_DOWNMIXSSE) $(BUILTIN_DOWNMIX3DN)
#
# Virtual targets
#
include ../../Makefile.modules
$(BUILTIN_DOWNMIX): BUILTIN_DOWNMIX_%.o: .dep/%.d
$(BUILTIN_DOWNMIX): BUILTIN_DOWNMIX_%.o: %.c
$(CC) $(CFLAGS) -DBUILTIN -DMODULE_NAME=downmix -c -o $@ $<
$(BUILTIN_DOWNMIXSSE): BUILTIN_DOWNMIXSSE_%.o: .dep/%.d
$(BUILTIN_DOWNMIXSSE): BUILTIN_DOWNMIXSSE_%.o: %.c
$(CC) $(CFLAGS) -DBUILTIN -DMODULE_NAME=downmixsse -c -o $@ $<
$(BUILTIN_DOWNMIX3DN): BUILTIN_DOWNMIX3DN_%.o: .dep/%.d
$(BUILTIN_DOWNMIX3DN): BUILTIN_DOWNMIX3DN_%.o: %.c
$(CC) $(CFLAGS) -DBUILTIN -DMODULE_NAME=downmix3dn -c -o $@ $<
#
# Real targets
#
../../lib/downmix.so: $(PLUGIN_DOWNMIX)
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS)
../../lib/downmix.a: $(BUILTIN_DOWNMIX)
ar r $@ $^
$(RANLIB) $@
../../lib/downmixsse.so: $(PLUGIN_DOWNMIXSSE)
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS)
../../lib/downmixsse.a: $(BUILTIN_DOWNMIXSSE)
ar r $@ $^
$(RANLIB) $@
../../lib/downmix3dn.so: $(PLUGIN_DOWNMIX3DN)
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS)
../../lib/downmix3dn.a: $(BUILTIN_DOWNMIX3DN)
ar r $@ $^
$(RANLIB) $@
/*****************************************************************************
* ac3_downmix_3dn.c: accelerated 3D Now! ac3 downmix functions
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_downmix_3dn.c,v 1.1 2001/05/15 16:19:42 sam Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define MODULE_NAME downmix3dn
#include "modules_inner.h"
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "tests.h"
#include "ac3_downmix.h"
void sqrt2_3dn (void)
{
__asm__ (".float 0f0.7071068");
}
void _M( downmix_3f_2r_to_2ch ) (float * samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $128, %%ecx\n" /* loop counter */
"movd (%%ebx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 4(%%ebx), %%mm6\n" /* clev */
"punpckldq %%mm6, %%mm6\n" /* clev | clev */
"movd 8(%%ebx), %%mm7\n" /* slev */
"punpckldq %%mm7, %%mm7\n" /* slev | slev */
".loop:\n"
"movq (%%eax), %%mm0\n" /* left */
"movq 2048(%%eax), %%mm1\n" /* right */
"movq 1024(%%eax), %%mm2\n" /* center */
"movq 3072(%%eax), %%mm3\n" /* leftsur */
"movq 4096(%%eax), %%mm4\n" /* rightsur */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm6, %%mm2\n"
"pfadd %%mm2, %%mm0\n"
"pfadd %%mm2, %%mm1\n"
"pfmul %%mm7, %%mm3\n"
"pfmul %%mm7, %%mm4\n"
"pfadd %%mm3, %%mm0\n"
"pfadd %%mm4, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ecx\n"
"jnz .loop\n"
"popl %%ecx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void _M( downmix_2f_2r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $128, %%ecx\n" /* loop counter */
"movd (%%ebx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 8(%%ebx), %%mm7\n" /* slev */
"punpckldq %%mm7, %%mm7\n" /* slev | slev */
".loop3:\n"
"movq (%%eax), %%mm0\n" /* left */
"movq 1024(%%eax), %%mm1\n" /* right */
"movq 2048(%%eax), %%mm3\n" /* leftsur */
"movq 3072(%%eax), %%mm4\n" /* rightsur */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm7, %%mm3\n"
"pfmul %%mm7, %%mm4\n"
"pfadd %%mm3, %%mm0\n"
"pfadd %%mm4, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ecx\n"
"jnz .loop3\n"
"popl %%ecx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void _M( downmix_3f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $128, %%ecx\n" /* loop counter */
"movd (%%ebx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 4(%%ebx), %%mm6\n" /* clev */
"punpckldq %%mm6, %%mm6\n" /* clev | clev */
"movd 8(%%ebx), %%mm7\n" /* slev */
"punpckldq %%mm7, %%mm7\n" /* slev | slev */
".loop4:\n"
"movq (%%eax), %%mm0\n" /* left */
"movq 2048(%%eax), %%mm1\n" /* right */
"movq 1024(%%eax), %%mm2\n" /* center */
"movq 3072(%%eax), %%mm3\n" /* sur */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm6, %%mm2\n"
"pfadd %%mm2, %%mm0\n"
"pfmul %%mm7, %%mm3\n"
"pfadd %%mm2, %%mm1\n"
"pfsub %%mm3, %%mm0\n"
"pfadd %%mm3, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ecx\n"
"jnz .loop4\n"
"popl %%ecx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void _M( downmix_2f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $128, %%ecx\n" /* loop counter */
"movd (%%ebx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 8(%%ebx), %%mm7\n" /* slev */
"punpckldq %%mm7, %%mm7\n" /* slev | slev */
".loop5:\n"
"movq (%%eax), %%mm0\n" /* left */
"movq 1024(%%eax), %%mm1\n" /* right */
"movq 2048(%%eax), %%mm3\n" /* sur */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm7, %%mm3\n"
"pfsub %%mm3, %%mm0\n"
"pfadd %%mm3, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ecx\n"
"jnz .loop5\n"
"popl %%ecx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void _M( downmix_3f_0r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $128, %%ecx\n" /* loop counter */
"movd (%%ebx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 4(%%ebx), %%mm6\n" /* clev */
"punpckldq %%mm6, %%mm6\n" /* clev | clev */
".loop6:\n"
"movq (%%eax), %%mm0\n" /*left */
"movq 2048(%%eax), %%mm1\n" /* right */
"movq 1024(%%eax), %%mm2\n" /* center */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm6, %%mm2\n"
"pfadd %%mm2, %%mm0\n"
"pfadd %%mm2, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ecx\n"
"jnz .loop6\n"
"popl %%ecx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void _M( stream_sample_1ch_to_s16 ) (s16 *s16_samples, float *left)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"pushl %%edx\n"
"movl $sqrt2_3dn, %%edx\n"
"movd (%%edx), %%mm7\n"
"punpckldq %%mm7, %%mm7\n" /* sqrt2 | sqrt2 */
"movl $128, %%ecx\n"
".loop2:\n"
"movq (%%ebx), %%mm0\n" /* c1 | c0 */
"pfmul %%mm7, %%mm0\n"
"pf2id %%mm0, %%mm0\n" /* c1 c0 --> mm0, int_32 */
"packssdw %%mm0, %%mm0\n" /* c1 c1 c0 c0 --> mm0, int_16 */
"movq %%mm0, (%%eax)\n"
"addl $8, %%eax\n"
"addl $8, %%ebx\n"
"decl %%ecx\n"
"jnz .loop2\n"
"popl %%edx\n"
"popl %%ecx\n"
"femms\n"
: "=a" (s16_samples), "=b" (left)
: "a" (s16_samples), "b" (left));
}
void _M( stream_sample_2ch_to_s16 ) (s16 *s16_samples, float *left, float *right)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $128, %%ecx\n"
".loop1:\n"
"movq (%%ebx), %%mm0\n" /* l1 | l0 */
"movq (%%edx), %%mm1\n" /* r1 | r0 */
"movq %%mm0, %%mm2\n" /* l1 | l0 */
"punpckldq %%mm1, %%mm0\n" /* r0 | l0 */
"punpckhdq %%mm1, %%mm2\n" /* r1 | l1 */
"pf2id %%mm0, %%mm0\n" /* r0 l0 --> mm0, int_32 */
"pf2id %%mm2, %%mm2\n" /* r0 l0 --> mm0, int_32 */
"packssdw %%mm2, %%mm0\n" /* r1 l1 r0 l0 --> mm0, int_16 */
"movq %%mm0, (%%eax)\n"
"movq %%mm2, 8(%%eax)\n"
"addl $8, %%eax\n"
"addl $8, %%ebx\n"
"addl $8, %%edx\n"
"decl %%ecx\n"
"jnz .loop1\n"
"popl %%ecx\n"
"femms\n"
: "=a" (s16_samples), "=b" (left), "=d" (right)
: "a" (s16_samples), "b" (left), "d" (right));
}
/*****************************************************************************
* ac3_downmix_c.c: ac3 downmix functions
* ac3_downmix_c.c: ac3 downmix functions in C
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_downmix_c.c,v 1.8 2001/05/14 15:58:04 reno Exp $
* $Id: ac3_downmix_c.c,v 1.1 2001/05/15 16:19:42 sam Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
......@@ -22,6 +22,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define MODULE_NAME downmix
#include "modules_inner.h"
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <string.h> /* memcpy() */
......@@ -31,12 +37,9 @@
#include "threads.h"
#include "mtime.h"
#include "stream_control.h"
#include "input_ext-dec.h"
#include "ac3_downmix.h"
#include "ac3_decoder.h"
void downmix_3f_2r_to_2ch_c (float *samples, dm_par_t *dm_par)
void _M( downmix_3f_2r_to_2ch ) (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *center, *left_sur, *right_sur;
......@@ -56,7 +59,7 @@ void downmix_3f_2r_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 _M( downmix_2f_2r_to_2ch ) (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *left_sur, *right_sur;
......@@ -75,7 +78,7 @@ void downmix_2f_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 _M( downmix_3f_1r_to_2ch ) (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *center, *right_sur;
......@@ -95,7 +98,7 @@ void downmix_3f_1r_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 _M( downmix_2f_1r_to_2ch ) (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *right_sur;
......@@ -114,7 +117,7 @@ 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 _M( downmix_3f_0r_to_2ch ) (float *samples, dm_par_t *dm_par)
{
int i;
float *left, *right, *center;
......@@ -133,7 +136,7 @@ void downmix_3f_0r_to_2ch_c (float *samples, dm_par_t *dm_par)
}
void stream_sample_2ch_to_s16_c (s16 *out_buf, float *left, float *right)
void _M( stream_sample_2ch_to_s16 ) (s16 *out_buf, float *left, float *right)
{
int i;
for (i=0; i < 256; i++) {
......@@ -143,7 +146,7 @@ void stream_sample_2ch_to_s16_c (s16 *out_buf, float *left, float *right)
}
void stream_sample_1ch_to_s16_c (s16 *out_buf, float *center)
void _M( stream_sample_1ch_to_s16 ) (s16 *out_buf, float *center)
{
int i;
float tmp;
......@@ -153,3 +156,4 @@ void stream_sample_1ch_to_s16_c (s16 *out_buf, float *center)
*out_buf++ = tmp;
}
}
/*****************************************************************************
* ac3_downmix.h: ac3 downmix functions
* ac3_downmix_common.h: ac3 downmix functions headers
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: ac3_downmix.h,v 1.7 2001/05/14 15:58:04 reno Exp $
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_downmix_common.h,v 1.1 2001/05/15 16:19:42 sam Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -21,31 +22,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/* 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);
/* SSE functions */
void downmix_3f_2r_to_2ch_sse(float *samples, dm_par_t * dm_par);
void downmix_3f_1r_to_2ch_sse(float *samples, dm_par_t * dm_par);
void downmix_2f_2r_to_2ch_sse(float *samples, dm_par_t * dm_par);
void downmix_2f_1r_to_2ch_sse(float *samples, dm_par_t * dm_par);
void downmix_3f_0r_to_2ch_sse(float *samples, dm_par_t * dm_par);
void stream_sample_2ch_to_s16_sse(s16 *s16_samples, float *left, float *right);
void stream_sample_1ch_to_s16_sse(s16 *s16_samples, float *center);
/* 3DNow! functions */
void downmix_3f_2r_to_2ch_3dn(float *samples, dm_par_t * dm_par);
void downmix_3f_1r_to_2ch_3dn(float *samples, dm_par_t * dm_par);
void downmix_2f_2r_to_2ch_3dn(float *samples, dm_par_t * dm_par);
void downmix_2f_1r_to_2ch_3dn(float *samples, dm_par_t * dm_par);
void downmix_3f_0r_to_2ch_3dn(float *samples, dm_par_t * dm_par);
void stream_sample_2ch_to_s16_3dn(s16 *s16_samples, float *left, float *right);
void stream_sample_1ch_to_s16_3dn(s16 *s16_samples, float *center);
void _M( downmix_3f_2r_to_2ch ) ( float *, dm_par_t * );
void _M( downmix_2f_2r_to_2ch ) ( float *, dm_par_t * );
void _M( downmix_3f_1r_to_2ch ) ( float *, dm_par_t * );
void _M( downmix_2f_1r_to_2ch ) ( float *, dm_par_t * );
void _M( downmix_3f_0r_to_2ch ) ( float *, dm_par_t * );
void _M( stream_sample_2ch_to_s16 ) ( s16 *, float *, float * );
void _M( stream_sample_1ch_to_s16 ) ( s16 *, float * );
/*****************************************************************************
* ac3_downmix_sse.c: accelerated SSE ac3 downmix functions
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_downmix_sse.c,v 1.1 2001/05/15 16:19:42 sam Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define MODULE_NAME downmixsse
#include "modules_inner.h"
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "tests.h"
#include "ac3_downmix.h"
void sqrt2_sse (void)
{
__asm__ (".float 0f0.7071068");
}
void _M( downmix_3f_2r_to_2ch ) (float * samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $64, %%ecx\n" /* loop counter */
"movss (%%ebx), %%xmm5\n" /* unit */
"shufps $0, %%xmm5, %%xmm5\n" /* unit | unit | unit | unit */
"movss 4(%%ebx), %%xmm6\n" /* clev */
"shufps $0, %%xmm6, %%xmm6\n" /* clev | clev | clev | clev */
"movss 8(%%ebx), %%xmm7\n" /* slev */
"shufps $0, %%xmm7, %%xmm7\n" /* slev | slev | slev | slev */
".loop:\n"
"movups (%%eax), %%xmm0\n" /* left */
"movups 2048(%%eax), %%xmm1\n" /* right */
"movups 1024(%%eax), %%xmm2\n" /* center */
"movups 3072(%%eax), %%xmm3\n" /* leftsur */
"movups 4096(%%eax), %%xmm4\n" /* rithgsur */
"mulps %%xmm5, %%xmm0\n"
"mulps %%xmm5, %%xmm1\n"
"mulps %%xmm6, %%xmm2\n"
"addps %%xmm2, %%xmm0\n"
"addps %%xmm2, %%xmm1\n"
"mulps %%xmm7, %%xmm3\n"
"mulps %%xmm7, %%xmm4\n"
"addps %%xmm3, %%xmm0\n"
"addps %%xmm4, %%xmm1\n"
"movups %%xmm0, (%%eax)\n"
"movups %%xmm1, 1024(%%eax)\n"
"addl $16, %%eax\n"
"decl %%ecx\n"
"jnz .loop\n"
"popl %%ecx\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void _M( downmix_2f_2r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $64, %%ecx\n" /* loop counter */
"movss (%%ebx), %%xmm5\n" /* unit */
"shufps $0, %%xmm5, %%xmm5\n" /* unit | unit | unit | unit */
"movss 8(%%ebx), %%xmm7\n" /* slev */
"shufps $0, %%xmm7, %%xmm7\n" /* slev | slev | slev | slev */
".loop3:\n"
"movups (%%eax), %%xmm0\n" /* left */
"movups 1024(%%eax), %%xmm1\n" /* right */
"movups 2048(%%eax), %%xmm3\n" /* leftsur */
"movups 3072(%%eax), %%xmm4\n" /* rightsur */
"mulps %%xmm5, %%xmm0\n"
"mulps %%xmm5, %%xmm1\n"
"mulps %%xmm7, %%xmm3\n"
"mulps %%xmm7, %%xmm4\n"
"addps %%xmm3, %%xmm0\n"
"addps %%xmm4, %%xmm1\n"
"movups %%xmm0, (%%eax)\n"
"movups %%xmm1, 1024(%%eax)\n"
"addl $16, %%eax\n"
"decl %%ecx\n"
"jnz .loop3\n"
"popl %%ecx\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void _M( downmix_3f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $64, %%ecx\n" /* loop counter */
"movss (%%ebx), %%xmm5\n" /* unit */
"shufps $0, %%xmm5, %%xmm5\n" /* unit | unit | unit | unit */
"movss 4(%%ebx), %%xmm6\n" /* clev */
"shufps $0, %%xmm6, %%xmm6\n" /* clev | clev | clev | clev */
"movss 8(%%ebx), %%xmm7\n" /* slev */
"shufps $0, %%xmm7, %%xmm7\n" /* slev | slev | slev | slev */
".loop4:\n"
"movups (%%eax), %%xmm0\n" /* left */
"movups 2048(%%eax), %%xmm1\n" /* right */
"movups 1024(%%eax), %%xmm2\n" /* center */
"movups 3072(%%eax), %%xmm3\n" /* sur */
"mulps %%xmm5, %%xmm0\n"
"mulps %%xmm5, %%xmm1\n"
"mulps %%xmm6, %%xmm2\n"
"addps %%xmm2, %%xmm0\n"
"mulps %%xmm7, %%xmm3\n"
"addps %%xmm2, %%xmm1\n"
"subps %%xmm3, %%xmm0\n"
"addps %%xmm3, %%xmm1\n"
"movups %%xmm0, (%%eax)\n"
"movups %%xmm1, 1024(%%eax)\n"
"addl $16, %%eax\n"
"decl %%ecx\n"
"jnz .loop4\n"
"popl %%ecx\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void _M( downmix_2f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $64, %%ecx\n" /* loop counter */
"movss (%%ebx), %%xmm5\n" /* unit */
"shufps $0, %%xmm5, %%xmm5\n" /* unit | unit | unit | unit */
"movss 8(%%ebx), %%xmm7\n" /* slev */
"shufps $0, %%xmm7, %%xmm7\n" /* slev | slev | slev | slev */
".loop5:\n"
"movups (%%eax), %%xmm0\n" /* left */
"movups 1024(%%eax), %%xmm1\n" /* right */
"movups 2048(%%eax), %%xmm3\n" /* sur */
"mulps %%xmm5, %%xmm0\n"
"mulps %%xmm5, %%xmm1\n"
"mulps %%xmm7, %%xmm3\n"
"subps %%xmm3, %%xmm0\n"
"addps %%xmm3, %%xmm1\n"
"movups %%xmm0, (%%eax)\n"
"movups %%xmm1, 1024(%%eax)\n"
"addl $16, %%eax\n"
"decl %%ecx\n"
"jnz .loop5\n"
"popl %%ecx\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void _M( downmix_3f_0r_to_2ch ) (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $64, %%ecx\n" /* loop counter */
"movss (%%ebx), %%xmm5\n" /* unit */
"shufps $0, %%xmm5, %%xmm5\n" /* unit | unit | unit | unit */
"movss 4(%%ebx), %%xmm6\n" /* clev */
"shufps $0, %%xmm6, %%xmm6\n" /* clev | clev | clev | clev */
".loop6:\n"
"movups (%%eax), %%xmm0\n" /*left */
"movups 2048(%%eax), %%xmm1\n" /* right */
"movups 1024(%%eax), %%xmm2\n" /* center */
"mulps %%xmm5, %%xmm0\n"
"mulps %%xmm5, %%xmm1\n"
"mulps %%xmm6, %%xmm2\n"
"addps %%xmm2, %%xmm0\n"
"addps %%xmm2, %%xmm1\n"
"movups %%xmm0, (%%eax)\n"
"movups %%xmm1, 1024(%%eax)\n"
"addl $16, %%eax\n"
"decl %%ecx\n"
"jnz .loop6\n"
"popl %%ecx\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void _M( stream_sample_1ch_to_s16 ) (s16 *s16_samples, float *left)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"pushl %%edx\n"
"movl $sqrt2_sse, %%edx\n"
"movss (%%edx), %%xmm7\n"
"shufps $0, %%xmm7, %%xmm7\n" /* sqrt2 | sqrt2 | sqrt2 | sqrt2 */
"movl $64, %%ecx\n"
".loop2:\n"
"movups (%%ebx), %%xmm0\n" /* c3 | c2 | c1 | c0 */
"mulps %%xmm7, %%xmm0\n"
"movhlps %%xmm0, %%xmm2\n" /* c3 | c2 */
"cvtps2pi %%xmm0, %%mm0\n" /* c1 c0 --> mm0, int_32 */
"cvtps2pi %%xmm2, %%mm1\n" /* c3 c2 --> mm1, int_32 */
"packssdw %%mm0, %%mm0\n" /* c1 c1 c0 c0 --> mm0, int_16 */
"packssdw %%mm1, %%mm1\n" /* c3 c3 c2 c2 --> mm1, int_16 */
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 8(%%eax)\n"
"addl $16, %%eax\n"
"addl $16, %%ebx\n"
"decl %%ecx\n"
"jnz .loop2\n"
"popl %%edx\n"
"popl %%ecx\n"
"emms\n"
: "=a" (s16_samples), "=b" (left)
: "a" (s16_samples), "b" (left));
}
void _M( stream_sample_2ch_to_s16 ) (s16 *s16_samples, float *left, float *right)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $64, %%ecx\n"
".loop1:\n"
"movups (%%ebx), %%xmm0\n" /* l3 | l2 | l1 | l0 */
"movups (%%edx), %%xmm1\n" /* r3 | r2 | r1 | r0 */
"movhlps %%xmm0, %%xmm2\n" /* l3 | l2 */
"movhlps %%xmm1, %%xmm3\n" /* r3 | r2 */
"unpcklps %%xmm1, %%xmm0\n" /* r1 | l1 | r0 | l0 */
"unpcklps %%xmm3, %%xmm2\n" /* r3 | l3 | r2 | l2 */
"cvtps2pi %%xmm0, %%mm0\n" /* r0 l0 --> mm0, int_32 */
"movhlps %%xmm0, %%xmm0\n"
"cvtps2pi %%xmm0, %%mm1\n" /* r1 l1 --> mm1, int_32 */
"cvtps2pi %%xmm2, %%mm2\n" /* r2 l2 --> mm2, int_32 */
"movhlps %%xmm2, %%xmm2\n"
"cvtps2pi %%xmm2, %%mm3\n" /* r3 l3 --> mm3, int_32 */
"packssdw %%mm1, %%mm0\n" /* r1 l1 r0 l0 --> mm0, int_16 */
"packssdw %%mm3, %%mm2\n" /* r3 l3 r2 l2 --> mm2, int_16 */
"movq %%mm0, (%%eax)\n"
"movq %%mm2, 8(%%eax)\n"
"addl $16, %%eax\n"
"addl $16, %%ebx\n"
"addl $16, %%edx\n"
"decl %%ecx\n"
"jnz .loop1\n"
"popl %%ecx\n"
"emms\n"
: "=a" (s16_samples), "=b" (left), "=d" (right)
: "a" (s16_samples), "b" (left), "d" (right));
}
/*****************************************************************************
* downmix.c : AC3 downmix module
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: downmix.c,v 1.1 2001/05/15 16:19:42 sam Exp $
*
* Authors: Gaël Hendryckx <jimmy@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define MODULE_NAME downmix
#include "modules_inner.h"
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <stdlib.h>
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "tests.h"
#include "ac3_downmix.h"
#include "ac3_downmix_common.h"
#include "modules.h"
/*****************************************************************************
* Local and extern prototypes.
*****************************************************************************/
static void downmix_getfunctions( function_list_t * p_function_list );
static int downmix_Probe ( probedata_t *p_data );
/*****************************************************************************
* Build configuration tree.
*****************************************************************************/
MODULE_CONFIG_START
ADD_WINDOW( "Configuration for AC3 downmix module" )
ADD_COMMENT( "Ha, ha -- nothing to configure yet" )
MODULE_CONFIG_END
/*****************************************************************************
* InitModule: get the module structure and configuration.
*****************************************************************************
* We have to fill psz_name, psz_longname and psz_version. These variables
* will be strdup()ed later by the main application because the module can
* be unloaded later to save memory, and we want to be able to access this
* data even after the module has been unloaded.
*****************************************************************************/
MODULE_INIT
{
p_module->psz_name = MODULE_STRING;
p_module->psz_longname = "AC3 downmix module";
p_module->psz_version = VERSION;
p_module->i_capabilities = MODULE_CAPABILITY_NULL
| MODULE_CAPABILITY_DOWNMIX;
return( 0 );
}
/*****************************************************************************
* ActivateModule: set the module to an usable state.
*****************************************************************************
* This function fills the capability functions and the configuration
* structure. Once ActivateModule() has been called, the i_usage can
* be set to 0 and calls to NeedModule() be made to increment it. To unload
* the module, one has to wait until i_usage == 0 and call DeactivateModule().
*****************************************************************************/
MODULE_ACTIVATE
{
p_module->p_functions = malloc( sizeof( module_functions_t ) );
if( p_module->p_functions == NULL )
{
return( -1 );
}
downmix_getfunctions( &p_module->p_functions->downmix );
p_module->p_config = p_config;
return( 0 );
}
/*****************************************************************************
* DeactivateModule: make sure the module can be unloaded.
*****************************************************************************
* This function must only be called when i_usage == 0. If it successfully
* returns, i_usage can be set to -1 and the module unloaded. Be careful to
* lock usage_lock during the whole process.
*****************************************************************************/
MODULE_DEACTIVATE
{
free( p_module->p_functions );
return( 0 );
}
/* Following functions are local */
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
*****************************************************************************/
static void downmix_getfunctions( function_list_t * p_function_list )
{
p_function_list->pf_probe = downmix_Probe;
#define F p_function_list->functions.downmix
F.pf_downmix_3f_2r_to_2ch = _M( downmix_3f_2r_to_2ch );
F.pf_downmix_3f_1r_to_2ch = _M( downmix_3f_1r_to_2ch );
F.pf_downmix_2f_2r_to_2ch = _M( downmix_2f_2r_to_2ch );
F.pf_downmix_2f_1r_to_2ch = _M( downmix_2f_1r_to_2ch );
F.pf_downmix_3f_0r_to_2ch = _M( downmix_3f_0r_to_2ch );
F.pf_stream_sample_2ch_to_s16 = _M( stream_sample_2ch_to_s16 );
F.pf_stream_sample_1ch_to_s16 = _M( stream_sample_1ch_to_s16 );
#undef F
}
/*****************************************************************************
* downmix_Probe: returns a preference score
*****************************************************************************/
static int downmix_Probe( probedata_t *p_data )
{
if( TestMethod( DOWNMIX_METHOD_VAR, "downmix" ) )
{
return( 999 );
}
/* This plugin always works */
return( 50 );
}
/*****************************************************************************
* downmix3dn.c : accelerated 3D Now! AC3 downmix module
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: downmix3dn.c,v 1.1 2001/05/15 16:19:42 sam Exp $
*
* Authors: Gaël Hendryckx <jimmy@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define MODULE_NAME downmix3dn
#include "modules_inner.h"
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <stdlib.h>
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "tests.h"
#include "ac3_downmix.h"
#include "ac3_downmix_common.h"
#include "modules.h"
/*****************************************************************************
* Local and extern prototypes.
*****************************************************************************/
static void downmix_getfunctions( function_list_t * p_function_list );
static int downmix_Probe ( probedata_t *p_data );
/*****************************************************************************
* Build configuration tree.
*****************************************************************************/
MODULE_CONFIG_START
ADD_WINDOW( "Configuration for AC3 downmix3dn module" )
ADD_COMMENT( "Ha, ha -- nothing to configure yet" )
MODULE_CONFIG_END
/*****************************************************************************
* InitModule: get the module structure and configuration.
*****************************************************************************
* We have to fill psz_name, psz_longname and psz_version. These variables
* will be strdup()ed later by the main application because the module can
* be unloaded later to save memory, and we want to be able to access this
* data even after the module has been unloaded.
*****************************************************************************/
MODULE_INIT
{
p_module->psz_name = MODULE_STRING;
p_module->psz_longname = "3D Now! AC3 downmix module";
p_module->psz_version = VERSION;
p_module->i_capabilities = MODULE_CAPABILITY_NULL
| MODULE_CAPABILITY_DOWNMIX;
return( 0 );
}
/*****************************************************************************
* ActivateModule: set the module to an usable state.
*****************************************************************************
* This function fills the capability functions and the configuration
* structure. Once ActivateModule() has been called, the i_usage can
* be set to 0 and calls to NeedModule() be made to increment it. To unload
* the module, one has to wait until i_usage == 0 and call DeactivateModule().
*****************************************************************************/
MODULE_ACTIVATE
{
p_module->p_functions = malloc( sizeof( module_functions_t ) );
if( p_module->p_functions == NULL )
{
return( -1 );
}
downmix_getfunctions( &p_module->p_functions->downmix );
p_module->p_config = p_config;
return( 0 );
}
/*****************************************************************************
* DeactivateModule: make sure the module can be unloaded.
*****************************************************************************
* This function must only be called when i_usage == 0. If it successfully
* returns, i_usage can be set to -1 and the module unloaded. Be careful to
* lock usage_lock during the whole process.
*****************************************************************************/
MODULE_DEACTIVATE
{
free( p_module->p_functions );
return( 0 );
}
/* Following functions are local */
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
*****************************************************************************/
static void downmix_getfunctions( function_list_t * p_function_list )
{
p_function_list->pf_probe = downmix_Probe;
#define F p_function_list->functions.downmix
F.pf_downmix_3f_2r_to_2ch = _M( downmix_3f_2r_to_2ch );
F.pf_downmix_3f_1r_to_2ch = _M( downmix_3f_1r_to_2ch );
F.pf_downmix_2f_2r_to_2ch = _M( downmix_2f_2r_to_2ch );
F.pf_downmix_2f_1r_to_2ch = _M( downmix_2f_1r_to_2ch );
F.pf_downmix_3f_0r_to_2ch = _M( downmix_3f_0r_to_2ch );
F.pf_stream_sample_2ch_to_s16 = _M( stream_sample_2ch_to_s16 );
F.pf_stream_sample_1ch_to_s16 = _M( stream_sample_1ch_to_s16 );
#undef F
}
/*****************************************************************************
* downmix_Probe: returns a preference score
*****************************************************************************/
static int downmix_Probe( probedata_t *p_data )
{
if( !TestCPU( CPU_CAPABILITY_3DNOW ) )
{
return( 0 );
}
if( TestMethod( DOWNMIX_METHOD_VAR, "downmix3dn" ) )
{
return( 999 );
}
/* This plugin always works */
return( 200 );
}
/*****************************************************************************
* downmixsse.c : accelerated SSE AC3 downmix module
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: downmixsse.c,v 1.1 2001/05/15 16:19:42 sam Exp $
*
* Authors: Gaël Hendryckx <jimmy@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define MODULE_NAME downmixsse
#include "modules_inner.h"
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <stdlib.h>
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "tests.h"
#include "ac3_downmix.h"
#include "ac3_downmix_common.h"
#include "modules.h"
/*****************************************************************************
* Local and extern prototypes.
*****************************************************************************/
static void downmix_getfunctions( function_list_t * p_function_list );
static int downmix_Probe ( probedata_t *p_data );
/*****************************************************************************
* Build configuration tree.
*****************************************************************************/
MODULE_CONFIG_START
ADD_WINDOW( "Configuration for AC3 downmixsse module" )
ADD_COMMENT( "Ha, ha -- nothing to configure yet" )
MODULE_CONFIG_END
/*****************************************************************************
* InitModule: get the module structure and configuration.
*****************************************************************************
* We have to fill psz_name, psz_longname and psz_version. These variables
* will be strdup()ed later by the main application because the module can
* be unloaded later to save memory, and we want to be able to access this
* data even after the module has been unloaded.
*****************************************************************************/
MODULE_INIT
{
p_module->psz_name = MODULE_STRING;
p_module->psz_longname = "SSE AC3 downmix module";
p_module->psz_version = VERSION;
p_module->i_capabilities = MODULE_CAPABILITY_NULL
| MODULE_CAPABILITY_DOWNMIX;
return( 0 );
}
/*****************************************************************************
* ActivateModule: set the module to an usable state.
*****************************************************************************
* This function fills the capability functions and the configuration
* structure. Once ActivateModule() has been called, the i_usage can
* be set to 0 and calls to NeedModule() be made to increment it. To unload
* the module, one has to wait until i_usage == 0 and call DeactivateModule().
*****************************************************************************/
MODULE_ACTIVATE
{
p_module->p_functions = malloc( sizeof( module_functions_t ) );
if( p_module->p_functions == NULL )
{
return( -1 );
}
downmix_getfunctions( &p_module->p_functions->downmix );
p_module->p_config = p_config;
return( 0 );
}
/*****************************************************************************
* DeactivateModule: make sure the module can be unloaded.
*****************************************************************************
* This function must only be called when i_usage == 0. If it successfully
* returns, i_usage can be set to -1 and the module unloaded. Be careful to
* lock usage_lock during the whole process.
*****************************************************************************/
MODULE_DEACTIVATE
{
free( p_module->p_functions );
return( 0 );
}
/* Following functions are local */
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
*****************************************************************************/
static void downmix_getfunctions( function_list_t * p_function_list )
{
p_function_list->pf_probe = downmix_Probe;
#define F p_function_list->functions.downmix
F.pf_downmix_3f_2r_to_2ch = _M( downmix_3f_2r_to_2ch );
F.pf_downmix_3f_1r_to_2ch = _M( downmix_3f_1r_to_2ch );
F.pf_downmix_2f_2r_to_2ch = _M( downmix_2f_2r_to_2ch );
F.pf_downmix_2f_1r_to_2ch = _M( downmix_2f_1r_to_2ch );
F.pf_downmix_3f_0r_to_2ch = _M( downmix_3f_0r_to_2ch );
F.pf_stream_sample_2ch_to_s16 = _M( stream_sample_2ch_to_s16 );
F.pf_stream_sample_1ch_to_s16 = _M( stream_sample_1ch_to_s16 );
#undef F
}
/*****************************************************************************
* downmix_Probe: returns a preference score
*****************************************************************************/
static int downmix_Probe( probedata_t *p_data )
{
if( !TestCPU( CPU_CAPABILITY_SSE ) )
{
return( 0 );
}
if( TestMethod( DOWNMIX_METHOD_VAR, "downmixsse" ) )
{
return( 999 );
}
/* This plugin always works */
return( 200 );
}
......@@ -2,7 +2,7 @@
* idctaltivec.c : Altivec IDCT module
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: idctaltivec.c,v 1.5 2001/05/06 04:32:02 sam Exp $
* $Id: idctaltivec.c,v 1.6 2001/05/15 16:19:42 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -146,22 +146,18 @@ static void idct_getfunctions( function_list_t * p_function_list )
*****************************************************************************/
static int idct_Probe( probedata_t *p_data )
{
if( TestCPU( CPU_CAPABILITY_ALTIVEC ) )
if( !TestCPU( CPU_CAPABILITY_ALTIVEC ) )
{
if( TestMethod( IDCT_METHOD_VAR, "idctaltivec" ) )
{
return( 999 );
}
else
{
/* The Altivec iDCT is deactivated until it really works */
return( 0 /* 200 */ );
}
return( 0 );
}
else
if( TestMethod( IDCT_METHOD_VAR, "idctaltivec" ) )
{
return( 0 );
return( 999 );
}
/* The Altivec iDCT is deactivated until it really works */
return( 0 /* 200 */ );
}
/*****************************************************************************
......
......@@ -2,7 +2,7 @@
* idctmmx.c : MMX IDCT module
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: idctmmx.c,v 1.10 2001/05/06 04:32:02 sam Exp $
* $Id: idctmmx.c,v 1.11 2001/05/15 16:19:42 sam Exp $
*
* Authors: Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
* Michel Lespinasse <walken@zoy.org>
......@@ -151,21 +151,17 @@ static void idct_getfunctions( function_list_t * p_function_list )
*****************************************************************************/
static int idct_Probe( probedata_t *p_data )
{
if( TestCPU( CPU_CAPABILITY_MMX ) )
if( !TestCPU( CPU_CAPABILITY_MMX ) )
{
if( TestMethod( IDCT_METHOD_VAR, "idctmmx" ) )
{
return( 999 );
}
else
{
return( 150 );
}
return( 0 );
}
else
if( TestMethod( IDCT_METHOD_VAR, "idctmmx" ) )
{
return( 0 );
return( 999 );
}
return( 150 );
}
/*****************************************************************************
......
......@@ -2,7 +2,7 @@
* idctmmxext.c : MMX EXT IDCT module
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: idctmmxext.c,v 1.7 2001/05/06 04:32:02 sam Exp $
* $Id: idctmmxext.c,v 1.8 2001/05/15 16:19:42 sam Exp $
*
* Authors: Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
* Michel Lespinasse <walken@zoy.org>
......@@ -151,21 +151,18 @@ static void idct_getfunctions( function_list_t * p_function_list )
*****************************************************************************/
static int idct_Probe( probedata_t *p_data )
{
if( TestCPU( CPU_CAPABILITY_MMXEXT ) )
if( !TestCPU( CPU_CAPABILITY_MMXEXT ) )
{
if( TestMethod( IDCT_METHOD_VAR, "idctmmxext" ) )
{
return( 999 );
}
else
{
return( 200 );
}
return( 0 );
}
else
if( TestMethod( IDCT_METHOD_VAR, "idctmmxext" ) )
{
return( 0 );
return( 999 );
}
return( 200 );
}
/*****************************************************************************
......
###############################################################################
# vlc (VideoLAN Client) imdct module makefile
# (c)2001 VideoLAN
###############################################################################
#
# Objects
#
PLUGIN_IMDCT = imdct.o ac3_imdct_c.o ac3_srfft_c.o
PLUGIN_IMDCTSSE = imdctsse.o ac3_imdct_sse.o ac3_srfft_sse.o
PLUGIN_IMDCTCOMMON = ac3_imdct_common.o
BUILTIN_IMDCT = $(PLUGIN_IMDCT:%.o=BUILTIN_IMDCT_%.o) \
$(PLUGIN_IMDCTCOMMON:%.o=BUILTIN_IMDCT_%.o)
BUILTIN_IMDCTSSE = $(PLUGIN_IMDCTSSE:%.o=BUILTIN_IMDCTSSE_%.o) \
$(PLUGIN_IMDCTCOMMON:%.o=BUILTIN_IMDCTSSE_%.o)
PLUGIN_C = $(PLUGIN_IMDCT) $(PLUGIN_IMDCTSSE) $(PLUGIN_IMDCTCOMMON)
ALL_OBJ = $(PLUGIN_C) $(BUILTIN_IMDCT) $(BUILTIN_IMDCTSSE)
#
# Virtual targets
#
include ../../Makefile.modules
$(BUILTIN_IMDCT): BUILTIN_IMDCT_%.o: .dep/%.d
$(BUILTIN_IMDCT): BUILTIN_IMDCT_%.o: %.c
$(CC) $(CFLAGS) -DBUILTIN -DMODULE_NAME=imdct -c -o $@ $<
$(BUILTIN_IMDCTSSE): BUILTIN_IMDCTSSE_%.o: .dep/%.d
$(BUILTIN_IMDCTSSE): BUILTIN_IMDCTSSE_%.o: %.c
$(CC) $(CFLAGS) -DBUILTIN -DMODULE_NAME=imdctsse -c -o $@ $<
#
# Real targets
#
../../lib/imdct.so: $(PLUGIN_IMDCT) $(PLUGIN_IMDCTCOMMON)
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS)
../../lib/imdct.a: $(BUILTIN_IMDCT)
ar r $@ $^
$(RANLIB) $@
../../lib/imdctsse.so: $(PLUGIN_IMDCTSSE) $(PLUGIN_IMDCTCOMMON)
$(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS)
../../lib/imdctsse.a: $(BUILTIN_IMDCTSSE)
ar r $@ $^
$(RANLIB) $@
This diff is collapsed.
This diff is collapsed.
/*****************************************************************************
* ac3_imdct_c.h: ac3 DCT
* ac3_imdct_common.h: common ac3 DCT headers
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_imdct_c.h,v 1.2 2001/04/30 21:10:25 reno Exp $
* $Id: ac3_imdct_common.h,v 1.1 2001/05/15 16:19:42 sam Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
......@@ -22,9 +22,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
int imdct_init_c (imdct_t * p_imdct);
void imdct_do_256(imdct_t * p_imdct, float data[], float delay[]);
void imdct_do_256_nol(imdct_t * p_imdct, float data[], float delay[]);
void imdct_do_512_c(imdct_t * p_imdct, float data[], float delay[]);
void imdct_do_512_nol_c(imdct_t * p_imdct, float data[], float delay[]);
void _M( imdct_init ) ( imdct_t * p_imdct );
void _M( imdct_do_256 ) ( imdct_t * p_imdct, float data[], float delay[] );
void _M( imdct_do_256_nol ) ( imdct_t * p_imdct, float data[], float delay[] );
void _M( imdct_do_512 ) ( imdct_t * p_imdct, float data[], float delay[] );
void _M( imdct_do_512_nol ) ( imdct_t * p_imdct, float data[], float delay[] );
This diff is collapsed.
/*****************************************************************************
* ac3_srfft.h: ac3 FFT
* ac3_srfft.h: ac3 FFT tables
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_srfft.h,v 1.3 2001/05/14 15:58:04 reno Exp $
* $Id: ac3_srfft.h,v 1.1 2001/05/15 16:19:42 sam Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
......@@ -289,3 +289,4 @@ static const complex_t delta128_3[32] =
a_i += v_i; \
A13.imag = a_i; \
}
/*****************************************************************************
* ac3_srfft.c: ac3 FFT
* ac3_srfft.c: ac3 FFT in C
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_srfft.c,v 1.4 2001/05/14 15:58:04 reno Exp $
* $Id: ac3_srfft_c.c,v 1.1 2001/05/15 16:19:42 sam Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
......@@ -22,6 +22,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define MODULE_NAME imdct
#include "modules_inner.h"
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <string.h> /* memcpy() */
......@@ -34,10 +40,7 @@
#include "threads.h"
#include "mtime.h"
#include "stream_control.h"
#include "input_ext-dec.h"
#include "ac3_decoder.h"
#include "ac3_imdct.h"
#include "ac3_srfft.h"
static void fft_8 (complex_t *x);
......@@ -206,7 +209,7 @@ static void fft_8 (complex_t *x)
static void fft_asmb(int k, complex_t *x, complex_t *wTB,
const complex_t *d, const complex_t *d_3)
const complex_t *d, const complex_t *d_3)
{
register complex_t *x2k, *x3k, *x4k, *wB;
register float a_r, a_i, a1_r, a1_i, u_r, u_i, v_r, v_i;
......@@ -256,7 +259,7 @@ static void fft_asmb16(complex_t *x, complex_t *wTB)
}
void fft_64p_c (complex_t *a)
void _M( fft_64p ) ( complex_t *a )
{
fft_8(&a[0]); fft_4(&a[8]); fft_4(&a[12]);
fft_asmb16(&a[0], &a[8]);
......@@ -274,7 +277,7 @@ void fft_64p_c (complex_t *a)
}
void fft_128p_c (complex_t *a)
void _M( fft_128p ) ( complex_t *a )
{
fft_8(&a[0]); fft_4(&a[8]); fft_4(&a[12]);
fft_asmb16(&a[0], &a[8]);
......@@ -310,3 +313,4 @@ void fft_128p_c (complex_t *a)
/* fft_128(&a[0]); */
fft_asmb(16, &a[0], &a[64], &delta128[0], &delta128_3[0]);
}
This diff is collapsed.
/*****************************************************************************
* imdct.c : IMDCT module
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: imdct.c,v 1.1 2001/05/15 16:19:42 sam Exp $
*
* Authors: Gaël Hendryckx <jimmy@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define MODULE_NAME imdct
#include "modules_inner.h"
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <stdlib.h>
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "tests.h"
#include "ac3_imdct.h"
#include "ac3_imdct_common.h"
#include "modules.h"
/*****************************************************************************
* Local and extern prototypes.
*****************************************************************************/
static void imdct_getfunctions( function_list_t * p_function_list );
static int imdct_Probe ( probedata_t *p_data );
/*****************************************************************************
* Build configuration tree.
*****************************************************************************/
MODULE_CONFIG_START
ADD_WINDOW( "Configuration for IMDCT module" )
ADD_COMMENT( "Ha, ha -- nothing to configure yet" )
MODULE_CONFIG_END
/*****************************************************************************
* InitModule: get the module structure and configuration.
*****************************************************************************
* We have to fill psz_name, psz_longname and psz_version. These variables
* will be strdup()ed later by the main application because the module can
* be unloaded later to save memory, and we want to be able to access this
* data even after the module has been unloaded.
*****************************************************************************/
MODULE_INIT
{
p_module->psz_name = MODULE_STRING;
p_module->psz_longname = "AC3 IMDCT module";
p_module->psz_version = VERSION;
p_module->i_capabilities = MODULE_CAPABILITY_NULL
| MODULE_CAPABILITY_IMDCT;
return( 0 );
}
/*****************************************************************************
* ActivateModule: set the module to an usable state.
*****************************************************************************
* This function fills the capability functions and the configuration
* structure. Once ActivateModule() has been called, the i_usage can
* be set to 0 and calls to NeedModule() be made to increment it. To unload
* the module, one has to wait until i_usage == 0 and call DeactivateModule().
*****************************************************************************/
MODULE_ACTIVATE
{
p_module->p_functions = malloc( sizeof( module_functions_t ) );
if( p_module->p_functions == NULL )
{
return( -1 );
}
imdct_getfunctions( &p_module->p_functions->imdct );
p_module->p_config = p_config;
return( 0 );
}
/*****************************************************************************
* DeactivateModule: make sure the module can be unloaded.
*****************************************************************************
* This function must only be called when i_usage == 0. If it successfully
* returns, i_usage can be set to -1 and the module unloaded. Be careful to
* lock usage_lock during the whole process.
*****************************************************************************/
MODULE_DEACTIVATE
{
free( p_module->p_functions );
return( 0 );
}
/* Following functions are local */
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
*****************************************************************************/
static void imdct_getfunctions( function_list_t * p_function_list )
{
p_function_list->pf_probe = imdct_Probe;
#define F p_function_list->functions.imdct
F.pf_imdct_init = _M( imdct_init );
F.pf_imdct_256 = _M( imdct_do_256 );
F.pf_imdct_256_nol = _M( imdct_do_256_nol );
F.pf_imdct_512 = _M( imdct_do_512 );
F.pf_imdct_512_nol = _M( imdct_do_512_nol );
#undef F
}
/*****************************************************************************
* imdct_Probe: returns a preference score
*****************************************************************************/
static int imdct_Probe( probedata_t *p_data )
{
if( TestMethod( IMDCT_METHOD_VAR, "imdct" ) )
{
return( 999 );
}
/* This plugin always works */
return( 50 );
}
/*****************************************************************************
* imdctsse.c : accelerated SSE IMDCT module
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: imdctsse.c,v 1.1 2001/05/15 16:19:42 sam Exp $
*
* Authors: Gaël Hendryckx <jimmy@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define MODULE_NAME imdctsse
#include "modules_inner.h"
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <stdlib.h>
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "tests.h"
#include "ac3_imdct.h"
#include "ac3_imdct_common.h"
#include "modules.h"
/*****************************************************************************
* Local and extern prototypes.
*****************************************************************************/
static void imdct_getfunctions( function_list_t * p_function_list );
static int imdct_Probe ( probedata_t *p_data );
/*****************************************************************************
* Build configuration tree.
*****************************************************************************/
MODULE_CONFIG_START
ADD_WINDOW( "Configuration for IMDCT module" )
ADD_COMMENT( "Ha, ha -- nothing to configure yet" )
MODULE_CONFIG_END
/*****************************************************************************
* InitModule: get the module structure and configuration.
*****************************************************************************
* We have to fill psz_name, psz_longname and psz_version. These variables
* will be strdup()ed later by the main application because the module can
* be unloaded later to save memory, and we want to be able to access this
* data even after the module has been unloaded.
*****************************************************************************/
MODULE_INIT
{
p_module->psz_name = MODULE_STRING;
p_module->psz_longname = "AC3 IMDCT module";
p_module->psz_version = VERSION;
p_module->i_capabilities = MODULE_CAPABILITY_NULL
| MODULE_CAPABILITY_IMDCT;
return( 0 );
}
/*****************************************************************************
* ActivateModule: set the module to an usable state.
*****************************************************************************
* This function fills the capability functions and the configuration
* structure. Once ActivateModule() has been called, the i_usage can
* be set to 0 and calls to NeedModule() be made to increment it. To unload
* the module, one has to wait until i_usage == 0 and call DeactivateModule().
*****************************************************************************/
MODULE_ACTIVATE
{
p_module->p_functions = malloc( sizeof( module_functions_t ) );
if( p_module->p_functions == NULL )
{
return( -1 );
}
imdct_getfunctions( &p_module->p_functions->imdct );
p_module->p_config = p_config;
return( 0 );
}
/*****************************************************************************
* DeactivateModule: make sure the module can be unloaded.
*****************************************************************************
* This function must only be called when i_usage == 0. If it successfully
* returns, i_usage can be set to -1 and the module unloaded. Be careful to
* lock usage_lock during the whole process.
*****************************************************************************/
MODULE_DEACTIVATE
{
free( p_module->p_functions );
return( 0 );
}
/* Following functions are local */
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
*****************************************************************************/
static void imdct_getfunctions( function_list_t * p_function_list )
{
p_function_list->pf_probe = imdct_Probe;
#define F p_function_list->functions.imdct
F.pf_imdct_init = _M( imdct_init );
F.pf_imdct_256 = _M( imdct_do_256 );
F.pf_imdct_256_nol = _M( imdct_do_256_nol );
F.pf_imdct_512 = _M( imdct_do_512 );
F.pf_imdct_512_nol = _M( imdct_do_512_nol );
#undef F
}
/*****************************************************************************
* imdct_Probe: returns a preference score
*****************************************************************************/
static int imdct_Probe( probedata_t *p_data )
{
if( !TestCPU( CPU_CAPABILITY_SSE ) )
{
return( 0 );
}
if( TestMethod( IDCT_METHOD_VAR, "imdctsse" ) )
{
return( 999 );
}
/* This plugin always works */
return( 200 );
}
......@@ -2,7 +2,7 @@
* motionmmx.c : MMX motion compensation module for vlc
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* $Id: motionmmx.c,v 1.4 2001/04/15 04:19:57 sam Exp $
* $Id: motionmmx.c,v 1.5 2001/05/15 16:19:42 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -116,20 +116,16 @@ MODULE_DEACTIVATE
*****************************************************************************/
int _M( motion_Probe )( probedata_t *p_data )
{
if( TestCPU( CPU_CAPABILITY_MMX ) )
if( !TestCPU( CPU_CAPABILITY_MMX ) )
{
if( TestMethod( MOTION_METHOD_VAR, "motionmmx" ) )
{
return( 999 );
}
else
{
return( 150 );
}
return( 0 );
}
else
if( TestMethod( MOTION_METHOD_VAR, "motionmmx" ) )
{
return( 0 );
return( 999 );
}
return( 150 );
}
......@@ -2,7 +2,7 @@
* motionmmxext.c : MMX EXT motion compensation module for vlc
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* $Id: motionmmxext.c,v 1.4 2001/04/15 04:19:57 sam Exp $
* $Id: motionmmxext.c,v 1.5 2001/05/15 16:19:42 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -116,20 +116,16 @@ MODULE_DEACTIVATE
*****************************************************************************/
int _M( motion_Probe )( probedata_t *p_data )
{
if( TestCPU( CPU_CAPABILITY_MMXEXT ) )
if( !TestCPU( CPU_CAPABILITY_MMXEXT ) )
{
if( TestMethod( MOTION_METHOD_VAR, "motionmmxext" ) )
{
return( 999 );
}
else
{
return( 200 );
}
return( 0 );
}
else
if( TestMethod( MOTION_METHOD_VAR, "motionmmxext" ) )
{
return( 0 );
return( 999 );
}
return( 200 );
}
......@@ -3,7 +3,7 @@
* Provides functions to perform the YUV conversion.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: video_yuvmmx.c,v 1.8 2001/04/15 04:19:58 sam Exp $
* $Id: video_yuvmmx.c,v 1.9 2001/05/15 16:19:42 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -79,21 +79,17 @@ void _M( yuv_getfunctions )( function_list_t * p_function_list )
static int yuv_Probe( probedata_t *p_data )
{
/* Test for MMX support in the CPU */
if( TestCPU( CPU_CAPABILITY_MMX ) )
if( !TestCPU( CPU_CAPABILITY_MMX ) )
{
if( TestMethod( YUV_METHOD_VAR, "yuvmmx" ) )
{
return( 999 );
}
else
{
return( 100 );
}
return( 0 );
}
else
if( TestMethod( YUV_METHOD_VAR, "yuvmmx" ) )
{
return( 0 );
return( 999 );
}
return( 100 );
}
/*****************************************************************************
......
......@@ -2,7 +2,7 @@
* ac3_bit_allocate.c: ac3 allocation tables
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* $Id: ac3_bit_allocate.c,v 1.21 2001/05/14 15:58:03 reno Exp $
* $Id: ac3_bit_allocate.c,v 1.22 2001/05/15 16:19:42 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
......@@ -22,6 +22,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <string.h> /* memcpy() */
......@@ -31,12 +35,13 @@
#include "threads.h"
#include "mtime.h"
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#include "stream_control.h"
#include "input_ext-dec.h"
#include "ac3_imdct.h"
#include "ac3_downmix.h"
#include "ac3_decoder.h"
#include "ac3_internal.h" /* DELTA_BIT_REUSE */
......
......@@ -2,7 +2,7 @@
* ac3_decoder.c: core ac3 decoder
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder.c,v 1.33 2001/05/14 15:58:03 reno Exp $
* $Id: ac3_decoder.c,v 1.34 2001/05/15 16:19:42 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@zoy.org>
......@@ -23,6 +23,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <string.h> /* memcpy() */
......@@ -39,8 +42,11 @@
#include "audio_output.h"
#include "ac3_imdct.h"
#include "ac3_downmix.h"
#include "ac3_decoder.h"
#include "ac3_decoder_thread.h" /* ac3dec_thread_t */
#include "ac3_internal.h"
static const float cmixlev_lut[4] = { 0.707, 0.595, 0.500, 0.707 };
......@@ -50,7 +56,6 @@ int ac3_init (ac3dec_t * p_ac3dec)
{
p_ac3dec->mantissa.lfsr_state = 1; /* dither_gen initialization */
imdct_init(&p_ac3dec->imdct);
downmix_init(&p_ac3dec->downmix);
return 0;
}
......@@ -58,7 +63,7 @@ int ac3_init (ac3dec_t * p_ac3dec)
int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer)
{
int i;
ac3dec_thread_t * p_ac3dec_t = (ac3dec_thread_t *) p_ac3dec->bit_stream.p_callback_arg;
ac3dec_thread_t * p_ac3thread = (ac3dec_thread_t *) p_ac3dec->bit_stream.p_callback_arg;
if (parse_bsi (p_ac3dec))
{
......@@ -67,20 +72,20 @@ int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer)
return 1;
}
/* compute downmix parameters
* downmix to tow channels for now */
p_ac3dec->dm_par.clev = 0.0;
/* 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 & 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];
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;
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 */
......@@ -88,45 +93,50 @@ int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer)
(p_ac3dec->bsi.nfchans + p_ac3dec->bsi.lfeon));
if ((p_ac3dec_t->p_fifo->b_die) && (p_ac3dec_t->p_fifo->b_error))
if( p_ac3thread->p_fifo->b_die || p_ac3thread->p_fifo->b_error )
{
return 1;
}
if (parse_audblk (p_ac3dec, i))
if( parse_audblk( p_ac3dec, i ) )
{
intf_WarnMsg (3,"ac3dec warn: error during audioblock");
parse_auxdata (p_ac3dec);
intf_WarnMsg( 3, "ac3dec warning: error during audioblock" );
parse_auxdata( p_ac3dec );
return 1;
}
if ((p_ac3dec_t->p_fifo->b_die) && (p_ac3dec_t->p_fifo->b_error))
if( p_ac3thread->p_fifo->b_die || p_ac3thread->p_fifo->b_error )
{
return 1;
}
if (exponent_unpack (p_ac3dec))
if( exponent_unpack( p_ac3dec ) )
{
intf_WarnMsg (3,"ac3dec warn: error during unpack");
parse_auxdata (p_ac3dec);
intf_WarnMsg( 3, "ac3dec warning: error during unpack" );
parse_auxdata( p_ac3dec );
return 1;
}
bit_allocate (p_ac3dec);
mantissa_unpack (p_ac3dec);
if ((p_ac3dec_t->p_fifo->b_die) && (p_ac3dec_t->p_fifo->b_error))
if( p_ac3thread->p_fifo->b_die || p_ac3thread->p_fifo->b_error )
{
return 1;
}
if (p_ac3dec->bsi.acmod == 0x2)
{
rematrix (p_ac3dec);
}
imdct (p_ac3dec, buffer);
buffer += 2*256;
buffer += 2 * 256;
}
parse_auxdata (p_ac3dec);
return 0;
}
......@@ -2,7 +2,7 @@
* ac3_decoder.h : ac3 decoder interface
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder.h,v 1.8 2001/05/14 15:58:03 reno Exp $
* $Id: ac3_decoder.h,v 1.9 2001/05/15 16:19:42 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Renaud Dartus <reno@videolan.org>
......@@ -352,63 +352,6 @@ typedef struct mantissa_s
u16 lfsr_state;
} mantissa_t;
typedef struct complex_s {
float real;
float imag;
} complex_t;
#define N 512
typedef struct imdct_s
{
complex_t buf[N/4];
/* Delay buffer for time domain interleaving */
float delay[6][256];
float delay1[6][256];
/* Twiddle factors for IMDCT */
float xcos1[N/4];
float xsin1[N/4];
float xcos2[N/8];
float xsin2[N/8];
/* Twiddle factor LUT */
complex_t *w[7];
complex_t w_1[1];
complex_t w_2[2];
complex_t w_4[4];
complex_t w_8[8];
complex_t w_16[16];
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
{
/*
......@@ -436,3 +379,4 @@ struct ac3dec_s
downmix_t downmix;
};
This diff is collapsed.
/*****************************************************************************
* ac3_downmix_3dn.c: ac3 downmix functions
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_downmix_3dn.c,v 1.1 2001/05/14 15:58:04 reno Exp $
*
* Authors: Renaud Dartus <reno@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include "defs.h"
#include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "tests.h"
#include "stream_control.h"
#include "input_ext-dec.h"
#include "ac3_decoder.h"
void downmix_3f_2r_to_2ch_3dn (float * samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $128, %%ecx\n" /* loop counter */
"movd (%%ebx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 4(%%ebx), %%mm6\n" /* clev */
"punpckldq %%mm6, %%mm6\n" /* clev | clev */
"movd 8(%%ebx), %%mm7\n" /* slev */
"punpckldq %%mm7, %%mm7\n" /* slev | slev */
".loop:\n"
"movq (%%eax), %%mm0\n" /* left */
"movq 2048(%%eax), %%mm1\n" /* right */
"movq 1024(%%eax), %%mm2\n" /* center */
"movq 3072(%%eax), %%mm3\n" /* leftsur */
"movq 4096(%%eax), %%mm4\n" /* rightsur */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm6, %%mm2\n"
"pfadd %%mm2, %%mm0\n"
"pfadd %%mm2, %%mm1\n"
"pfmul %%mm7, %%mm3\n"
"pfmul %%mm7, %%mm4\n"
"pfadd %%mm3, %%mm0\n"
"pfadd %%mm4, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ecx\n"
"jnz .loop\n"
"popl %%ecx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void downmix_2f_2r_to_2ch_3dn (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $128, %%ecx\n" /* loop counter */
"movd (%%ebx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 8(%%ebx), %%mm7\n" /* slev */
"punpckldq %%mm7, %%mm7\n" /* slev | slev */
".loop3:\n"
"movq (%%eax), %%mm0\n" /* left */
"movq 1024(%%eax), %%mm1\n" /* right */
"movq 2048(%%eax), %%mm3\n" /* leftsur */
"movq 3072(%%eax), %%mm4\n" /* rightsur */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm7, %%mm3\n"
"pfmul %%mm7, %%mm4\n"
"pfadd %%mm3, %%mm0\n"
"pfadd %%mm4, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ecx\n"
"jnz .loop3\n"
"popl %%ecx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void downmix_3f_1r_to_2ch_3dn (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $128, %%ecx\n" /* loop counter */
"movd (%%ebx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 4(%%ebx), %%mm6\n" /* clev */
"punpckldq %%mm6, %%mm6\n" /* clev | clev */
"movd 8(%%ebx), %%mm7\n" /* slev */
"punpckldq %%mm7, %%mm7\n" /* slev | slev */
".loop4:\n"
"movq (%%eax), %%mm0\n" /* left */
"movq 2048(%%eax), %%mm1\n" /* right */
"movq 1024(%%eax), %%mm2\n" /* center */
"movq 3072(%%eax), %%mm3\n" /* sur */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm6, %%mm2\n"
"pfadd %%mm2, %%mm0\n"
"pfmul %%mm7, %%mm3\n"
"pfadd %%mm2, %%mm1\n"
"pfsub %%mm3, %%mm0\n"
"pfadd %%mm3, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ecx\n"
"jnz .loop4\n"
"popl %%ecx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void downmix_2f_1r_to_2ch_3dn (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $128, %%ecx\n" /* loop counter */
"movd (%%ebx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 8(%%ebx), %%mm7\n" /* slev */
"punpckldq %%mm7, %%mm7\n" /* slev | slev */
".loop5:\n"
"movq (%%eax), %%mm0\n" /* left */
"movq 1024(%%eax), %%mm1\n" /* right */
"movq 2048(%%eax), %%mm3\n" /* sur */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm7, %%mm3\n"
"pfsub %%mm3, %%mm0\n"
"pfadd %%mm3, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ecx\n"
"jnz .loop5\n"
"popl %%ecx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void downmix_3f_0r_to_2ch_3dn (float *samples, dm_par_t * dm_par)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $128, %%ecx\n" /* loop counter */
"movd (%%ebx), %%mm5\n" /* unit */
"punpckldq %%mm5, %%mm5\n" /* unit | unit */
"movd 4(%%ebx), %%mm6\n" /* clev */
"punpckldq %%mm6, %%mm6\n" /* clev | clev */
".loop6:\n"
"movq (%%eax), %%mm0\n" /*left */
"movq 2048(%%eax), %%mm1\n" /* right */
"movq 1024(%%eax), %%mm2\n" /* center */
"pfmul %%mm5, %%mm0\n"
"pfmul %%mm5, %%mm1\n"
"pfmul %%mm6, %%mm2\n"
"pfadd %%mm2, %%mm0\n"
"pfadd %%mm2, %%mm1\n"
"movq %%mm0, (%%eax)\n"
"movq %%mm1, 1024(%%eax)\n"
"addl $8, %%eax\n"
"decl %%ecx\n"
"jnz .loop6\n"
"popl %%ecx\n"
"femms\n"
: "=a" (samples)
: "a" (samples), "b" (dm_par));
}
void stream_sample_1ch_to_s16_3dn (s16 *s16_samples, float *left)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"pushl %%edx\n"
"movl $sqrt2, %%edx\n"
"movd (%%edx), %%mm7\n"
"punpckldq %%mm7, %%mm7\n" /* sqrt2 | sqrt2 */
"movl $128, %%ecx\n"
".loop2:\n"
"movq (%%ebx), %%mm0\n" /* c1 | c0 */
"pfmul %%mm7, %%mm0\n"
"pf2id %%mm0, %%mm0\n" /* c1 c0 --> mm0, int_32 */
"packssdw %%mm0, %%mm0\n" /* c1 c1 c0 c0 --> mm0, int_16 */
"movq %%mm0, (%%eax)\n"
"addl $8, %%eax\n"
"addl $8, %%ebx\n"
"decl %%ecx\n"
"jnz .loop2\n"
"popl %%edx\n"
"popl %%ecx\n"
"femms\n"
: "=a" (s16_samples), "=b" (left)
: "a" (s16_samples), "b" (left));
}
void stream_sample_2ch_to_s16_3dn (s16 *s16_samples, float *left, float *right)
{
__asm__ __volatile__ (
"pushl %%ecx\n"
"movl $128, %%ecx\n"
".loop1:\n"
"movq (%%ebx), %%mm0\n" /* l1 | l0 */
"movq (%%edx), %%mm1\n" /* r1 | r0 */
"movq %%mm0, %%mm2\n" /* l1 | l0 */
"punpckldq %%mm1, %%mm0\n" /* r0 | l0 */
"punpckhdq %%mm1, %%mm2\n" /* r1 | l1 */
"pf2id %%mm0, %%mm0\n" /* r0 l0 --> mm0, int_32 */
"pf2id %%mm2, %%mm2\n" /* r0 l0 --> mm0, int_32 */
"packssdw %%mm2, %%mm0\n" /* r1 l1 r0 l0 --> mm0, int_16 */
"movq %%mm0, (%%eax)\n"
"movq %%mm2, 8(%%eax)\n"
"addl $8, %%eax\n"
"addl $8, %%ebx\n"
"addl $8, %%edx\n"
"decl %%ecx\n"
"jnz .loop1\n"
"popl %%ecx\n"
"femms\n"
: "=a" (s16_samples), "=b" (left), "=d" (right)
: "a" (s16_samples), "b" (left), "d" (right));
}
This diff is collapsed.
......@@ -2,7 +2,7 @@
* ac3_exponent.c: ac3 exponent calculations
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_exponent.c,v 1.24 2001/05/14 15:58:04 reno Exp $
* $Id: ac3_exponent.c,v 1.25 2001/05/15 16:19:42 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@zoy.org>
......@@ -22,6 +22,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <string.h> /* memcpy(), memset() */
......@@ -38,136 +42,13 @@
#include "audio_output.h"
#include "ac3_imdct.h"
#include "ac3_downmix.h"
#include "ac3_decoder.h"
#include "ac3_internal.h"
static const s16 exps_1[128] =
{
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
0, 0, 0
};
static const s16 exps_2[128] =
{
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
0, 0, 0
};
static const s16 exps_3[128] =
{
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
0, 0, 0
};
#define UNPACK_FBW 1
#define UNPACK_CPL 2
#define UNPACK_LFE 4
static __inline__ int exp_unpack_ch (ac3dec_t * p_ac3dec, u16 type,
u16 expstr, u16 ngrps, u16 initial_exp,
u16 exps[], u16 * dest)
{
u16 i,j;
s16 exp_acc;
if (expstr == EXP_REUSE)
{
return 0;
}
/* Handle the initial absolute exponent */
exp_acc = initial_exp;
j = 0;
/* In the case of a fbw channel then the initial absolute values is
* also an exponent */
if (type != UNPACK_CPL)
{
dest[j++] = exp_acc;
}
/* Loop through the groups and fill the dest array appropriately */
switch (expstr)
{
case EXP_D15: /* 1 */
for (i = 0; i < ngrps; i++)
{
if (exps[i] > 124)
{
intf_ErrMsg ( "ac3dec error: invalid exponent" );
return 1;
}
exp_acc += (exps_1[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
exp_acc += (exps_2[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
exp_acc += (exps_3[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
}
break;
case EXP_D25: /* 2 */
for (i = 0; i < ngrps; i++)
{
if (exps[i] > 124)
{
intf_ErrMsg ( "ac3dec error: invalid exponent" );
return 1;
}
exp_acc += (exps_1[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_2[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_3[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
}
break;
case EXP_D45: /* 3 */
for (i = 0; i < ngrps; i++)
{
if (exps[i] > 124)
{
intf_ErrMsg ( "ac3dec error: invalid exponent" );
return 1;
}
exp_acc += (exps_1[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_2[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_3[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
}
break;
}
return 0;
}
#include "ac3_exponent.h"
int exponent_unpack (ac3dec_t * p_ac3dec)
{
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
int imdct_init_sse (imdct_t * p_imdct);
void imdct_do_512_sse(imdct_t * p_imdct, float data[], float delay[]);
void imdct_do_512_nol_sse(imdct_t * p_imdct, float data[], float delay[]);
......@@ -2,7 +2,7 @@
* ac3_internals.h: needed by the ac3 decoder
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* $Id: ac3_internal.h,v 1.9 2001/05/14 15:58:04 reno Exp $
* $Id: ac3_internal.h,v 1.10 2001/05/15 16:19:42 sam Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
*
......@@ -36,9 +36,6 @@
/* ac3_bit_allocate.c */
void bit_allocate (ac3dec_t *);
/* ac3_downmix.c */
void downmix_init (downmix_t * p_downmix);
/* ac3_exponent.c */
int exponent_unpack (ac3dec_t *);
......@@ -56,3 +53,4 @@ void parse_auxdata (ac3dec_t *);
/* ac3_rematrix.c */
void rematrix (ac3dec_t *);
This diff is collapsed.
This diff is collapsed.
......@@ -2,7 +2,7 @@
* ac3_parse.c: ac3 parsing procedures
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_parse.c,v 1.22 2001/05/14 15:58:04 reno Exp $
* $Id: ac3_parse.c,v 1.23 2001/05/15 16:19:42 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
......@@ -23,6 +23,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "defs.h"
#include <string.h> /* memset() */
......@@ -33,12 +36,15 @@
#include "threads.h"
#include "mtime.h"
#include "intf_msg.h"
#include "stream_control.h"
#include "input_ext-dec.h"
#include "audio_output.h"
#include "intf_msg.h"
#include "ac3_imdct.h"
#include "ac3_downmix.h"
#include "ac3_decoder.h"
#include "ac3_decoder_thread.h" /* ac3dec_thread_t */
......@@ -871,7 +877,6 @@ static void parse_audblk_stats (ac3dec_t * p_ac3dec)
for(i=0;i<p_ac3dec->bsi.nfchans;i++)
intf_ErrMsg ("%1d",p_ac3dec->audblk.blksw[i]);
intf_ErrMsg ("]");
intf_ErrMsg ("\n");
}
#endif
This diff is collapsed.
This diff is collapsed.
......@@ -2,7 +2,7 @@
* aout_u8.c: 8 bit unsigned audio output functions
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: aout_u8.c,v 1.4 2001/05/06 04:32:02 sam Exp $
* $Id: aout_u8.c,v 1.5 2001/05/15 16:19:42 sam Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
*
......@@ -105,8 +105,6 @@ void aout_U8StereoThread( aout_thread_t * p_aout )
int i_fifo;
long l_buffer, l_buffer_limit, l_bytes;
intf_DbgMsg("adec debug: running audio output U8_S_thread (%p) (pid == %i)", p_aout, getpid());
/* As the s32_buffer was created with calloc(), we don't have to set this
* memory to zero and we can immediately jump into the thread's loop */
while ( ! p_aout->b_die )
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment