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
......@@ -149,6 +155,8 @@ also accepts a lot of parameters to customize its behaviour.
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:
......@@ -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 ) )
{
return( 0 );
}
if( TestMethod( IDCT_METHOD_VAR, "idctaltivec" ) )
{
return( 999 );
}
else
{
/* The Altivec iDCT is deactivated until it really works */
return( 0 /* 200 */ );
}
}
else
{
return( 0 );
}
}
/*****************************************************************************
......
......@@ -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 ) )
{
return( 0 );
}
if( TestMethod( IDCT_METHOD_VAR, "idctmmx" ) )
{
return( 999 );
}
else
{
return( 150 );
}
}
else
{
return( 0 );
}
}
/*****************************************************************************
......
......@@ -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 ) )
{
return( 0 );
}
if( TestMethod( IDCT_METHOD_VAR, "idctmmxext" ) )
{
return( 999 );
}
else
{
return( 200 );
}
}
else
{
return( 0 );
}
}
/*****************************************************************************
......
###############################################################################
# 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);
......@@ -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 ) )
{
return( 0 );
}
if( TestMethod( MOTION_METHOD_VAR, "motionmmx" ) )
{
return( 999 );
}
else
{
return( 150 );
}
}
else
{
return( 0 );
}
}
......@@ -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 ) )
{
return( 0 );
}
if( TestMethod( MOTION_METHOD_VAR, "motionmmxext" ) )
{
return( 999 );
}
else
{
return( 200 );
}
}
else
{
return( 0 );
}
}
......@@ -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 ) )
{
return( 0 );
}
if( TestMethod( YUV_METHOD_VAR, "yuvmmx" ) )
{
return( 999 );
}
else
{
return( 100 );
}
}
else
{
return( 0 );
}
}
/*****************************************************************************
......
......@@ -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))
{
......@@ -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.
......@@ -2,7 +2,7 @@
* ac3_imdct.c: ac3 DCT
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_imdct.c,v 1.19 2001/05/14 15:58:04 reno Exp $
* $Id: ac3_imdct.c,v 1.20 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> /* memcpy() */
......@@ -38,32 +41,20 @@
#include "stream_control.h"
#include "input_ext-dec.h"
#include "ac3_imdct.h"
#include "ac3_downmix.h"
#include "ac3_decoder.h"
#include "ac3_imdct_c.h" /* imdct_init_c */
#include "ac3_imdct_sse.h" /* imdct_init_sse */
#include "tests.h" /* TestCPU */
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
void imdct_init(imdct_t * p_imdct)
{
int i;
float scale = 181.019;
#if 0
if ( TestCPU (CPU_CAPABILITY_SSE) )
{
imdct_init_sse (p_imdct);
}
else
#endif
{
imdct_init_c (p_imdct);
}
p_imdct->pf_imdct_init( p_imdct );
/* More twiddle factors to turn IFFT into IMDCT */
for (i=0; i < 64; i++) {
......@@ -85,11 +76,11 @@ void imdct (ac3dec_t * p_ac3dec, s16 * buffer)
/* test if dm in frequency is doable */
if (!(doable = p_ac3dec->audblk.blksw[0]))
{
do_imdct = p_ac3dec->imdct.imdct_do_512;
do_imdct = p_ac3dec->imdct.pf_imdct_512;
}
else
{
do_imdct = imdct_do_256; /* There is only a C function */
do_imdct = p_ac3dec->imdct.pf_imdct_256;
}
/* downmix in the frequency domain if all the channels
......@@ -109,19 +100,19 @@ void imdct (ac3dec_t * p_ac3dec, s16 * buffer)
switch(p_ac3dec->bsi.acmod)
{
case 7: /* 3/2 */
p_ac3dec->downmix.downmix_3f_2r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
p_ac3dec->downmix.pf_downmix_3f_2r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
break;
case 6: /* 2/2 */
p_ac3dec->downmix.downmix_2f_2r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
p_ac3dec->downmix.pf_downmix_2f_2r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
break;
case 5: /* 3/1 */
p_ac3dec->downmix.downmix_3f_1r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
p_ac3dec->downmix.pf_downmix_3f_1r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
break;
case 4: /* 2/1 */
p_ac3dec->downmix.downmix_2f_1r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
p_ac3dec->downmix.pf_downmix_2f_1r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
break;
case 3: /* 3/0 */
p_ac3dec->downmix.downmix_3f_0r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
p_ac3dec->downmix.pf_downmix_3f_0r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
break;
case 2:
break;
......@@ -132,7 +123,7 @@ void imdct (ac3dec_t * p_ac3dec, s16 * buffer)
// center = samples[ac3_config.dual_mono_ch_sel];
do_imdct(&p_ac3dec->imdct, center, p_ac3dec->imdct.delay[0]); /* no downmix*/
p_ac3dec->downmix.stream_sample_1ch_to_s16 (buffer, center);
p_ac3dec->downmix.pf_stream_sample_1ch_to_s16 (buffer, center);
return;
break;
......@@ -140,7 +131,7 @@ void imdct (ac3dec_t * p_ac3dec, s16 * buffer)
do_imdct (&p_ac3dec->imdct, p_ac3dec->samples[0], p_ac3dec->imdct.delay[0]);
do_imdct (&p_ac3dec->imdct, p_ac3dec->samples[1], p_ac3dec->imdct.delay[1]);
p_ac3dec->downmix.stream_sample_2ch_to_s16(buffer, p_ac3dec->samples[0], p_ac3dec->samples[1]);
p_ac3dec->downmix.pf_stream_sample_2ch_to_s16(buffer, p_ac3dec->samples[0], p_ac3dec->samples[1]);
} else {
/* imdct and then downmix
......@@ -150,9 +141,9 @@ void imdct (ac3dec_t * p_ac3dec, s16 * buffer)
{
if (p_ac3dec->audblk.blksw[i])
/* There is only a C function */
imdct_do_256_nol (&p_ac3dec->imdct, p_ac3dec->samples[i], p_ac3dec->imdct.delay1[i]);
p_ac3dec->imdct.pf_imdct_256_nol (&p_ac3dec->imdct, p_ac3dec->samples[i], p_ac3dec->imdct.delay1[i]);
else
p_ac3dec->imdct.imdct_do_512_nol (&p_ac3dec->imdct, p_ac3dec->samples[i], p_ac3dec->imdct.delay1[i]);
p_ac3dec->imdct.pf_imdct_512_nol (&p_ac3dec->imdct, p_ac3dec->samples[i], p_ac3dec->imdct.delay1[i]);
}
/* mix the sample, overlap */
......
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.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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