summaryrefslogtreecommitdiffstats
path: root/mpg123_artsplugin
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commite2de64d6f1beb9e492daf5b886e19933c1fa41dd (patch)
tree9047cf9e6b5c43878d5bf82660adae77ceee097a /mpg123_artsplugin
downloadtdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.tar.gz
tdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'mpg123_artsplugin')
-rw-r--r--mpg123_artsplugin/Makefile.am25
-rwxr-xr-xmpg123_artsplugin/compare_to_original.sh3
-rw-r--r--mpg123_artsplugin/configure.in.in92
-rw-r--r--mpg123_artsplugin/distexclude24
-rw-r--r--mpg123_artsplugin/dxhead.c250
-rw-r--r--mpg123_artsplugin/dxhead.h77
-rw-r--r--mpg123_artsplugin/mpg123/Makefile.am34
-rw-r--r--mpg123_artsplugin/mpg123/README42
-rw-r--r--mpg123_artsplugin/mpg123/audio.c298
-rw-r--r--mpg123_artsplugin/mpg123/audio.h106
-rw-r--r--mpg123_artsplugin/mpg123/buffer.c245
-rw-r--r--mpg123_artsplugin/mpg123/buffer.h13
-rw-r--r--mpg123_artsplugin/mpg123/common.c921
-rw-r--r--mpg123_artsplugin/mpg123/common.h19
-rw-r--r--mpg123_artsplugin/mpg123/dct36_3dnow.s499
-rw-r--r--mpg123_artsplugin/mpg123/dct64.c168
-rw-r--r--mpg123_artsplugin/mpg123/dct64_3dnow.s706
-rw-r--r--mpg123_artsplugin/mpg123/dct64_MMX.s836
-rw-r--r--mpg123_artsplugin/mpg123/dct64_i386.c329
-rw-r--r--mpg123_artsplugin/mpg123/dct64_i486-a.s831
-rw-r--r--mpg123_artsplugin/mpg123/dct64_i486-b.c140
-rw-r--r--mpg123_artsplugin/mpg123/dct64_i486.c322
-rw-r--r--mpg123_artsplugin/mpg123/decode.c223
-rw-r--r--mpg123_artsplugin/mpg123/decode_2to1.c233
-rw-r--r--mpg123_artsplugin/mpg123/decode_3dnow.s279
-rw-r--r--mpg123_artsplugin/mpg123/decode_4to1.c240
-rw-r--r--mpg123_artsplugin/mpg123/decode_MMX.s108
-rw-r--r--mpg123_artsplugin/mpg123/decode_i386.c257
-rw-r--r--mpg123_artsplugin/mpg123/decode_i486.c250
-rw-r--r--mpg123_artsplugin/mpg123/decode_i586.s323
-rw-r--r--mpg123_artsplugin/mpg123/decode_ntom.c290
-rw-r--r--mpg123_artsplugin/mpg123/genre.h263
-rw-r--r--mpg123_artsplugin/mpg123/getbits.c116
-rw-r--r--mpg123_artsplugin/mpg123/getbits.h33
-rw-r--r--mpg123_artsplugin/mpg123/httpget.c481
-rw-r--r--mpg123_artsplugin/mpg123/huffman.h332
-rw-r--r--mpg123_artsplugin/mpg123/l2tables.h154
-rw-r--r--mpg123_artsplugin/mpg123/layer1.c157
-rw-r--r--mpg123_artsplugin/mpg123/layer2.c318
-rw-r--r--mpg123_artsplugin/mpg123/layer3.c1880
-rw-r--r--mpg123_artsplugin/mpg123/mpg123.h465
-rw-r--r--mpg123_artsplugin/mpg123/readers.c618
-rw-r--r--mpg123_artsplugin/mpg123/tabinit.c139
-rw-r--r--mpg123_artsplugin/mpg123/tabinit_MMX.s160
-rw-r--r--mpg123_artsplugin/mpg123/vbrhead.c79
-rw-r--r--mpg123_artsplugin/mpg123/xfermem.c275
-rw-r--r--mpg123_artsplugin/mpg123/xfermem.h60
-rw-r--r--mpg123_artsplugin/mpg123PlayObject.mcopclass6
-rw-r--r--mpg123_artsplugin/mpg123PlayObject_impl.cpp675
-rw-r--r--mpg123_artsplugin/mpg123PlayObject_impl.h111
-rw-r--r--mpg123_artsplugin/mpg123arts.idl12
51 files changed, 14517 insertions, 0 deletions
diff --git a/mpg123_artsplugin/Makefile.am b/mpg123_artsplugin/Makefile.am
new file mode 100644
index 00000000..15cf345b
--- /dev/null
+++ b/mpg123_artsplugin/Makefile.am
@@ -0,0 +1,25 @@
+# $Id$
+
+INCLUDES= -I$(kde_includes)/arts $(all_includes)
+
+noinst_HEADERS = mpg123PlayObject_impl.h
+
+lib_LTLIBRARIES = libmpg123arts.la
+libmpg123arts_la_COMPILE_FIRST = mpg123arts.h
+libmpg123arts_la_SOURCES = mpg123arts.cc mpg123PlayObject_impl.cpp dxhead.c
+libmpg123arts_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined
+libmpg123arts_la_LIBADD = -lkmedia2_idl -lsoundserver_idl -lartsflow mpg123/libmpg123.la
+libmpg123arts_la_METASOURCES = AUTO
+
+mpg123arts.mcoptype: mpg123arts.h
+mpg123arts.mcopclass: mpg123arts.h
+mpg123arts.cc mpg123arts.h: $(srcdir)/mpg123arts.idl $(MCOPIDL)
+ $(MCOPIDL) -t -I$(kde_includes)/arts $(srcdir)/mpg123arts.idl
+
+mcoptypedir = $(libdir)/mcop
+mcoptype_DATA = mpg123arts.mcoptype mpg123arts.mcopclass
+
+mcopclassdir = $(libdir)/mcop/Arts
+mcopclass_DATA = mpg123PlayObject.mcopclass
+
+SUBDIRS = mpg123 .
diff --git a/mpg123_artsplugin/compare_to_original.sh b/mpg123_artsplugin/compare_to_original.sh
new file mode 100755
index 00000000..b9787084
--- /dev/null
+++ b/mpg123_artsplugin/compare_to_original.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+diff \
+"--exclude-from=distexclude" -Bbdu1 ~/cvs/mpg123/mpg123 mpg123 &> ~/mpg.diff
diff --git a/mpg123_artsplugin/configure.in.in b/mpg123_artsplugin/configure.in.in
new file mode 100644
index 00000000..33da7fa9
--- /dev/null
+++ b/mpg123_artsplugin/configure.in.in
@@ -0,0 +1,92 @@
+dnl ============
+dnl Machine type
+dnl ============
+
+ARCH_CFLAGS="$CFLAGS -O2 -funroll-all-loops -finline-functions -ffast-math"
+
+case "$ARCH_TYPE" in
+ i486)
+ AC_DEFINE(ARCH_486, 1, [WE ARE BUILDING FOR A 486])
+ OPTIMIZED_ARCH="YES"
+ ;;
+ i586)
+ AC_DEFINE(ARCH_586, 1, [WE ARE BUILDING FOR A PENTIUM])
+ OPTIMIZED_ARCH="YES"
+ ;;
+ i686)
+ AC_DEFINE(ARCH_686, 1, [WE ARE BUILDING FOR A PPRO])
+ OPTIMIZED_ARCH="YES"
+ #EXTRA_CPU_CFLAGS=$(if $CC -march=i686 -S -o /dev/null -xc /dev/null > /dev/null; then echo "-march=i686"; fi)
+ ;;
+ ppc)
+ AC_DEFINE(ARCH_PPC, 1, [WE ARE BUILDING FOR A POWERPC])
+ OPTIMIZED_ARCH="YES"
+ ;;
+ sun4u)
+ AC_DEFINE(ARCH_ULTRA, 1, [WE ARE BUILDING FOR A SUN ULTRASPARC])
+ # Is there mpg123 optimization for UltraSparc?
+ ;;
+esac
+
+# ARCH_X86
+if test "$ARCH_TYPE" = "i486" || test "$ARCH_TYPE" = "i586" || test "$ARCH_TYPE" = "i686"; then
+ MPG123_PLAT_LIB="$MPG123_PLAT_LIB libmpx86.la"
+fi
+# ARCH_486
+if test "$ARCH_TYPE" = "i486"; then
+ MPG123_PLAT_LIB="$MPG123_PLAT_LIB libmp486.la"
+ ARCH_CFLAGS="$ARCH_CFLAGS -DROT_I386 -DI386_ASSEM -DI486_OPT -DLINUX -DREAL_IS_FLOAT"
+fi
+# ARCH_586
+if test "$ARCH_TYPE" = "i586" -a "$MMX_SUPPORT" = "no"; then
+ MPG123_PLAT_LIB="$MPG123_PLAT_LIB libmp586.la"
+ ARCH_CFLAGS="$ARCH_CFLAGS -DROT_I386 -DI386_ASSEM -DPENTIUM_OPT -DLINUX -DREAL_IS_FLOAT"
+fi
+# ARCH_586_MMX
+if test "$ARCH_TYPE" = "i586" -a "$MMX_SUPPORT" = "yes"; then
+ ARCH_CFLAGS="$ARCH_CFLAGS -DROT_I386 -DI386_ASSEM -DPENTIUM_OPT -DLINUX -DREAL_IS_FLOAT"
+ MPG123_PLAT_LIB=libmp586mmx.la
+fi
+# ARCH_686
+if test "$ARCH_TYPE" = "i686" -a "$MMX_SUPPORT" = "no"; then
+ ARCH_CFLAGS="$ARCH_CFLAGS -DROT_I386 -DI386_ASSEM -DPENTIUM_OPT -DLINUX -DREAL_IS_FLOAT -march=pentiumpro"
+ MPG123_PLAT_LIB=libmp686.la
+fi
+# ARCH_686_MMX
+if test "$ARCH_TYPE" = "i686" -a "$MMX_SUPPORT" = "yes"; then
+ ARCH_CFLAGS="$ARCH_CFLAGS -DROT_I386 -DI386_ASSEM -DPENTIUM_OPT -DUSE_MMX -DLINUX -DREAL_IS_FLOAT -march=pentiumpro"
+ MPG123_PLAT_LIB=libmp686mmx.la
+fi
+# ARCH_PPC
+if test "$ARCH_TYPE" = "ppc"; then
+ MPG123_PLAT_LIB=libmpppc.la
+fi
+# ARCH_ULTRA
+if test "$ARCH_TYPE" = "sun4u"; then
+ :
+ # nothing for now
+fi
+# ARCH_PLAIN
+if test -z "$OPTIMIZED_ARCH"; then
+ MPG123_PLAT_LIB=libmpplain.la
+fi
+
+AC_SUBST(ARCH_CFLAGS)
+AC_SUBST(MPG123_PLAT_LIB)
+
+if test "$kde_mpeglib_compiles" = "yes"
+then
+DO_NOT_COMPILE="$DO_NOT_COMPILE mpg123_artsplugin"
+fi
+
+# this is run after libtool configure parts, which set AS to as
+# which is the wrong one for us. E.g. libtool doesn't recognize that as
+# tag. So we unset it here, so the below macro can set it.
+save_AS=$AS
+unset AS
+ifdef([AM_PROG_AS],[AM_PROG_AS],[])
+#if the macro did set something usefull fallback.
+test -z "$AS" && AS=$save_AS
+#and if AS was set to as by the macro, and we have a saved value,
+#it's likely it contains a better guess (or it's also as)
+test "x$AS" = xas && test -n "$save_AS" && AS=$save_AS
diff --git a/mpg123_artsplugin/distexclude b/mpg123_artsplugin/distexclude
new file mode 100644
index 00000000..9e9f6792
--- /dev/null
+++ b/mpg123_artsplugin/distexclude
@@ -0,0 +1,24 @@
+audio_*.c
+README*
+control_*.[ch]
+precompiled
+mpglib
+jukebox
+mpg123.[1c]
+Makefile*
+BENCHMARKING
+BUGS
+CHANGES
+COPYING
+CVS
+INSTALL
+JUKEBOX
+TODO
+tools
+playlist.[ch]
+wav.c
+version.h
+term.[ch]
+getlopt.[ch]
+.cvsignore
+equaliz*
diff --git a/mpg123_artsplugin/dxhead.c b/mpg123_artsplugin/dxhead.c
new file mode 100644
index 00000000..fb056055
--- /dev/null
+++ b/mpg123_artsplugin/dxhead.c
@@ -0,0 +1,250 @@
+/*---- DXhead.c --------------------------------------------
+
+
+decoder MPEG Layer III
+
+handle Xing header
+
+mod 12/7/98 add vbr scale
+
+Copyright 1998 Xing Technology Corp.
+-----------------------------------------------------------*/
+#include <stdlib.h>
+#include <unistd.h>
+#include <float.h>
+#include <math.h>
+#include "mpg123/mpg123.h"
+#include "dxhead.h"
+
+/* 4 Xing
+ * 4 flags
+ * 4 frames
+ * 4 bytes
+ * 100 toc
+ */
+
+/*-------------------------------------------------------------*/
+static int ExtractI4(unsigned char *buf)
+{
+
+ int x;
+
+/* big endian extract */
+
+ x = buf[0];
+
+ x <<= 8;
+
+ x |= buf[1];
+
+ x <<= 8;
+
+ x |= buf[2];
+
+ x <<= 8;
+
+ x |= buf[3];
+
+
+ return x;
+
+}
+
+/*-------------------------------------------------------------*/
+int mpg123_get_xing_header(XHEADDATA * X, unsigned char *buf)
+{
+
+ int i, head_flags;
+
+ int h_id, h_mode, h_sr_index;
+
+ static int sr_table[4] =
+ {44100, 48000, 32000, 99999};
+
+
+/* get Xing header data */
+
+
+ X->flags = 0; /* clear to null incase fail */
+ X->toc = NULL;
+
+
+/* get selected MPEG header data */
+ h_id = (buf[1] >> 3) & 1;
+
+ h_sr_index = (buf[2] >> 2) & 3;
+
+ h_mode = (buf[3] >> 6) & 3;
+
+
+
+/* determine offset of header */
+ if (h_id)
+ { /* mpeg1 */
+
+ if (h_mode != 3) {
+ buf += (32 + 4);
+
+}
+
+ else
+ buf += (17 + 4);
+
+ }
+
+ else
+ { /* mpeg2 */
+
+ if (h_mode != 3)
+ buf += (17 + 4);
+
+ else
+ buf += (9 + 4);
+
+ }
+
+
+ if (buf[0] != 'X')
+ return 0; /* fail */
+
+ if (buf[1] != 'i')
+ return 0; /* header not found */
+
+ if (buf[2] != 'n')
+ return 0;
+
+ if (buf[3] != 'g')
+ return 0;
+
+ buf += 4;
+
+
+ X->h_id = h_id;
+
+ X->samprate = sr_table[h_sr_index];
+
+ if (h_id == 0)
+ X->samprate >>= 1;
+
+
+ head_flags = X->flags = ExtractI4(buf);
+ buf += 4; /* get flags */
+
+
+ if (head_flags & FRAMES_FLAG)
+ {
+ X->frames = ExtractI4(buf);
+ buf += 4;
+ }
+
+ if (head_flags & BYTES_FLAG)
+ {
+ X->bytes = ExtractI4(buf);
+ buf += 4;
+ }
+
+
+ if (head_flags & TOC_FLAG)
+ {
+
+ X->toc = malloc(100);
+ if (X->toc != NULL)
+ {
+
+ for (i = 0; i < 100; i++)
+ X->toc[i] = buf[i];
+
+ }
+
+ buf += 100;
+
+ }
+
+
+ X->vbr_scale = -1;
+
+ if (head_flags & VBR_SCALE_FLAG)
+ {
+ X->vbr_scale = ExtractI4(buf);
+ buf += 4;
+ }
+
+
+/*if( X->toc != NULL ) {
+ *for(i=0;i<100;i++) {
+ * if( (i%10) == 0 ) printf("\n");
+ * printf(" %3d", (int)(X->toc[i]));
+ *}
+ *}
+ */
+
+ return 1; /* success */
+
+}
+
+/*-------------------------------------------------------------*/
+int mpg123_seek_point(unsigned char TOC[100], int file_bytes, float percent)
+{
+
+/* interpolate in TOC to get file seek point in bytes */
+ int a, seekpoint;
+
+ float fa, fb, fx;
+
+
+
+ if (percent < 0.0f)
+ percent = 0.0f;
+
+ if (percent > 100.0f)
+ percent = 100.0f;
+
+
+ a = (int) percent;
+
+ if (a > 99)
+ a = 99;
+
+ fa = TOC[a];
+
+ if (a < 99)
+ {
+
+ fb = TOC[a + 1];
+
+ }
+
+ else
+ {
+
+ fb = 256.0f;
+
+ }
+
+
+
+ fx = fa + (fb - fa) * (percent - a);
+
+
+ seekpoint = (int) ((1.0f / 256.0f) * fx * file_bytes);
+
+
+
+ return seekpoint;
+
+}
+
+/*-------------------------------------------------------------*/
+int mpg123_stream_check_for_xing_header(struct frame *fr, XHEADDATA * xhead)
+{
+ unsigned char *head_data;
+ int ret;
+
+ lseek(rd->filept, -(fr->framesize + 4), SEEK_CUR);
+ head_data = malloc(fr->framesize + 4);
+ read(rd->filept,head_data, fr->framesize +4); /* now read the rest */
+ ret = mpg123_get_xing_header(xhead, head_data);
+ free(head_data);
+ return ret;
+}
+
diff --git a/mpg123_artsplugin/dxhead.h b/mpg123_artsplugin/dxhead.h
new file mode 100644
index 00000000..16a6a0fc
--- /dev/null
+++ b/mpg123_artsplugin/dxhead.h
@@ -0,0 +1,77 @@
+/*---- DXhead.h --------------------------------------------
+
+
+decoder MPEG Layer III
+
+handle Xing header
+
+
+Copyright 1998 Xing Technology Corp.
+-----------------------------------------------------------*/
+/* A Xing header may be present in the ancillary
+ * data field of the first frame of an mp3 bitstream
+ * The Xing header (optionally) contains
+ * frames total number of audio frames in the bitstream
+ * bytes total number of bytes in the bitstream
+ * toc table of contents
+
+ * toc (table of contents) gives seek points
+ * for random access
+ * the ith entry determines the seek point for
+ * i-percent duration
+ * seek point in bytes = (toc[i]/256.0) * total_bitstream_bytes
+ * e.g. half duration seek point = (toc[50]/256.0) * total_bitstream_bytes
+ */
+
+#define FRAMES_FLAG 0x0001
+#define BYTES_FLAG 0x0002
+#define TOC_FLAG 0x0004
+#define VBR_SCALE_FLAG 0x0008
+
+#define FRAMES_AND_BYTES (FRAMES_FLAG | BYTES_FLAG)
+
+/* structure to receive extracted header
+ * toc may be NULL
+ */
+typedef struct
+{
+
+ int h_id; /* from MPEG header, 0=MPEG2, 1=MPEG1 */
+
+ int samprate; /* determined from MPEG header */
+
+ int flags; /* from Xing header data */
+
+ int frames; /* total bit stream frames from Xing header data */
+
+ int bytes; /* total bit stream bytes from Xing header data */
+
+ int vbr_scale; /* encoded vbr scale from Xing header data */
+
+ unsigned char *toc; /* pointer to unsigned char toc_buffer[100] */
+
+ /* may be NULL if toc not desired */
+}
+XHEADDATA;
+
+
+
+int mpg123_get_xing_header(XHEADDATA * X, unsigned char *buf);
+
+/* return 0=fail, 1=success
+ * X structure to receive header data (output)
+ * buf bitstream input
+ */
+
+int mpg123_seek_point(unsigned char TOC[100], int file_bytes, float percent);
+
+/* return seekpoint in bytes (may be at eof if percent=100.0)
+ * TOC = table of contents from Xing header
+ * file_bytes = number of bytes in mp3 file
+ * percent = play time percentage of total playtime. May be
+ * fractional (e.g. 87.245)
+ */
+int mpg123_stream_check_for_xing_header(struct frame *fr, XHEADDATA * xhead);
+
+
+
diff --git a/mpg123_artsplugin/mpg123/Makefile.am b/mpg123_artsplugin/mpg123/Makefile.am
new file mode 100644
index 00000000..2243efc2
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/Makefile.am
@@ -0,0 +1,34 @@
+# $Id$
+
+EXTRA_DIST = README decode_i386.c decode_i586.s dct64_i386.c decode.c \
+ dct64.c audio.h
+
+# -I$(ROOT_DIR)/app
+INCLUDES = -I$(top_srcdir)/include
+COMMON_CFLAGS = -D_REENTRANT -DNOXFERMEM -DNO_EQUALIZER \
+ -DNO_DECODE_AUDIO -DNO_DECODE_FILE -DNO_DECODE_WAV
+
+libmpg123_la_SOURCES = common.c decode_2to1.c decode_4to1.c decode_ntom.c \
+ layer1.c layer2.c layer3.c readers.c \
+ httpget.c getbits.c tabinit.c xfermem.c vbrhead.c buffer.c audio.c
+
+noinst_HEADERS = huffman.h mpg123.h l2tables.h audio.h common.h \
+ genre.h getbits.h xfermem.h buffer.h
+
+EXTRA_LTLIBRARIES = libmp486.la libmp586.la libmp586mmx.la libmpppc.la libmp686.la libmp686mmx.la libmpplain.la
+libmp486_la_SOURCES = decode_i386.c dct64_i386.c decode_i486.c dct64_i486.c
+libmp586_la_SOURCES = decode_i386.c dct64_i386.c decode_i586.s
+libmp586mmx_la_SOURCES = decode_i386.c dct64_MMX.s decode_MMX.s tabinit_MMX.s
+libmp686_la_SOURCES = decode_i386.c dct64_i386.c decode_i586.s
+libmp686mmx_la_SOURCES = decode_i386.c dct64_MMX.s decode_MMX.s tabinit_MMX.s
+libmpppc_la_SOURCES = decode.c dct64.c
+libmpplain_la_SOURCES = decode.c dct64.c
+
+AM_CFLAGS = $(COMMON_CFLAGS) $(ARCH_CFLAGS)
+
+lib_LTLIBRARIES = libmpg123.la
+libmpg123_la_LDFLAGS = -module -avoid-version
+libmpg123_la_LIBADD = ./$(MPG123_PLAT_LIB)
+libmpg123_la_DEPENDENCIES = ./$(MPG123_PLAT_LIB)
+
+
diff --git a/mpg123_artsplugin/mpg123/README b/mpg123_artsplugin/mpg123/README
new file mode 100644
index 00000000..383b694b
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/README
@@ -0,0 +1,42 @@
+$Id$
+
+Keeping in mind this is a slightly modified version of mpg123 (available
+at http://www.mpg123.de/), and somewhat trimmed down to not include any of
+the front ends, I present you with this:
+
+Maybe I change the policy to GPL in the future ...
+But at the moment this is the policy:
+
+Copyright (c) 1995-99 by Michael Hipp, all rights reserved.
+Parts of the software are contributed by other people, please
+refer to the README file for details!
+
+DISTRIBUTION:
+This software may be distributed freely, provided that it is
+distributed in its entirety, without modifications, and with
+the original copyright notice and license included. You may
+distribute your own seperate patches together with this software
+package or a modified package if you always include a pointer
+where to get the original unmodified package. In this case
+you must inform the author about the modified package.
+The software may not be sold for profit or as "hidden" part of
+another software, but it may be included with collections
+of other software, such as CD-ROM images of FTP servers and
+similar, provided that this software is not a significant part
+of that collection.
+Precompiled binaries of this software may be distributed in the
+same way, provided that this copyright notice and license is
+included without modification.
+
+USAGE:
+This software may be used freely, provided that the original
+author is always credited. If you intend to use this software
+as a significant part of business (for-profit) activities, you
+have to contact the author first. Also, any usage that is not
+covered by this license requires the explicit permission of
+the author.
+
+DISCLAIMER:
+This software is provided as-is. The author can not be held
+liable for any damage that might arise from the use of this
+software. Use it at your own risk.
diff --git a/mpg123_artsplugin/mpg123/audio.c b/mpg123_artsplugin/mpg123/audio.c
new file mode 100644
index 00000000..b37c6659
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/audio.c
@@ -0,0 +1,298 @@
+
+#include "mpg123.h"
+
+void audio_info_struct_init(struct audio_info_struct *ai)
+{
+#ifdef AUDIO_USES_FD
+ ai->fn = -1;
+#endif
+#ifdef SGI
+#if 0
+ ALconfig config;
+ ALport port;
+#endif
+#endif
+ ai->rate = -1;
+ ai->gain = -1;
+ ai->output = -1;
+#ifdef ALSA
+ ai->handle = NULL;
+ ai->alsa_format.format = -1;
+ ai->alsa_format.rate = -1;
+ ai->alsa_format.channels = -1;
+#endif
+ ai->device = NULL;
+ ai->channels = -1;
+ ai->format = -1;
+}
+
+#define NUM_CHANNELS 2
+#define NUM_ENCODINGS 6
+#define NUM_RATES 10
+
+struct audio_name audio_val2name[NUM_ENCODINGS+1] = {
+ { AUDIO_FORMAT_SIGNED_16 , "signed 16 bit" , "s16 " } ,
+ { AUDIO_FORMAT_UNSIGNED_16, "unsigned 16 bit" , "u16 " } ,
+ { AUDIO_FORMAT_UNSIGNED_8 , "unsigned 8 bit" , "u8 " } ,
+ { AUDIO_FORMAT_SIGNED_8 , "signed 8 bit" , "s8 " } ,
+ { AUDIO_FORMAT_ULAW_8 , "mu-law (8 bit)" , "ulaw " } ,
+ { AUDIO_FORMAT_ALAW_8 , "a-law (8 bit)" , "alaw " } ,
+ { -1 , NULL }
+};
+
+#if 0
+static char *channel_name[NUM_CHANNELS] =
+ { "mono" , "stereo" };
+#endif
+
+static int channels[NUM_CHANNELS] = { 1 , 2 };
+static int rates[NUM_RATES] = {
+ 8000, 11025, 12000,
+ 16000, 22050, 24000,
+ 32000, 44100, 48000,
+ 8000 /* 8000 = dummy for user forced */
+
+};
+static int encodings[NUM_ENCODINGS] = {
+ AUDIO_FORMAT_SIGNED_16,
+ AUDIO_FORMAT_UNSIGNED_16,
+ AUDIO_FORMAT_UNSIGNED_8,
+ AUDIO_FORMAT_SIGNED_8,
+ AUDIO_FORMAT_ULAW_8,
+ AUDIO_FORMAT_ALAW_8
+};
+
+static char capabilities[NUM_CHANNELS][NUM_ENCODINGS][NUM_RATES];
+
+void audio_capabilities(struct audio_info_struct *ai)
+{
+ int fmts;
+ int i,j,k,k1=NUM_RATES-1;
+ struct audio_info_struct ai1 = *ai;
+
+ if (param.outmode != DECODE_AUDIO) {
+ memset(capabilities,1,sizeof(capabilities));
+ return;
+ }
+
+ memset(capabilities,0,sizeof(capabilities));
+ if(param.force_rate) {
+ rates[NUM_RATES-1] = param.force_rate;
+ k1 = NUM_RATES;
+ }
+
+#ifndef NO_DECODE_AUDIO
+ if(audio_open(&ai1) < 0) {
+ perror("audio");
+ exit(1);
+ }
+#endif
+
+ for(i=0;i<NUM_CHANNELS;i++) {
+ for(j=0;j<NUM_RATES;j++) {
+ ai1.channels = channels[i];
+ ai1.rate = rates[j];
+ fmts = audio_get_formats(&ai1);
+ if(fmts < 0)
+ continue;
+ for(k=0;k<NUM_ENCODINGS;k++) {
+ if((fmts & encodings[k]) == encodings[k])
+ capabilities[i][k][j] = 1;
+ }
+ }
+ }
+
+#ifndef NO_DECODE_AUDIO
+ audio_close(&ai1);
+#endif
+
+ if(param.verbose > 1) {
+ fprintf(stderr,"\nAudio capabilities:\n |");
+ for(j=0;j<NUM_ENCODINGS;j++) {
+ fprintf(stderr," %5s |",audio_val2name[j].sname);
+ }
+ fprintf(stderr,"\n --------------------------------------------------------\n");
+ for(k=0;k<k1;k++) {
+ fprintf(stderr," %5d |",rates[k]);
+ for(j=0;j<NUM_ENCODINGS;j++) {
+ if(capabilities[0][j][k]) {
+ if(capabilities[1][j][k])
+ fprintf(stderr," M/S |");
+ else
+ fprintf(stderr," M |");
+ }
+ else if(capabilities[1][j][k])
+ fprintf(stderr," S |");
+ else
+ fprintf(stderr," |");
+ }
+ fprintf(stderr,"\n");
+ }
+ fprintf(stderr,"\n");
+ }
+}
+
+static int rate2num(int r)
+{
+ int i;
+ for(i=0;i<NUM_RATES;i++)
+ if(rates[i] == r)
+ return i;
+ return -1;
+}
+
+
+static int audio_fit_cap_helper(struct audio_info_struct *ai,int rn,int f0,int f2,int c)
+{
+ int i;
+
+ if(rn >= 0) {
+ for(i=f0;i<f2;i++) {
+ if(capabilities[c][i][rn]) {
+ ai->rate = rates[rn];
+ ai->format = encodings[i];
+ ai->channels = channels[c];
+ return 1;
+ }
+ }
+ }
+ return 0;
+
+}
+
+/*
+ * c=num of channels of stream
+ * r=rate of stream
+ */
+void audio_fit_capabilities(struct audio_info_struct *ai,int c,int r)
+{
+ int rn;
+ int f0=0;
+ int save_channels = c;
+ int save_rate = r;
+
+ if(param.force_8bit) {
+ f0 = 2;
+ }
+
+ c--; /* stereo=1 ,mono=0 */
+
+ if(param.force_mono >= 0)
+ c = 0;
+ if(param.force_stereo)
+ c = 1;
+
+ if(param.force_rate) {
+ rn = rate2num(param.force_rate);
+ if(audio_fit_cap_helper(ai,rn,f0,2,c))
+ return;
+ if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+ return;
+
+ if(c == 1 && !param.force_stereo)
+ c = 0;
+ else if(c == 0 && !param.force_mono)
+ c = 1;
+
+ if(audio_fit_cap_helper(ai,rn,f0,2,c))
+ return;
+ if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+ return;
+ }
+ else {
+
+ rn = rate2num(r>>0);
+ if(audio_fit_cap_helper(ai,rn,f0,2,c))
+ return;
+ rn = rate2num(r<<1);
+ if(audio_fit_cap_helper(ai,rn,f0,2,c))
+ return;
+ rn = rate2num(r<<2);
+ if(audio_fit_cap_helper(ai,rn,f0,2,c))
+ return;
+ rn = rate2num(r>>1);
+ if(audio_fit_cap_helper(ai,rn,f0,2,c))
+ return;
+ rn = rate2num(r>>2);
+ if(audio_fit_cap_helper(ai,rn,f0,2,c))
+ return;
+
+ rn = rate2num(r>>0);
+ if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+ return;
+ rn = rate2num(r<<1);
+ if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+ return;
+ rn = rate2num(r<<2);
+ if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+ return;
+ rn = rate2num(r>>1);
+ if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+ return;
+ rn = rate2num(r>>2);
+ if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+ return;
+
+
+ if(c == 1 && !param.force_stereo)
+ c = 0;
+ else if(c == 0 && !param.force_mono)
+ c = 1;
+
+ rn = rate2num(r>>0);
+ if(audio_fit_cap_helper(ai,rn,f0,2,c))
+ return;
+ rn = rate2num(r<<1);
+ if(audio_fit_cap_helper(ai,rn,f0,2,c))
+ return;
+ rn = rate2num(r<<2);
+ if(audio_fit_cap_helper(ai,rn,f0,2,c))
+ return;
+ rn = rate2num(r>>1);
+ if(audio_fit_cap_helper(ai,rn,f0,2,c))
+ return;
+ rn = rate2num(r>>2);
+ if(audio_fit_cap_helper(ai,rn,f0,2,c))
+ return;
+
+ rn = rate2num(r>>0);
+ if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+ return;
+ rn = rate2num(r<<1);
+ if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+ return;
+ rn = rate2num(r<<2);
+ if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+ return;
+ rn = rate2num(r>>1);
+ if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+ return;
+ rn = rate2num(r>>2);
+ if(audio_fit_cap_helper(ai,rn,2,NUM_ENCODINGS,c))
+ return;
+ }
+
+ fprintf(stderr,"\nAudiodevice: No supported audio rate found for %d Hz and %d channels !\n",save_rate,save_channels);
+ fprintf(stderr,"Use '-vv' to list all possible audio rates and\n");
+ fprintf(stderr,"choose a supported rate with the '-r <rate>' option.\n");
+
+ exit(1);
+}
+
+char *audio_encoding_name(int format)
+{
+ int i;
+
+ for(i=0;i<NUM_ENCODINGS;i++) {
+ if(audio_val2name[i].val == format)
+ return audio_val2name[i].name;
+ }
+ return "Unknown";
+}
+
+#if !defined(SOLARIS) && !defined(__NetBSD__) && !defined(AIX_UMS) || defined(NAS)
+void audio_queueflush(struct audio_info_struct *ai)
+{
+}
+#endif
+
diff --git a/mpg123_artsplugin/mpg123/audio.h b/mpg123_artsplugin/mpg123/audio.h
new file mode 100644
index 00000000..78a6e0b3
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/audio.h
@@ -0,0 +1,106 @@
+/*
+ * Audio 'LIB' defines
+ */
+
+#define AUDIO_OUT_HEADPHONES 0x01
+#define AUDIO_OUT_INTERNAL_SPEAKER 0x02
+#define AUDIO_OUT_LINE_OUT 0x04
+
+enum { DECODE_TEST, DECODE_AUDIO, DECODE_FILE, DECODE_BUFFER, DECODE_WAV,
+ DECODE_AU,DECODE_CDR,DECODE_AUDIOFILE };
+
+#define AUDIO_FORMAT_MASK 0x100
+#define AUDIO_FORMAT_16 0x100
+#define AUDIO_FORMAT_8 0x000
+
+#define AUDIO_FORMAT_SIGNED_16 0x110
+#define AUDIO_FORMAT_UNSIGNED_16 0x120
+#define AUDIO_FORMAT_UNSIGNED_8 0x1
+#define AUDIO_FORMAT_SIGNED_8 0x2
+#define AUDIO_FORMAT_ULAW_8 0x4
+#define AUDIO_FORMAT_ALAW_8 0x8
+
+/* 3% rate tolerance */
+#define AUDIO_RATE_TOLERANCE 3
+
+#if 0
+#if defined(HPUX) || defined(SUNOS) || defined(SOLARIS) || defined(OSS) || defined(__NetBSD__) || defined(SPARCLINUX) || defined(__FreeBSD__)
+#endif
+#endif
+
+#ifndef AIX_UMS
+#define AUDIO_USES_FD
+#endif
+#ifdef AIX_UMS
+#include <UMSAudioDevice.h>
+#endif
+
+#ifdef SGI
+/* #include <audio.h> */
+#include <dmedia/audio.h>
+#endif
+
+
+#ifdef HAVE_ALSA_ASOUNDLIB_H
+#include <alsa/asoundlib.h>
+#elif defined(HAVE_SYS_ASOUNDLIB_H)
+#include <sys/asoundlib.h>
+#endif
+
+struct audio_info_struct
+{
+#ifdef AUDIO_USES_FD
+ int fn; /* filenumber */
+#endif
+#ifdef SGI
+ ALconfig config;
+ ALport port;
+#endif
+ long rate;
+ long gain;
+ int output;
+#ifdef ALSA
+ snd_pcm_t *handle;
+ snd_pcm_format_t alsa_format;
+#endif
+#ifdef AIX_UMS
+ UMSAudioDevice dev;
+ UMSAudioDeviceMClass class;
+ Environment *ev;
+ UMSAudioDeviceMClass_ErrorCode err;
+ char *errstr;
+ char *fmtal;
+ char *inp;
+ char *out;
+#endif
+ char *device;
+ int channels;
+ int format;
+ int private1;
+ void *private2;
+};
+
+struct audio_name {
+ int val;
+ char *name;
+ char *sname;
+};
+
+extern void audio_capabilities(struct audio_info_struct *);
+extern void audio_fit_capabilities(struct audio_info_struct *ai,int c,int r);
+
+extern char *audio_encoding_name(int format);
+
+extern int audio_play_samples(struct audio_info_struct *,unsigned char *,int);
+extern int audio_open(struct audio_info_struct *);
+extern int audio_reset_parameters(struct audio_info_struct *);
+extern int audio_rate_best_match(struct audio_info_struct *ai);
+extern int audio_set_rate(struct audio_info_struct *);
+extern int audio_set_format(struct audio_info_struct *);
+extern int audio_get_formats(struct audio_info_struct *);
+extern int audio_set_channels(struct audio_info_struct *);
+extern int audio_write_sample(struct audio_info_struct *,short *,int);
+extern int audio_close(struct audio_info_struct *);
+extern void audio_info_struct_init(struct audio_info_struct *);
+extern void audio_queueflush(struct audio_info_struct *ai);
+
diff --git a/mpg123_artsplugin/mpg123/buffer.c b/mpg123_artsplugin/mpg123/buffer.c
new file mode 100644
index 00000000..3c85b654
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/buffer.c
@@ -0,0 +1,245 @@
+/*
+ * buffer.c
+ *
+ * Oliver Fromme <oliver.fromme@heim3.tu-clausthal.de>
+ * Mon Apr 14 03:53:18 MET DST 1997
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+
+#include "mpg123.h"
+
+int outburst = MAXOUTBURST;
+int preload;
+
+static int intflag = FALSE;
+static int usr1flag = FALSE;
+
+static void catch_interrupt (void)
+{
+ intflag = TRUE;
+}
+
+static void catch_usr1 (void)
+{
+ usr1flag = TRUE;
+}
+
+/* Interfaces to writer process */
+
+extern void buffer_sig(int signal, int block);
+
+void buffer_ignore_lowmem(void)
+{
+#ifndef NOXFERMEM
+ if(buffermem->wakeme[XF_READER])
+ xfermem_putcmd(buffermem->fd[XF_WRITER], XF_CMD_WAKEUP);
+#endif
+}
+
+void buffer_end(void)
+{
+#ifndef NOXFERMEM
+ xfermem_putcmd(buffermem->fd[XF_WRITER], XF_CMD_TERMINATE);
+#endif
+}
+
+void buffer_resync(void)
+{
+ buffer_sig(SIGINT, TRUE);
+}
+
+void buffer_reset(void)
+{
+ buffer_sig(SIGUSR1, TRUE);
+}
+
+void buffer_start(void)
+{
+ buffer_sig(SIGCONT, FALSE);
+}
+
+void buffer_stop(void)
+{
+ buffer_sig(SIGSTOP, FALSE);
+}
+
+extern int buffer_pid;
+
+void buffer_sig(int signal, int block)
+{
+
+#ifndef NOXFERMEM
+
+ kill(buffer_pid, signal);
+
+ if (!buffermem || !block)
+ return;
+
+ if(xfermem_block(XF_WRITER, buffermem) != XF_CMD_WAKEUP)
+ perror("Could not resync/reset buffers");
+#endif
+
+ return;
+}
+
+#ifndef NOXFERMEM
+
+void buffer_loop(struct audio_info_struct *ai, sigset_t *oldsigset)
+{
+ int bytes;
+ int my_fd = buffermem->fd[XF_READER];
+ txfermem *xf = buffermem;
+ int done = FALSE;
+
+ catchsignal (SIGINT, catch_interrupt);
+ catchsignal (SIGUSR1, catch_usr1);
+ sigprocmask (SIG_SETMASK, oldsigset, NULL);
+#ifndef NO_DECODE_AUDIO
+ if (param.outmode == DECODE_AUDIO) {
+ if (audio_open(ai) < 0) {
+ perror("audio");
+ exit(1);
+ }
+ }
+#endif
+
+ for (;;) {
+ if (intflag) {
+ intflag = FALSE;
+#ifndef NO_DECODE_AUDIO
+ if (param.outmode == DECODE_AUDIO)
+ audio_queueflush (ai);
+#endif
+ xf->readindex = xf->freeindex;
+ if (xf->wakeme[XF_WRITER])
+ xfermem_putcmd(my_fd, XF_CMD_WAKEUP);
+ }
+ if (usr1flag) {
+ usr1flag = FALSE;
+ /* close and re-open in order to flush
+ * the device's internal buffer before
+ * changing the sample rate. [OF]
+ */
+ /* writer must block when sending SIGUSR1
+ * or we will lose all data processed
+ * in the meantime! [dk]
+ */
+ xf->readindex = xf->freeindex;
+ /* We've nailed down the new starting location -
+ * writer is now safe to go on. [dk]
+ */
+ if (xf->wakeme[XF_WRITER])
+ xfermem_putcmd(my_fd, XF_CMD_WAKEUP);
+#ifndef NO_DECODE_AUDIO
+ if (param.outmode == DECODE_AUDIO) {
+ audio_close (ai);
+ ai->rate = xf->buf[0];
+ ai->channels = xf->buf[1];
+ ai->format = xf->buf[2];
+ if (audio_open(ai) < 0) {
+ sleep(1);
+ /* give em a 2. try */
+ if (audio_open(ai) < 0) {
+ perror("audio");
+ exit(1);
+ }
+ }
+ }
+#endif
+ }
+ if ( (bytes = xfermem_get_usedspace(xf)) < outburst ) {
+ /* if we got a buffer underrun we first
+ * fill 1/8 of the buffer before continue/start
+ * playing */
+ preload = xf->size>>3;
+ if(preload < outburst)
+ preload = outburst;
+ }
+ if(bytes < preload) {
+ int cmd;
+ if (done && !bytes) {
+ break;
+ }
+
+ if(!done) {
+
+ cmd = xfermem_block(XF_READER, xf);
+
+ switch(cmd) {
+
+ /* More input pending. */
+ case XF_CMD_WAKEUP_INFO:
+ continue;
+ /* Yes, we know buffer is low but
+ * know we don't care.
+ */
+ case XF_CMD_WAKEUP:
+ break; /* Proceed playing. */
+ case XF_CMD_TERMINATE:
+ /* Proceed playing without
+ * blocking any further.
+ */
+ done=TRUE;
+ break;
+ case -1:
+ if(errno==EINTR)
+ continue;
+ perror("Yuck! Error in buffer handling...");
+ done = TRUE;
+ xf->readindex = xf->freeindex;
+ xfermem_putcmd(xf->fd[XF_READER], XF_CMD_TERMINATE);
+ break;
+ default:
+ fprintf(stderr, "\nEh!? Received unknown command 0x%x in buffer process. Tell Daniel!\n", cmd);
+ }
+ }
+ }
+ preload = outburst; /* set preload to lower mark */
+ if (bytes > xf->size - xf->readindex)
+ bytes = xf->size - xf->readindex;
+ if (bytes > outburst)
+ bytes = outburst;
+
+ if (param.outmode == DECODE_FILE)
+ bytes = write(OutputDescriptor, xf->data + xf->readindex, bytes);
+#ifndef NO_DECODE_AUDIO
+ else if (param.outmode == DECODE_AUDIO)
+ bytes = audio_play_samples(ai,
+ (unsigned char *) (xf->data + xf->readindex), bytes);
+#endif
+
+ if(bytes < 0) {
+ bytes = 0;
+ if(errno != EINTR) {
+ perror("Ouch ... error while writing audio data: ");
+ /*
+ * done==TRUE tells writer process to stop
+ * sending data. There might be some latency
+ * involved when resetting readindex to
+ * freeindex so we might need more than one
+ * cycle to terminate. (The number of cycles
+ * should be finite unless I managed to mess
+ * up something. ;-) [dk]
+ */
+ done = TRUE;
+ xf->readindex = xf->freeindex;
+ xfermem_putcmd(xf->fd[XF_READER], XF_CMD_TERMINATE);
+ }
+ }
+
+ xf->readindex = (xf->readindex + bytes) % xf->size;
+ if (xf->wakeme[XF_WRITER])
+ xfermem_putcmd(my_fd, XF_CMD_WAKEUP);
+ }
+
+#ifndef NO_DECODE_AUDIO
+ if (param.outmode == DECODE_AUDIO)
+ audio_close (ai);
+#endif
+}
+
+#endif
+
+/* EOF */
diff --git a/mpg123_artsplugin/mpg123/buffer.h b/mpg123_artsplugin/mpg123/buffer.h
new file mode 100644
index 00000000..c1c771d4
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/buffer.h
@@ -0,0 +1,13 @@
+/*
+ * Application specific interaction between main and buffer
+ * process. This is much less generic than the functions in
+ * xfermem so I chose to put it in buffer.[hc].
+ * 01/28/99 [dk]
+ */
+
+void buffer_ignore_lowmem(void);
+void buffer_end(void);
+void buffer_resync(void);
+void buffer_reset(void);
+void buffer_start(void);
+void buffer_stop(void);
diff --git a/mpg123_artsplugin/mpg123/common.c b/mpg123_artsplugin/mpg123/common.c
new file mode 100644
index 00000000..65d658fd
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/common.c
@@ -0,0 +1,921 @@
+/* GPL clean */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef WIN32
+#include <time.h>
+#else
+#include <sys/time.h>
+#endif
+
+#include <fcntl.h>
+
+#ifdef READ_MMAP
+#include <sys/mman.h>
+#ifndef MAP_FAILED
+#define MAP_FAILED ( (void *) -1 )
+#endif
+#endif
+
+#include "mpg123.h"
+#include "genre.h"
+#include "common.h"
+
+int tabsel_123[2][3][16] = {
+ { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,},
+ {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,},
+ {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} },
+
+ { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,},
+ {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,},
+ {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} }
+};
+
+long freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 };
+
+struct bitstream_info bsi;
+
+static int bsbufend[2]= { 0,0 };
+static int bsbufold_end;
+static unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */
+static unsigned char *bsbuf=bsspace[1],*bsbufold;
+static int bsnum=0;
+
+static int skip_riff(struct reader *);
+static int skip_new_id3(struct reader *);
+
+unsigned char *pcm_sample;
+int pcm_point = 0;
+int audiobufsize = AUDIOBUFSIZE;
+
+static int decode_header(struct frame *fr,unsigned long newhead);
+
+void safewrite(int fd, const void *buf, size_t count) {
+ int donesofar = 0;
+ while(donesofar < count) {
+ int retval;
+ char *p = (char*) buf + donesofar;
+ retval = write(fd,(void*) p,(count-donesofar));
+ if(retval == -1) {
+ if((errno != EINTR) && (errno != EAGAIN))
+ exit(fprintf(stderr,"exception on output!\n"));
+ } else
+ donesofar += retval;
+ }
+}
+
+void audio_flush(int outmode, struct audio_info_struct *ai)
+{
+ if (pcm_point) {
+ switch (outmode) {
+#ifndef NO_DECODE_FILE
+ case DECODE_FILE:
+ safewrite (OutputDescriptor, pcm_sample, pcm_point);
+ break;
+#endif
+#ifndef NO_DECODE_AUDIO
+ case DECODE_AUDIO:
+ audio_play_samples (ai, pcm_sample, pcm_point);
+ break;
+#endif
+#ifndef NOXFERMEM
+ case DECODE_BUFFER:
+ safewrite (buffer_fd[1], pcm_sample, pcm_point);
+ break;
+#endif
+#ifndef NO_DECODE_WAV
+ case DECODE_WAV:
+ case DECODE_CDR:
+ case DECODE_AU:
+ wav_write(pcm_sample, pcm_point);
+ break;
+#endif
+ default:
+ break;
+ }
+ pcm_point = 0;
+ }
+}
+
+#if !defined(WIN32) && !defined(GENERIC)
+void (*catchsignal(int signum, void(*handler)()))()
+{
+ struct sigaction new_sa;
+ struct sigaction old_sa;
+
+#ifdef DONT_CATCH_SIGNALS
+ printf ("Not catching any signals.\n");
+ return ((void (*)()) -1);
+#endif
+
+ new_sa.sa_handler = handler;
+ sigemptyset(&new_sa.sa_mask);
+ new_sa.sa_flags = 0;
+ if (sigaction(signum, &new_sa, &old_sa) == -1)
+ return ((void (*)()) -1);
+ return (old_sa.sa_handler);
+}
+#endif
+
+void read_frame_init (struct frame *fr)
+{
+ fr->firsthead = 0;
+ fr->thishead = 0;
+ fr->freeformatsize = 0;
+}
+
+int head_check(unsigned long head)
+{
+ if( (head & 0xffe00000) != 0xffe00000)
+ return FALSE;
+ if(!((head>>17)&3))
+ return FALSE;
+ if( ((head>>12)&0xf) == 0xf)
+ return FALSE;
+ if( ((head>>10)&0x3) == 0x3 )
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * return 0: EOF or other stream error
+ * -1: giving up
+ * 1: synched
+ */
+#define MAX_INPUT_FRAMESIZE 1920
+#define SYNC_HEAD_MASK 0xffff0000
+#define SYNC_HEAD_MASK_FF 0x0000f000
+#define LOOK_AHEAD_NUM 3
+#define SCAN_LENGTH 16384
+
+#define CHECK_FOR_RIFF 0x0001
+#define CHECK_FOR_ID3_V1 0x0002
+#define CHECK_FOR_ID3_V2 0x0004
+
+int sync_stream(struct reader *rds,struct frame *fr,int flags,int *skipped)
+{
+ int i,j,l,ret;
+ unsigned long firsthead,nexthead;
+ struct frame frameInfo,nextInfo;
+ unsigned char dummybuf[MAX_INPUT_FRAMESIZE];
+ int found=0;
+ int freeformatsize=0;
+
+ for(i=0;i<SCAN_LENGTH;i++) {
+
+ readers_mark_pos(rds); /* store our current position */
+
+ if(!rds->head_read(rds,&firsthead))
+ return 0;
+
+ /* first a few simple checks */
+ if( !head_check(firsthead) || !decode_header(&frameInfo,firsthead) ) {
+
+ /* Check for RIFF Headers */
+ if( (flags & CHECK_FOR_RIFF) && firsthead == ('R'<<24)+('I'<<16)+('F'<<8)+'F') {
+ fprintf(stderr,"Found RIFF Header\n");
+ ret = skip_riff(rds);
+ if(ret > 0) { /* RIFF was OK continue with next byte */
+ *skipped += ret+4;
+ continue;
+ }
+ if(ret == 0)
+ return 0;
+ }
+
+ /* Check for old ID3 Header (or better Footer ;) */
+ if( (flags & CHECK_FOR_ID3_V1) && (firsthead>>8) == ('T'<<16)+('A'<<8)+'G') {
+ fprintf(stderr,"Found old ID3 Header\n");
+ }
+
+ /* Check for new ID3 header */
+ if( (flags & CHECK_FOR_ID3_V2) && (firsthead>>8) == ('I'<<16)+('D'<<8)+'3') {
+ if( (firsthead & 0xff) != 0xff) {
+ fprintf(stderr,"Found new ID3 Header\n");
+ ret = skip_new_id3(rds);
+ if(!ret)
+ return 0;
+ if(ret > 0) {
+ *skipped += ret+4;
+ continue;
+ }
+ }
+ }
+
+ readers_goto_mark(rds); /* reset to old mark and continue */
+ if(!rds->read_frame_body(rds,dummybuf,1))
+ return 0;
+
+ (*skipped)++;
+ continue;
+ }
+
+ found = 0;
+ freeformatsize = 0;
+
+ /*
+ * At the first free format paket we do not know the size
+ */
+ if(frameInfo.bitrate_index == 0) {
+ int maxframesize = MAX_INPUT_FRAMESIZE; /* FIXME depends on layer and sampling freq */
+
+fprintf(stderr,"Searching for next FF header\n");
+
+ if(!rds->head_read(rds,&nexthead))
+ return 0;
+
+ for(j=0;j<maxframesize;j++) {
+ if(head_check(nexthead) && (nexthead & (SYNC_HEAD_MASK|SYNC_HEAD_MASK_FF) ) == (firsthead & (SYNC_HEAD_MASK|SYNC_HEAD_MASK_FF)) &&
+ decode_header(&nextInfo,nexthead) ) {
+
+/* fprintf(stderr,"j: %d %d %d\n",j,frameInfo.padsize,nextInfo.padsize); */
+
+ freeformatsize = j - frameInfo.padsize;
+ found = 1;
+ break;
+ }
+ if(!rds->head_shift(rds,&nexthead))
+ return 0;
+ }
+ }
+ else {
+ if(!rds->read_frame_body(rds,dummybuf,frameInfo.framesize))
+ return 0;
+
+ if(!rds->head_read(rds,&nexthead))
+ return 0;
+
+/*
+fprintf(stderr,"S: %08lx %08lx %d %d %d %d\n",firsthead,nexthead, head_check(nexthead),(nexthead & SYNC_HEAD_MASK) == firsthead,(nexthead & SYNC_HEAD_MASK_FF) != 0x0,decode_header(&nextInfo,nexthead));
+*/
+
+ if( head_check(nexthead) && (nexthead & SYNC_HEAD_MASK) == (firsthead & SYNC_HEAD_MASK) &&
+ (nexthead & SYNC_HEAD_MASK_FF) != 0x0 && decode_header(&nextInfo,nexthead)) {
+ found = 1;
+ }
+ }
+
+ if(!found) {
+ readers_goto_mark(rds); /* reset to old mark and continue */
+ if(!rds->read_frame_body(rds,dummybuf,1))
+ return 0;
+ (*skipped)++;
+ continue;
+ }
+
+/*
+fprintf(stderr,"s: %08lx %08lx %d %d %d\n",firsthead,nexthead,frameInfo.framesize,nextInfo.framesize,freeformatsize);
+*/
+
+ /* check some more frames */
+ for(l=0;l<LOOK_AHEAD_NUM;l++) {
+ int size;
+
+ if( freeformatsize > 0 ) {
+ size = freeformatsize + nextInfo.padsize;
+ }
+ else
+ size = nextInfo.framesize;
+
+ /* step over data */
+ if(!rds->read_frame_body(rds,dummybuf,size))
+ return 0;
+
+ if(!rds->head_read(rds,&nexthead))
+ return 0;
+
+ if(!head_check(nexthead) ||
+ (nexthead & SYNC_HEAD_MASK) != (firsthead & SYNC_HEAD_MASK) ||
+ !decode_header(&nextInfo,nexthead) ) {
+ found = 0;
+ break;
+ }
+ if( freeformatsize > 0) {
+ if( ( nexthead & SYNC_HEAD_MASK_FF ) != 0x0) {
+ found = 0;
+ break;
+ }
+ }
+ else {
+ if( (nexthead & SYNC_HEAD_MASK_FF) == 0x0) {
+ found = 0;
+ break;
+ }
+ }
+ }
+
+ if(found)
+ break;
+
+ readers_goto_mark(rds); /* reset to old mark and continue */
+ if(!rds->read_frame_body(rds,dummybuf,1)) /* skip first byte */
+ return 0;
+ (*skipped)++;
+
+ }
+
+ if(i == SCAN_LENGTH)
+ return -1;
+
+ readers_goto_mark(rds);
+ fr->freeformatsize = freeformatsize;
+ fr->firsthead = firsthead;
+
+ return 1;
+
+}
+
+/*
+ * skips the RIFF header at the beginning
+ *
+ * returns: 0 = read-error
+ * -1/-2 = illegal RIFF header (= -2 backstep not valid)
+ * 1 = skipping succeeded
+ */
+static int skip_riff(struct reader *rds)
+{
+ unsigned long length;
+ unsigned char buf[16];
+
+ if(!rds->read_frame_body(rds,buf,16)) /* read header information */
+ return 0;
+
+ if( strncmp("WAVEfmt ",(char *)buf+4,8) ) /* check 2. signature */
+ return -1;
+
+ length = (unsigned long) buf[12] + /* decode the header length */
+ (((unsigned long) buf[13])<<8) +
+ (((unsigned long) buf[14])<<16) +
+ (((unsigned long) buf[15])<<24);
+
+ if(!rds->skip_bytes(rds,length)) /* will not store data in backbuff! */
+ return 0;
+
+ if(!rds->read_frame_body(rds,buf,8)) /* skip "data" plus length */
+ return 0;
+
+ if(strncmp("data",(char *)buf,4))
+ return -2;
+
+ return length+8+16;
+}
+
+/*
+ * skips the ID3 header at the beginning
+ *
+ * returns: 0 = read-error
+ * -1 = illegal ID3 header
+ * 1 = skipping succeeded
+ */
+static int skip_new_id3(struct reader *rds)
+{
+ unsigned long length;
+ unsigned char buf[6];
+
+ if(!rds->read_frame_body(rds,buf,6)) /* read more header information */
+ return 0;
+
+ if(buf[0] == 0xff)
+ return -1;
+
+ if( (buf[2]|buf[3]|buf[4]|buf[5]) & 0x80)
+ return -1;
+
+ length = (unsigned long) buf[2] & 0x7f;
+ length <<= 7;
+ length += (unsigned long) buf[3] & 0x7f;
+ length <<= 7;
+ length += (unsigned long) buf[4] & 0x7f;
+ length <<= 7;
+ length += (unsigned long) buf[5] & 0x7f;
+
+ if(!rds->skip_bytes(rds,length)) /* will not store data in backbuff! */
+ return 0;
+
+ return length+6;
+
+}
+
+
+
+
+
+/*****************************************************************
+ * read next frame
+ */
+int read_frame(struct reader *rds,struct frame *fr)
+{
+ unsigned long newhead,oldhead;
+ static unsigned char ssave[34];
+
+ oldhead = fr->thishead;
+
+ if (param.halfspeed) {
+ static int halfphase = 0;
+ if (halfphase--) {
+ bsi.bitindex = 0;
+ bsi.wordpointer = (unsigned char *) bsbuf;
+ if (fr->lay == 3)
+ memcpy (bsbuf, ssave, fr->sideInfoSize);
+ return 1;
+ }
+ else
+ halfphase = param.halfspeed - 1;
+ }
+
+ while(1) {
+
+ if(!rds->head_read(rds,&newhead))
+ return FALSE;
+
+/*
+ fprintf(stderr,"n %08lx",newhead);
+*/
+
+ if( !head_check(newhead) || !decode_header(fr,newhead) ) {
+ if (!param.quiet)
+ fprintf(stderr,"Illegal Audio-MPEG-Header 0x%08lx at offset 0x%lx.\n",
+ newhead,rds->tell(rds)-4);
+
+ if(param.tryresync) {
+ int try = 0;
+ readers_pushback_header(rds,newhead);
+ if(sync_stream(rds,fr,0xffff,&try) <= 0)
+ return 0;
+ if(!param.quiet)
+ fprintf (stderr, "Skipped %d bytes in input.\n", try);
+ }
+ else
+ return (0);
+ }
+ else
+ break;
+ }
+
+/*
+ fprintf(stderr,"N %08lx",newhead);
+*/
+
+ fr->header_change = 2;
+ if(oldhead) {
+ if((oldhead & 0xc00) == (fr->thishead & 0xc00)) {
+ if( (oldhead & 0xc0) == 0 && (fr->thishead & 0xc0) == 0)
+ fr->header_change = 1;
+ else if( (oldhead & 0xc0) > 0 && (fr->thishead & 0xc0) > 0)
+ fr->header_change = 1;
+ }
+ }
+
+
+ if(!fr->bitrate_index) {
+ fr->framesize = fr->freeformatsize + fr->padsize;
+ }
+
+/*
+fprintf(stderr,"Reading %d\n",fr->framesize);
+*/
+
+ /* flip/init buffer for Layer 3 */
+ /* FIXME for reentrance */
+ bsbufold = bsbuf;
+ bsbufold_end = bsbufend[bsnum];
+ bsbuf = bsspace[bsnum]+512;
+ bsnum = (bsnum + 1) & 1;
+ bsbufend[bsnum] = fr->framesize;
+
+ /* read main data into memory */
+ if(!rds->read_frame_body(rds,bsbuf,fr->framesize))
+ return 0;
+
+ {
+ /* Test */
+ static struct vbrHeader head;
+ static int vbr = 0; /* FIXME */
+ if(!vbr) {
+ getVBRHeader(&head,bsbuf,fr);
+ vbr = 1;
+ }
+ }
+
+ bsi.bitindex = 0;
+ bsi.wordpointer = (unsigned char *) bsbuf;
+
+ if (param.halfspeed && fr->lay == 3)
+ memcpy (ssave, bsbuf, fr->sideInfoSize);
+
+ return 1;
+}
+
+/*
+ * decode a header and write the information
+ * into the frame structure
+ */
+static int decode_header(struct frame *fr,unsigned long newhead)
+{
+ if(!head_check(newhead)) {
+ fprintf(stderr,"Oopps header is wrong %08lx\n",newhead);
+ return 0;
+ }
+
+ if( newhead & (1<<20) ) {
+ fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1;
+ fr->mpeg25 = 0;
+ }
+ else {
+ fr->lsf = 1;
+ fr->mpeg25 = 1;
+ }
+
+ /*
+ * CHECKME: should be add more consistency checks here ?
+ * changed layer, changed CRC bit, changed sampling frequency
+ */
+ {
+ fr->lay = 4-((newhead>>17)&3);
+ if( ((newhead>>10)&0x3) == 0x3) {
+ fprintf(stderr,"Stream error\n");
+ return 0;
+ }
+ if(fr->mpeg25) {
+ fr->sampling_frequency = 6 + ((newhead>>10)&0x3);
+ }
+ else
+ fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3);
+ fr->error_protection = ((newhead>>16)&0x1)^0x1;
+ }
+
+ fr->bitrate_index = ((newhead>>12)&0xf);
+ fr->padding = ((newhead>>9)&0x1);
+ fr->extension = ((newhead>>8)&0x1);
+ fr->mode = ((newhead>>6)&0x3);
+ fr->mode_ext = ((newhead>>4)&0x3);
+ fr->copyright = ((newhead>>3)&0x1);
+ fr->original = ((newhead>>2)&0x1);
+ fr->emphasis = newhead & 0x3;
+
+ fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
+
+ switch(fr->lay) {
+ case 1:
+ fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
+ fr->framesize /= freqs[fr->sampling_frequency];
+ fr->framesize = ((fr->framesize+fr->padding)<<2)-4;
+ fr->sideInfoSize = 0;
+ fr->padsize = fr->padding << 2;
+ break;
+ case 2:
+ fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
+ fr->framesize /= freqs[fr->sampling_frequency];
+ fr->framesize += fr->padding - 4;
+ fr->sideInfoSize = 0;
+ fr->padsize = fr->padding;
+ break;
+ case 3:
+ if(fr->lsf)
+ fr->sideInfoSize = (fr->stereo == 1) ? 9 : 17;
+ else
+ fr->sideInfoSize = (fr->stereo == 1) ? 17 : 32;
+ if(fr->error_protection)
+ fr->sideInfoSize += 2;
+ fr->framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
+ fr->framesize /= freqs[fr->sampling_frequency]<<(fr->lsf);
+ fr->framesize = fr->framesize + fr->padding - 4;
+ fr->padsize = fr->padding;
+ break;
+ default:
+ fprintf(stderr,"Sorry, unknown layer type.\n");
+ return (0);
+ }
+
+ if(!fr->bitrate_index) {
+ /* fprintf(stderr,"Warning, Free format not heavily tested: (head %08lx)\n",newhead); */
+ fr->framesize = 0;
+ }
+ fr->thishead = newhead;
+
+ return 1;
+}
+
+#ifdef MPG123_REMOTE
+void print_rheader(struct frame *fr)
+{
+ static char *modes[4] = { "Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel" };
+ static char *layers[4] = { "Unknown" , "I", "II", "III" };
+ static char *mpeg_type[2] = { "1.0" , "2.0" };
+
+ /* version, layer, freq, mode, channels, bitrate, BPF */
+ fprintf(stderr,"@I %s %s %ld %s %d %d %d\n",
+ mpeg_type[fr->lsf],layers[fr->lay],freqs[fr->sampling_frequency],
+ modes[fr->mode],fr->stereo,
+ tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index],
+ fr->framesize+4);
+}
+#endif
+
+void print_header(struct frame *fr)
+{
+ static char *modes[4] = { "Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel" };
+ static char *layers[4] = { "Unknown" , "I", "II", "III" };
+
+ fprintf(stderr,"MPEG %s, Layer: %s, Freq: %ld, mode: %s, modext: %d, BPF : %d\n",
+ fr->mpeg25 ? "2.5" : (fr->lsf ? "2.0" : "1.0"),
+ layers[fr->lay],freqs[fr->sampling_frequency],
+ modes[fr->mode],fr->mode_ext,fr->framesize+4);
+ fprintf(stderr,"Channels: %d, copyright: %s, original: %s, CRC: %s, emphasis: %d.\n",
+ fr->stereo,fr->copyright?"Yes":"No",
+ fr->original?"Yes":"No",fr->error_protection?"Yes":"No",
+ fr->emphasis);
+ fprintf(stderr,"Bitrate: %d Kbits/s, Extension value: %d\n",
+ tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index],fr->extension);
+}
+
+void print_header_compact(struct frame *fr)
+{
+ static char *modes[4] = { "stereo", "joint-stereo", "dual-channel", "mono" };
+ static char *layers[4] = { "Unknown" , "I", "II", "III" };
+
+ fprintf(stderr,"MPEG %s layer %s, %d kbit/s, %ld Hz %s\n",
+ fr->mpeg25 ? "2.5" : (fr->lsf ? "2.0" : "1.0"),
+ layers[fr->lay],
+ tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index],
+ freqs[fr->sampling_frequency], modes[fr->mode]);
+}
+
+void print_id3_tag(unsigned char *buf)
+{
+ struct id3tag {
+ char tag[3];
+ char title[30];
+ char artist[30];
+ char album[30];
+ char year[4];
+ char comment[30];
+ unsigned char genre;
+ };
+ struct id3tag *tag = (struct id3tag *) buf;
+ char title[31]={0,};
+ char artist[31]={0,};
+ char album[31]={0,};
+ char year[5]={0,};
+ char comment[31]={0,};
+ char genre[31]={0,};
+
+ if(param.quiet)
+ return;
+
+ strncpy(title,tag->title,30);
+ strncpy(artist,tag->artist,30);
+ strncpy(album,tag->album,30);
+ strncpy(year,tag->year,4);
+ strncpy(comment,tag->comment,30);
+
+ if ( tag->genre < sizeof(genre_table)/sizeof(*genre_table) ) {
+ strncpy(genre, genre_table[tag->genre], 30);
+ } else {
+ strncpy(genre,"Unknown",30);
+ }
+
+ fprintf(stderr,"Title : %-30s Artist: %s\n",title,artist);
+ fprintf(stderr,"Album : %-30s Year : %4s\n",album,year);
+ fprintf(stderr,"Comment: %-30s Genre : %s\n",comment,genre);
+}
+
+#if 0
+/* removed the strndup for better portability */
+/*
+ * Allocate space for a new string containing the first
+ * "num" characters of "src". The resulting string is
+ * always zero-terminated. Returns NULL if malloc fails.
+ */
+char *strndup (const char *src, int num)
+{
+ char *dst;
+
+ if (!(dst = (char *) malloc(num+1)))
+ return (NULL);
+ dst[num] = '\0';
+ return (strncpy(dst, src, num));
+}
+#endif
+
+/*
+ * Split "path" into directory and filename components.
+ *
+ * Return value is 0 if no directory was specified (i.e.
+ * "path" does not contain a '/'), OR if the directory
+ * is the same as on the previous call to this function.
+ *
+ * Return value is 1 if a directory was specified AND it
+ * is different from the previous one (if any).
+ */
+
+int split_dir_file (const char *path, char **dname, char **fname)
+{
+ static char *lastdir = NULL;
+ char *slashpos;
+
+ if ((slashpos = strrchr(path, '/'))) {
+ *fname = slashpos + 1;
+ *dname = strdup(path); /* , 1 + slashpos - path); */
+ if(!(*dname)) {
+ perror("memory");
+ exit(1);
+ }
+ (*dname)[1 + slashpos - path] = 0;
+ if (lastdir && !strcmp(lastdir, *dname)) {
+ /*** same as previous directory ***/
+ free (*dname);
+ *dname = lastdir;
+ return 0;
+ }
+ else {
+ /*** different directory ***/
+ if (lastdir)
+ free (lastdir);
+ lastdir = *dname;
+ return 1;
+ }
+ }
+ else {
+ /*** no directory specified ***/
+ if (lastdir) {
+ free (lastdir);
+ lastdir = NULL;
+ };
+ *dname = NULL;
+ *fname = (char *)path;
+ return 0;
+ }
+}
+
+void set_pointer(int ssize,long backstep)
+{
+ bsi.wordpointer = bsbuf + ssize - backstep;
+ if (backstep)
+ memcpy(bsi.wordpointer,bsbufold+bsbufold_end-backstep,backstep);
+ bsi.bitindex = 0;
+}
+
+/********************************/
+
+double compute_bpf(struct frame *fr)
+{
+ double bpf;
+
+ if(!fr->bitrate_index) {
+ return fr->freeformatsize + 4;
+ }
+
+ switch(fr->lay) {
+ case 1:
+ bpf = tabsel_123[fr->lsf][0][fr->bitrate_index];
+ bpf *= 12000.0 * 4.0;
+ bpf /= freqs[fr->sampling_frequency] <<(fr->lsf);
+ break;
+ case 2:
+ case 3:
+ bpf = tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index];
+ bpf *= 144000;
+ bpf /= freqs[fr->sampling_frequency] << (fr->lsf);
+ break;
+ default:
+ bpf = 1.0;
+ }
+
+ return bpf;
+}
+
+double compute_tpf(struct frame *fr)
+{
+ static int bs[4] = { 0,384,1152,1152 };
+ double tpf;
+
+ tpf = (double) bs[fr->lay];
+ tpf /= freqs[fr->sampling_frequency] << (fr->lsf);
+ return tpf;
+}
+
+/*
+ * Returns number of frames queued up in output buffer, i.e.
+ * offset between currently played and currently decoded frame.
+ */
+
+#ifndef NOXFERMEM
+long compute_buffer_offset(struct frame *fr)
+{
+ long bufsize;
+
+ /*
+ * buffermem->buf[0] holds output sampling rate,
+ * buffermem->buf[1] holds number of channels,
+ * buffermem->buf[2] holds audio format of output.
+ */
+
+ if(!param.usebuffer || !(bufsize=xfermem_get_usedspace(buffermem))
+ || !buffermem->buf[0] || !buffermem->buf[1])
+ return 0;
+
+ bufsize = (long)((double) bufsize / buffermem->buf[0] /
+ buffermem->buf[1] / compute_tpf(fr));
+
+ if((buffermem->buf[2] & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_16)
+ return bufsize/2;
+ else
+ return bufsize;
+}
+#endif
+
+void print_stat(struct reader *rds,struct frame *fr,int no,long buffsize,struct audio_info_struct *ai)
+{
+ double bpf,tpf,tim1,tim2;
+ double dt = 0.0;
+ int sno,rno;
+ char outbuf[256];
+
+ if(!rds || !fr)
+ return;
+
+ outbuf[0] = 0;
+
+#ifndef GENERIC
+ {
+ struct timeval t;
+ fd_set serr;
+ int n,errfd = fileno(stderr);
+
+ t.tv_sec=t.tv_usec=0;
+
+ FD_ZERO(&serr);
+ FD_SET(errfd,&serr);
+ n = select(errfd+1,NULL,&serr,NULL,&t);
+ if(n <= 0)
+ return;
+ }
+#endif
+
+ bpf = compute_bpf(fr);
+ tpf = compute_tpf(fr);
+
+ if(buffsize > 0 && ai && ai->rate > 0 && ai->channels > 0) {
+ dt = (double) buffsize / ai->rate / ai->channels;
+ if( (ai->format & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_16)
+ dt *= 0.5;
+ }
+
+ rno = 0;
+ sno = no;
+ if(rds->filelen >= 0) {
+ long t = rds->tell(rds);
+ rno = (int)((double)(rds->filelen-t)/bpf);
+ sno = (int)((double)t/bpf);
+ }
+
+ sprintf(outbuf+strlen(outbuf),"\rFrame# %5d [%5d], ",sno,rno);
+
+ tim1 = sno*tpf-dt;
+ tim2 = rno*tpf+dt;
+#if 0
+ tim1 = tim1 < 0 ? 0.0 : tim1;
+#endif
+ tim2 = tim2 < 0 ? 0.0 : tim2;
+
+ sprintf(outbuf+strlen(outbuf),"Time: %02u:%02u.%02u [%02u:%02u.%02u], ",
+ (unsigned int)tim1/60,
+ (unsigned int)tim1%60,
+ (unsigned int)(tim1*100)%100,
+ (unsigned int)tim2/60,
+ (unsigned int)tim2%60,
+ (unsigned int)(tim2*100)%100);
+
+ if(param.usebuffer)
+ sprintf(outbuf+strlen(outbuf),"[%8ld] ",(long)buffsize);
+ write(fileno(stderr),outbuf,strlen(outbuf));
+#if 0
+ fflush(out); /* hmm not really nec. */
+#endif
+}
+
+int get_songlen(struct reader *rds,struct frame *fr,int no)
+{
+ double tpf;
+
+ if(!fr)
+ return 0;
+
+ if(no < 0) {
+ if(!rds || rds->filelen < 0)
+ return 0;
+ no = (double) rds->filelen / compute_bpf(fr);
+ }
+
+ tpf = compute_tpf(fr);
+ return no*tpf;
+}
+
+
diff --git a/mpg123_artsplugin/mpg123/common.h b/mpg123_artsplugin/mpg123/common.h
new file mode 100644
index 00000000..716a3c83
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/common.h
@@ -0,0 +1,19 @@
+/*
+ * common.h
+ */
+
+extern void print_id3_tag(unsigned char *buf);
+extern unsigned long firsthead;
+extern int tabsel_123[2][3][16];
+extern double compute_tpf(struct frame *fr);
+extern double compute_bpf(struct frame *fr);
+extern long compute_buffer_offset(struct frame *fr);
+
+/*
+struct bitstream_info {
+ int bitindex;
+ unsigned char *wordpointer;
+};
+*/
+
+
diff --git a/mpg123_artsplugin/mpg123/dct36_3dnow.s b/mpg123_artsplugin/mpg123/dct36_3dnow.s
new file mode 100644
index 00000000..05b7b81d
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/dct36_3dnow.s
@@ -0,0 +1,499 @@
+#
+# dct36_3dnow.s - 3DNow! optimized dct36()
+#
+# This code based 'dct36_3dnow.s' by Syuuhei Kashiyama
+# <squash@mb.kcom.ne.jp>,only two types of changes have been made:
+#
+# - remove PREFETCH instruction for speedup
+# - change function name for support 3DNow! automatic detect
+#
+# You can find Kashiyama's original 3dnow! support patch
+# (for mpg123-0.59o) at
+# http:#/user.ecc.u-tokyo.ac.jp/~g810370/linux-simd/ (Japanese).
+#
+# by KIMURA Takuhiro <kim@hannah.ipc.miyakyo-u.ac.jp> - until 31.Mar.1999
+# <kim@comtec.co.jp> - after 1.Apr.1999
+#
+
+##/
+##/ Replacement of dct36() with AMD's 3DNow! SIMD operations support
+##/
+##/ Syuuhei Kashiyama <squash@mb.kcom.ne.jp>
+##/
+##/ The author of this program disclaim whole expressed or implied
+##/ warranties with regard to this program, and in no event shall the
+##/ author of this program liable to whatever resulted from the use of
+##/ this program. Use it at your own risk.
+##/
+
+ .globl dct36_3dnow
+ .type dct36_3dnow,@function
+dct36_3dnow:
+ pushl %ebp
+ movl %esp,%ebp
+ subl $120,%esp
+ pushl %esi
+ pushl %ebx
+ movl 8(%ebp),%eax
+ movl 12(%ebp),%esi
+ movl 16(%ebp),%ecx
+ movl 20(%ebp),%edx
+ movl 24(%ebp),%ebx
+ leal -128(%ebp),%esp
+
+ femms
+ movq (%eax),%mm0
+ movq 4(%eax),%mm1
+ pfadd %mm1,%mm0
+ movq %mm0,4(%eax)
+ psrlq $32,%mm1
+ movq 12(%eax),%mm2
+ punpckldq %mm2,%mm1
+ pfadd %mm2,%mm1
+ movq %mm1,12(%eax)
+ psrlq $32,%mm2
+ movq 20(%eax),%mm3
+ punpckldq %mm3,%mm2
+ pfadd %mm3,%mm2
+ movq %mm2,20(%eax)
+ psrlq $32,%mm3
+ movq 28(%eax),%mm4
+ punpckldq %mm4,%mm3
+ pfadd %mm4,%mm3
+ movq %mm3,28(%eax)
+ psrlq $32,%mm4
+ movq 36(%eax),%mm5
+ punpckldq %mm5,%mm4
+ pfadd %mm5,%mm4
+ movq %mm4,36(%eax)
+ psrlq $32,%mm5
+ movq 44(%eax),%mm6
+ punpckldq %mm6,%mm5
+ pfadd %mm6,%mm5
+ movq %mm5,44(%eax)
+ psrlq $32,%mm6
+ movq 52(%eax),%mm7
+ punpckldq %mm7,%mm6
+ pfadd %mm7,%mm6
+ movq %mm6,52(%eax)
+ psrlq $32,%mm7
+ movq 60(%eax),%mm0
+ punpckldq %mm0,%mm7
+ pfadd %mm0,%mm7
+ movq %mm7,60(%eax)
+ psrlq $32,%mm0
+ movd 68(%eax),%mm1
+ pfadd %mm1,%mm0
+ movd %mm0,68(%eax)
+ movd 4(%eax),%mm0
+ movd 12(%eax),%mm1
+ punpckldq %mm1,%mm0
+ punpckldq 20(%eax),%mm1
+ pfadd %mm1,%mm0
+ movd %mm0,12(%eax)
+ psrlq $32,%mm0
+ movd %mm0,20(%eax)
+ psrlq $32,%mm1
+ movd 28(%eax),%mm2
+ punpckldq %mm2,%mm1
+ punpckldq 36(%eax),%mm2
+ pfadd %mm2,%mm1
+ movd %mm1,28(%eax)
+ psrlq $32,%mm1
+ movd %mm1,36(%eax)
+ psrlq $32,%mm2
+ movd 44(%eax),%mm3
+ punpckldq %mm3,%mm2
+ punpckldq 52(%eax),%mm3
+ pfadd %mm3,%mm2
+ movd %mm2,44(%eax)
+ psrlq $32,%mm2
+ movd %mm2,52(%eax)
+ psrlq $32,%mm3
+ movd 60(%eax),%mm4
+ punpckldq %mm4,%mm3
+ punpckldq 68(%eax),%mm4
+ pfadd %mm4,%mm3
+ movd %mm3,60(%eax)
+ psrlq $32,%mm3
+ movd %mm3,68(%eax)
+
+ movq 24(%eax),%mm0
+ movq 48(%eax),%mm1
+ movd COS9+12,%mm2
+ punpckldq %mm2,%mm2
+ movd COS9+24,%mm3
+ punpckldq %mm3,%mm3
+ pfmul %mm2,%mm0
+ pfmul %mm3,%mm1
+ pushl %eax
+ movl $1,%eax
+ movd %eax,%mm7
+ pi2fd %mm7,%mm7
+ popl %eax
+ movq 8(%eax),%mm2
+ movd COS9+4,%mm3
+ punpckldq %mm3,%mm3
+ pfmul %mm3,%mm2
+ pfadd %mm0,%mm2
+ movq 40(%eax),%mm3
+ movd COS9+20,%mm4
+ punpckldq %mm4,%mm4
+ pfmul %mm4,%mm3
+ pfadd %mm3,%mm2
+ movq 56(%eax),%mm3
+ movd COS9+28,%mm4
+ punpckldq %mm4,%mm4
+ pfmul %mm4,%mm3
+ pfadd %mm3,%mm2
+ movq (%eax),%mm3
+ movq 16(%eax),%mm4
+ movd COS9+8,%mm5
+ punpckldq %mm5,%mm5
+ pfmul %mm5,%mm4
+ pfadd %mm4,%mm3
+ movq 32(%eax),%mm4
+ movd COS9+16,%mm5
+ punpckldq %mm5,%mm5
+ pfmul %mm5,%mm4
+ pfadd %mm4,%mm3
+ pfadd %mm1,%mm3
+ movq 64(%eax),%mm4
+ movd COS9+32,%mm5
+ punpckldq %mm5,%mm5
+ pfmul %mm5,%mm4
+ pfadd %mm4,%mm3
+ movq %mm2,%mm4
+ pfadd %mm3,%mm4
+ movq %mm7,%mm5
+ punpckldq tfcos36+0,%mm5
+ pfmul %mm5,%mm4
+ movq %mm4,%mm5
+ pfacc %mm5,%mm5
+ movd 108(%edx),%mm6
+ punpckldq 104(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd %mm5,36(%ecx)
+ psrlq $32,%mm5
+ movd %mm5,32(%ecx)
+ movq %mm4,%mm6
+ punpckldq %mm6,%mm5
+ pfsub %mm6,%mm5
+ punpckhdq %mm5,%mm5
+ movd 32(%edx),%mm6
+ punpckldq 36(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd 32(%esi),%mm6
+ punpckldq 36(%esi),%mm6
+ pfadd %mm6,%mm5
+ movd %mm5,1024(%ebx)
+ psrlq $32,%mm5
+ movd %mm5,1152(%ebx)
+ movq %mm3,%mm4
+ pfsub %mm2,%mm4
+ movq %mm7,%mm5
+ punpckldq tfcos36+32,%mm5
+ pfmul %mm5,%mm4
+ movq %mm4,%mm5
+ pfacc %mm5,%mm5
+ movd 140(%edx),%mm6
+ punpckldq 72(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd %mm5,68(%ecx)
+ psrlq $32,%mm5
+ movd %mm5,0(%ecx)
+ movq %mm4,%mm6
+ punpckldq %mm6,%mm5
+ pfsub %mm6,%mm5
+ punpckhdq %mm5,%mm5
+ movd 0(%edx),%mm6
+ punpckldq 68(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd 0(%esi),%mm6
+ punpckldq 68(%esi),%mm6
+ pfadd %mm6,%mm5
+ movd %mm5,0(%ebx)
+ psrlq $32,%mm5
+ movd %mm5,2176(%ebx)
+ movq 8(%eax),%mm2
+ movq 40(%eax),%mm3
+ pfsub %mm3,%mm2
+ movq 56(%eax),%mm3
+ pfsub %mm3,%mm2
+ movd COS9+12,%mm3
+ punpckldq %mm3,%mm3
+ pfmul %mm3,%mm2
+ movq 16(%eax),%mm3
+ movq 32(%eax),%mm4
+ pfsub %mm4,%mm3
+ movq 64(%eax),%mm4
+ pfsub %mm4,%mm3
+ movd COS9+24,%mm4
+ punpckldq %mm4,%mm4
+ pfmul %mm4,%mm3
+ movq 48(%eax),%mm4
+ pfsub %mm4,%mm3
+ movq (%eax),%mm4
+ pfadd %mm4,%mm3
+ movq %mm2,%mm4
+ pfadd %mm3,%mm4
+ movq %mm7,%mm5
+ punpckldq tfcos36+4,%mm5
+ pfmul %mm5,%mm4
+ movq %mm4,%mm5
+ pfacc %mm5,%mm5
+ movd 112(%edx),%mm6
+ punpckldq 100(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd %mm5,40(%ecx)
+ psrlq $32,%mm5
+ movd %mm5,28(%ecx)
+ movq %mm4,%mm6
+ punpckldq %mm6,%mm5
+ pfsub %mm6,%mm5
+ punpckhdq %mm5,%mm5
+ movd 28(%edx),%mm6
+ punpckldq 40(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd 28(%esi),%mm6
+ punpckldq 40(%esi),%mm6
+ pfadd %mm6,%mm5
+ movd %mm5,896(%ebx)
+ psrlq $32,%mm5
+ movd %mm5,1280(%ebx)
+ movq %mm3,%mm4
+ pfsub %mm2,%mm4
+ movq %mm7,%mm5
+ punpckldq tfcos36+28,%mm5
+ pfmul %mm5,%mm4
+ movq %mm4,%mm5
+ pfacc %mm5,%mm5
+ movd 136(%edx),%mm6
+ punpckldq 76(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd %mm5,64(%ecx)
+ psrlq $32,%mm5
+ movd %mm5,4(%ecx)
+ movq %mm4,%mm6
+ punpckldq %mm6,%mm5
+ pfsub %mm6,%mm5
+ punpckhdq %mm5,%mm5
+ movd 4(%edx),%mm6
+ punpckldq 64(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd 4(%esi),%mm6
+ punpckldq 64(%esi),%mm6
+ pfadd %mm6,%mm5
+ movd %mm5,128(%ebx)
+ psrlq $32,%mm5
+ movd %mm5,2048(%ebx)
+
+ movq 8(%eax),%mm2
+ movd COS9+20,%mm3
+ punpckldq %mm3,%mm3
+ pfmul %mm3,%mm2
+ pfsub %mm0,%mm2
+ movq 40(%eax),%mm3
+ movd COS9+28,%mm4
+ punpckldq %mm4,%mm4
+ pfmul %mm4,%mm3
+ pfsub %mm3,%mm2
+ movq 56(%eax),%mm3
+ movd COS9+4,%mm4
+ punpckldq %mm4,%mm4
+ pfmul %mm4,%mm3
+ pfadd %mm3,%mm2
+ movq (%eax),%mm3
+ movq 16(%eax),%mm4
+ movd COS9+32,%mm5
+ punpckldq %mm5,%mm5
+ pfmul %mm5,%mm4
+ pfsub %mm4,%mm3
+ movq 32(%eax),%mm4
+ movd COS9+8,%mm5
+ punpckldq %mm5,%mm5
+ pfmul %mm5,%mm4
+ pfsub %mm4,%mm3
+ pfadd %mm1,%mm3
+ movq 64(%eax),%mm4
+ movd COS9+16,%mm5
+ punpckldq %mm5,%mm5
+ pfmul %mm5,%mm4
+ pfadd %mm4,%mm3
+ movq %mm2,%mm4
+ pfadd %mm3,%mm4
+ movq %mm7,%mm5
+ punpckldq tfcos36+8,%mm5
+ pfmul %mm5,%mm4
+ movq %mm4,%mm5
+ pfacc %mm5,%mm5
+ movd 116(%edx),%mm6
+ punpckldq 96(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd %mm5,44(%ecx)
+ psrlq $32,%mm5
+ movd %mm5,24(%ecx)
+ movq %mm4,%mm6
+ punpckldq %mm6,%mm5
+ pfsub %mm6,%mm5
+ punpckhdq %mm5,%mm5
+ movd 24(%edx),%mm6
+ punpckldq 44(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd 24(%esi),%mm6
+ punpckldq 44(%esi),%mm6
+ pfadd %mm6,%mm5
+ movd %mm5,768(%ebx)
+ psrlq $32,%mm5
+ movd %mm5,1408(%ebx)
+ movq %mm3,%mm4
+ pfsub %mm2,%mm4
+ movq %mm7,%mm5
+ punpckldq tfcos36+24,%mm5
+ pfmul %mm5,%mm4
+ movq %mm4,%mm5
+ pfacc %mm5,%mm5
+ movd 132(%edx),%mm6
+ punpckldq 80(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd %mm5,60(%ecx)
+ psrlq $32,%mm5
+ movd %mm5,8(%ecx)
+ movq %mm4,%mm6
+ punpckldq %mm6,%mm5
+ pfsub %mm6,%mm5
+ punpckhdq %mm5,%mm5
+ movd 8(%edx),%mm6
+ punpckldq 60(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd 8(%esi),%mm6
+ punpckldq 60(%esi),%mm6
+ pfadd %mm6,%mm5
+ movd %mm5,256(%ebx)
+ psrlq $32,%mm5
+ movd %mm5,1920(%ebx)
+ movq 8(%eax),%mm2
+ movd COS9+28,%mm3
+ punpckldq %mm3,%mm3
+ pfmul %mm3,%mm2
+ pfsub %mm0,%mm2
+ movq 40(%eax),%mm3
+ movd COS9+4,%mm4
+ punpckldq %mm4,%mm4
+ pfmul %mm4,%mm3
+ pfadd %mm3,%mm2
+ movq 56(%eax),%mm3
+ movd COS9+20,%mm4
+ punpckldq %mm4,%mm4
+ pfmul %mm4,%mm3
+ pfsub %mm3,%mm2
+ movq (%eax),%mm3
+ movq 16(%eax),%mm4
+ movd COS9+16,%mm5
+ punpckldq %mm5,%mm5
+ pfmul %mm5,%mm4
+ pfsub %mm4,%mm3
+ movq 32(%eax),%mm4
+ movd COS9+32,%mm5
+ punpckldq %mm5,%mm5
+ pfmul %mm5,%mm4
+ pfadd %mm4,%mm3
+ pfadd %mm1,%mm3
+ movq 64(%eax),%mm4
+ movd COS9+8,%mm5
+ punpckldq %mm5,%mm5
+ pfmul %mm5,%mm4
+ pfsub %mm4,%mm3
+ movq %mm2,%mm4
+ pfadd %mm3,%mm4
+ movq %mm7,%mm5
+ punpckldq tfcos36+12,%mm5
+ pfmul %mm5,%mm4
+ movq %mm4,%mm5
+ pfacc %mm5,%mm5
+ movd 120(%edx),%mm6
+ punpckldq 92(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd %mm5,48(%ecx)
+ psrlq $32,%mm5
+ movd %mm5,20(%ecx)
+ movq %mm4,%mm6
+ punpckldq %mm6,%mm5
+ pfsub %mm6,%mm5
+ punpckhdq %mm5,%mm5
+ movd 20(%edx),%mm6
+ punpckldq 48(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd 20(%esi),%mm6
+ punpckldq 48(%esi),%mm6
+ pfadd %mm6,%mm5
+ movd %mm5,640(%ebx)
+ psrlq $32,%mm5
+ movd %mm5,1536(%ebx)
+ movq %mm3,%mm4
+ pfsub %mm2,%mm4
+ movq %mm7,%mm5
+ punpckldq tfcos36+20,%mm5
+ pfmul %mm5,%mm4
+ movq %mm4,%mm5
+ pfacc %mm5,%mm5
+ movd 128(%edx),%mm6
+ punpckldq 84(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd %mm5,56(%ecx)
+ psrlq $32,%mm5
+ movd %mm5,12(%ecx)
+ movq %mm4,%mm6
+ punpckldq %mm6,%mm5
+ pfsub %mm6,%mm5
+ punpckhdq %mm5,%mm5
+ movd 12(%edx),%mm6
+ punpckldq 56(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd 12(%esi),%mm6
+ punpckldq 56(%esi),%mm6
+ pfadd %mm6,%mm5
+ movd %mm5,384(%ebx)
+ psrlq $32,%mm5
+ movd %mm5,1792(%ebx)
+
+ movq (%eax),%mm4
+ movq 16(%eax),%mm3
+ pfsub %mm3,%mm4
+ movq 32(%eax),%mm3
+ pfadd %mm3,%mm4
+ movq 48(%eax),%mm3
+ pfsub %mm3,%mm4
+ movq 64(%eax),%mm3
+ pfadd %mm3,%mm4
+ movq %mm7,%mm5
+ punpckldq tfcos36+16,%mm5
+ pfmul %mm5,%mm4
+ movq %mm4,%mm5
+ pfacc %mm5,%mm5
+ movd 124(%edx),%mm6
+ punpckldq 88(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd %mm5,52(%ecx)
+ psrlq $32,%mm5
+ movd %mm5,16(%ecx)
+ movq %mm4,%mm6
+ punpckldq %mm6,%mm5
+ pfsub %mm6,%mm5
+ punpckhdq %mm5,%mm5
+ movd 16(%edx),%mm6
+ punpckldq 52(%edx),%mm6
+ pfmul %mm6,%mm5
+ movd 16(%esi),%mm6
+ punpckldq 52(%esi),%mm6
+ pfadd %mm6,%mm5
+ movd %mm5,512(%ebx)
+ psrlq $32,%mm5
+ movd %mm5,1664(%ebx)
+
+ femms
+ popl %ebx
+ popl %esi
+ movl %ebp,%esp
+ popl %ebp
+ ret
diff --git a/mpg123_artsplugin/mpg123/dct64.c b/mpg123_artsplugin/mpg123/dct64.c
new file mode 100644
index 00000000..59c19676
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/dct64.c
@@ -0,0 +1,168 @@
+
+/*
+ * Discrete Cosine Tansform (DCT) for subband synthesis
+ *
+ * -funroll-loops (for gcc) will remove the loops for better performance
+ * using loops in the source-code enhances readabillity
+ */
+
+/*
+ * TODO: write an optimized version for the down-sampling modes
+ * (in these modes the bands 16-31 (2:1) or 8-31 (4:1) are zero
+ */
+
+#include "mpg123.h"
+
+void dct64(real *out0,real *out1,real *samples)
+{
+ real bufs[64];
+
+ {
+ register int i,j;
+ register real *b1,*b2,*bs,*costab;
+
+ b1 = samples;
+ bs = bufs;
+ costab = pnts[0]+16;
+ b2 = b1 + 32;
+
+ for(i=15;i>=0;i--)
+ *bs++ = (*b1++ + *--b2);
+ for(i=15;i>=0;i--)
+ *bs++ = REAL_MUL((*--b2 - *b1++), *--costab);
+
+ b1 = bufs;
+ costab = pnts[1]+8;
+ b2 = b1 + 16;
+
+ {
+ for(i=7;i>=0;i--)
+ *bs++ = (*b1++ + *--b2);
+ for(i=7;i>=0;i--)
+ *bs++ = REAL_MUL((*--b2 - *b1++), *--costab);
+ b2 += 32;
+ costab += 8;
+ for(i=7;i>=0;i--)
+ *bs++ = (*b1++ + *--b2);
+ for(i=7;i>=0;i--)
+ *bs++ = REAL_MUL((*b1++ - *--b2), *--costab);
+ b2 += 32;
+ }
+
+ bs = bufs;
+ costab = pnts[2];
+ b2 = b1 + 8;
+
+ for(j=2;j;j--)
+ {
+ for(i=3;i>=0;i--)
+ *bs++ = (*b1++ + *--b2);
+ for(i=3;i>=0;i--)
+ *bs++ = REAL_MUL((*--b2 - *b1++), costab[i]);
+ b2 += 16;
+ for(i=3;i>=0;i--)
+ *bs++ = (*b1++ + *--b2);
+ for(i=3;i>=0;i--)
+ *bs++ = REAL_MUL((*b1++ - *--b2), costab[i]);
+ b2 += 16;
+ }
+
+ b1 = bufs;
+ costab = pnts[3];
+ b2 = b1 + 4;
+
+ for(j=4;j;j--)
+ {
+ *bs++ = (*b1++ + *--b2);
+ *bs++ = (*b1++ + *--b2);
+ *bs++ = REAL_MUL((*--b2 - *b1++), costab[1]);
+ *bs++ = REAL_MUL((*--b2 - *b1++), costab[0]);
+ b2 += 8;
+ *bs++ = (*b1++ + *--b2);
+ *bs++ = (*b1++ + *--b2);
+ *bs++ = REAL_MUL((*b1++ - *--b2), costab[1]);
+ *bs++ = REAL_MUL((*b1++ - *--b2), costab[0]);
+ b2 += 8;
+ }
+ bs = bufs;
+ costab = pnts[4];
+
+ for(j=8;j;j--)
+ {
+ real v0,v1;
+ v0=*b1++; v1 = *b1++;
+ *bs++ = (v0 + v1);
+ *bs++ = REAL_MUL((v0 - v1), (*costab));
+ v0=*b1++; v1 = *b1++;
+ *bs++ = (v0 + v1);
+ *bs++ = REAL_MUL((v1 - v0), (*costab));
+ }
+
+ }
+
+
+ {
+ register real *b1;
+ register int i;
+
+ for(b1=bufs,i=8;i;i--,b1+=4)
+ b1[2] += b1[3];
+
+ for(b1=bufs,i=4;i;i--,b1+=8)
+ {
+ b1[4] += b1[6];
+ b1[6] += b1[5];
+ b1[5] += b1[7];
+ }
+
+ for(b1=bufs,i=2;i;i--,b1+=16)
+ {
+ b1[8] += b1[12];
+ b1[12] += b1[10];
+ b1[10] += b1[14];
+ b1[14] += b1[9];
+ b1[9] += b1[13];
+ b1[13] += b1[11];
+ b1[11] += b1[15];
+ }
+ }
+
+
+ out0[0x10*16] = bufs[0];
+ out0[0x10*15] = bufs[16+0] + bufs[16+8];
+ out0[0x10*14] = bufs[8];
+ out0[0x10*13] = bufs[16+8] + bufs[16+4];
+ out0[0x10*12] = bufs[4];
+ out0[0x10*11] = bufs[16+4] + bufs[16+12];
+ out0[0x10*10] = bufs[12];
+ out0[0x10* 9] = bufs[16+12] + bufs[16+2];
+ out0[0x10* 8] = bufs[2];
+ out0[0x10* 7] = bufs[16+2] + bufs[16+10];
+ out0[0x10* 6] = bufs[10];
+ out0[0x10* 5] = bufs[16+10] + bufs[16+6];
+ out0[0x10* 4] = bufs[6];
+ out0[0x10* 3] = bufs[16+6] + bufs[16+14];
+ out0[0x10* 2] = bufs[14];
+ out0[0x10* 1] = bufs[16+14] + bufs[16+1];
+ out0[0x10* 0] = bufs[1];
+
+ out1[0x10* 0] = bufs[1];
+ out1[0x10* 1] = bufs[16+1] + bufs[16+9];
+ out1[0x10* 2] = bufs[9];
+ out1[0x10* 3] = bufs[16+9] + bufs[16+5];
+ out1[0x10* 4] = bufs[5];
+ out1[0x10* 5] = bufs[16+5] + bufs[16+13];
+ out1[0x10* 6] = bufs[13];
+ out1[0x10* 7] = bufs[16+13] + bufs[16+3];
+ out1[0x10* 8] = bufs[3];
+ out1[0x10* 9] = bufs[16+3] + bufs[16+11];
+ out1[0x10*10] = bufs[11];
+ out1[0x10*11] = bufs[16+11] + bufs[16+7];
+ out1[0x10*12] = bufs[7];
+ out1[0x10*13] = bufs[16+7] + bufs[16+15];
+ out1[0x10*14] = bufs[15];
+ out1[0x10*15] = bufs[16+15];
+
+}
+
+
diff --git a/mpg123_artsplugin/mpg123/dct64_3dnow.s b/mpg123_artsplugin/mpg123/dct64_3dnow.s
new file mode 100644
index 00000000..2a214905
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/dct64_3dnow.s
@@ -0,0 +1,706 @@
+##/
+##/ Replacement of dct64() with AMD's 3DNow! SIMD operations support
+##/
+##/ Syuuhei Kashiyama <squash@mb.kcom.ne.jp>
+##/
+##/ The author of this program disclaim whole expressed or implied
+##/ warranties with regard to this program, and in no event shall the
+##/ author of this program liable to whatever resulted from the use of
+##/ this program. Use it at your own risk.
+##/
+
+ .globl dct64_3dnow
+ .type dct64_3dnow,@function
+dct64_3dnow:
+ subl $256,%esp
+ pushl %ebp
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ leal 16(%esp),%ebx
+ movl 284(%esp),%edi
+ movl 276(%esp),%ebp
+ movl 280(%esp),%edx
+ leal 128(%ebx),%esi
+
+ # femms
+
+ ## 1
+ movl pnts,%eax
+ movq 0(%edi),%mm0
+ movq %mm0,%mm1
+ movd 124(%edi),%mm2
+ punpckldq 120(%edi),%mm2
+ movq 0(%eax),%mm3
+ pfadd %mm2,%mm0
+ movq %mm0,0(%ebx)
+ pfsub %mm2,%mm1
+ pfmul %mm3,%mm1
+ movd %mm1,124(%ebx)
+ psrlq $32,%mm1
+ movd %mm1,120(%ebx)
+ movq 8(%edi),%mm4
+ movq %mm4,%mm5
+ movd 116(%edi),%mm6
+ punpckldq 112(%edi),%mm6
+ movq 8(%eax),%mm7
+ pfadd %mm6,%mm4
+ movq %mm4,8(%ebx)
+ pfsub %mm6,%mm5
+ pfmul %mm7,%mm5
+ movd %mm5,116(%ebx)
+ psrlq $32,%mm5
+ movd %mm5,112(%ebx)
+ movq 16(%edi),%mm0
+ movq %mm0,%mm1
+ movd 108(%edi),%mm2
+ punpckldq 104(%edi),%mm2
+ movq 16(%eax),%mm3
+ pfadd %mm2,%mm0
+ movq %mm0,16(%ebx)
+ pfsub %mm2,%mm1
+ pfmul %mm3,%mm1
+ movd %mm1,108(%ebx)
+ psrlq $32,%mm1
+ movd %mm1,104(%ebx)
+ movq 24(%edi),%mm4
+ movq %mm4,%mm5
+ movd 100(%edi),%mm6
+ punpckldq 96(%edi),%mm6
+ movq 24(%eax),%mm7
+ pfadd %mm6,%mm4
+ movq %mm4,24(%ebx)
+ pfsub %mm6,%mm5
+ pfmul %mm7,%mm5
+ movd %mm5,100(%ebx)
+ psrlq $32,%mm5
+ movd %mm5,96(%ebx)
+ movq 32(%edi),%mm0
+ movq %mm0,%mm1
+ movd 92(%edi),%mm2
+ punpckldq 88(%edi),%mm2
+ movq 32(%eax),%mm3
+ pfadd %mm2,%mm0
+ movq %mm0,32(%ebx)
+ pfsub %mm2,%mm1
+ pfmul %mm3,%mm1
+ movd %mm1,92(%ebx)
+ psrlq $32,%mm1
+ movd %mm1,88(%ebx)
+ movq 40(%edi),%mm4
+ movq %mm4,%mm5
+ movd 84(%edi),%mm6
+ punpckldq 80(%edi),%mm6
+ movq 40(%eax),%mm7
+ pfadd %mm6,%mm4
+ movq %mm4,40(%ebx)
+ pfsub %mm6,%mm5
+ pfmul %mm7,%mm5
+ movd %mm5,84(%ebx)
+ psrlq $32,%mm5
+ movd %mm5,80(%ebx)
+ movq 48(%edi),%mm0
+ movq %mm0,%mm1
+ movd 76(%edi),%mm2
+ punpckldq 72(%edi),%mm2
+ movq 48(%eax),%mm3
+ pfadd %mm2,%mm0
+ movq %mm0,48(%ebx)
+ pfsub %mm2,%mm1
+ pfmul %mm3,%mm1
+ movd %mm1,76(%ebx)
+ psrlq $32,%mm1
+ movd %mm1,72(%ebx)
+ movq 56(%edi),%mm4
+ movq %mm4,%mm5
+ movd 68(%edi),%mm6
+ punpckldq 64(%edi),%mm6
+ movq 56(%eax),%mm7
+ pfadd %mm6,%mm4
+ movq %mm4,56(%ebx)
+ pfsub %mm6,%mm5
+ pfmul %mm7,%mm5
+ movd %mm5,68(%ebx)
+ psrlq $32,%mm5
+ movd %mm5,64(%ebx)
+
+ ## 2
+ movl pnts+4,%eax
+ ## 0, 14
+ movq 0(%ebx),%mm0
+ movq %mm0,%mm1
+ movd 60(%ebx),%mm2
+ punpckldq 56(%ebx),%mm2
+ movq 0(%eax),%mm3
+ pfadd %mm2,%mm0
+ movq %mm0,0(%esi)
+ pfsub %mm2,%mm1
+ pfmul %mm3,%mm1
+ movd %mm1,60(%esi)
+ psrlq $32,%mm1
+ movd %mm1,56(%esi)
+ ## 16, 30
+ movq 64(%ebx),%mm0
+ movq %mm0,%mm1
+ movd 124(%ebx),%mm2
+ punpckldq 120(%ebx),%mm2
+ pfadd %mm2,%mm0
+ movq %mm0,64(%esi)
+ pfsubr %mm2,%mm1
+ pfmul %mm3,%mm1
+ movd %mm1,124(%esi)
+ psrlq $32,%mm1
+ movd %mm1,120(%esi)
+ ## 2, 12
+ movq 8(%ebx),%mm4
+ movq %mm4,%mm5
+ movd 52(%ebx),%mm6
+ punpckldq 48(%ebx),%mm6
+ movq 8(%eax),%mm7
+ pfadd %mm6,%mm4
+ movq %mm4,8(%esi)
+ pfsub %mm6,%mm5
+ pfmul %mm7,%mm5
+ movd %mm5,52(%esi)
+ psrlq $32,%mm5
+ movd %mm5,48(%esi)
+ ## 18, 28
+ movq 72(%ebx),%mm4
+ movq %mm4,%mm5
+ movd 116(%ebx),%mm6
+ punpckldq 112(%ebx),%mm6
+ pfadd %mm6,%mm4
+ movq %mm4,72(%esi)
+ pfsubr %mm6,%mm5
+ pfmul %mm7,%mm5
+ movd %mm5,116(%esi)
+ psrlq $32,%mm5
+ movd %mm5,112(%esi)
+ ## 4, 10
+ movq 16(%ebx),%mm0
+ movq %mm0,%mm1
+ movd 44(%ebx),%mm2
+ punpckldq 40(%ebx),%mm2
+ movq 16(%eax),%mm3
+ pfadd %mm2,%mm0
+ movq %mm0,16(%esi)
+ pfsub %mm2,%mm1
+ pfmul %mm3,%mm1
+ movd %mm1,44(%esi)
+ psrlq $32,%mm1
+ movd %mm1,40(%esi)
+ ## 20, 26
+ movq 80(%ebx),%mm0
+ movq %mm0,%mm1
+ movd 108(%ebx),%mm2
+ punpckldq 104(%ebx),%mm2
+ pfadd %mm2,%mm0
+ movq %mm0,80(%esi)
+ pfsubr %mm2,%mm1
+ pfmul %mm3,%mm1
+ movd %mm1,108(%esi)
+ psrlq $32,%mm1
+ movd %mm1,104(%esi)
+ ## 6, 8
+ movq 24(%ebx),%mm4
+ movq %mm4,%mm5
+ movd 36(%ebx),%mm6
+ punpckldq 32(%ebx),%mm6
+ movq 24(%eax),%mm7
+ pfadd %mm6,%mm4
+ movq %mm4,24(%esi)
+ pfsub %mm6,%mm5
+ pfmul %mm7,%mm5
+ movd %mm5,36(%esi)
+ psrlq $32,%mm5
+ movd %mm5,32(%esi)
+ ## 22, 24
+ movq 88(%ebx),%mm4
+ movq %mm4,%mm5
+ movd 100(%ebx),%mm6
+ punpckldq 96(%ebx),%mm6
+ pfadd %mm6,%mm4
+ movq %mm4,88(%esi)
+ pfsubr %mm6,%mm5
+ pfmul %mm7,%mm5
+ movd %mm5,100(%esi)
+ psrlq $32,%mm5
+ movd %mm5,96(%esi)
+
+ ## 3
+ movl pnts+8,%eax
+ movq 0(%eax),%mm0
+ movq 8(%eax),%mm1
+ ## 0, 6
+ movq 0(%esi),%mm2
+ movq %mm2,%mm3
+ movd 28(%esi),%mm4
+ punpckldq 24(%esi),%mm4
+ pfadd %mm4,%mm2
+ pfsub %mm4,%mm3
+ pfmul %mm0,%mm3
+ movq %mm2,0(%ebx)
+ movd %mm3,28(%ebx)
+ psrlq $32,%mm3
+ movd %mm3,24(%ebx)
+ ## 2, 4
+ movq 8(%esi),%mm5
+ movq %mm5,%mm6
+ movd 20(%esi),%mm7
+ punpckldq 16(%esi),%mm7
+ pfadd %mm7,%mm5
+ pfsub %mm7,%mm6
+ pfmul %mm1,%mm6
+ movq %mm5,8(%ebx)
+ movd %mm6,20(%ebx)
+ psrlq $32,%mm6
+ movd %mm6,16(%ebx)
+ ## 8, 14
+ movq 32(%esi),%mm2
+ movq %mm2,%mm3
+ movd 60(%esi),%mm4
+ punpckldq 56(%esi),%mm4
+ pfadd %mm4,%mm2
+ pfsubr %mm4,%mm3
+ pfmul %mm0,%mm3
+ movq %mm2,32(%ebx)
+ movd %mm3,60(%ebx)
+ psrlq $32,%mm3
+ movd %mm3,56(%ebx)
+ ## 10, 12
+ movq 40(%esi),%mm5
+ movq %mm5,%mm6
+ movd 52(%esi),%mm7
+ punpckldq 48(%esi),%mm7
+ pfadd %mm7,%mm5
+ pfsubr %mm7,%mm6
+ pfmul %mm1,%mm6
+ movq %mm5,40(%ebx)
+ movd %mm6,52(%ebx)
+ psrlq $32,%mm6
+ movd %mm6,48(%ebx)
+ ## 16, 22
+ movq 64(%esi),%mm2
+ movq %mm2,%mm3
+ movd 92(%esi),%mm4
+ punpckldq 88(%esi),%mm4
+ pfadd %mm4,%mm2
+ pfsub %mm4,%mm3
+ pfmul %mm0,%mm3
+ movq %mm2,64(%ebx)
+ movd %mm3,92(%ebx)
+ psrlq $32,%mm3
+ movd %mm3,88(%ebx)
+ ## 18, 20
+ movq 72(%esi),%mm5
+ movq %mm5,%mm6
+ movd 84(%esi),%mm7
+ punpckldq 80(%esi),%mm7
+ pfadd %mm7,%mm5
+ pfsub %mm7,%mm6
+ pfmul %mm1,%mm6
+ movq %mm5,72(%ebx)
+ movd %mm6,84(%ebx)
+ psrlq $32,%mm6
+ movd %mm6,80(%ebx)
+ ## 24, 30
+ movq 96(%esi),%mm2
+ movq %mm2,%mm3
+ movd 124(%esi),%mm4
+ punpckldq 120(%esi),%mm4
+ pfadd %mm4,%mm2
+ pfsubr %mm4,%mm3
+ pfmul %mm0,%mm3
+ movq %mm2,96(%ebx)
+ movd %mm3,124(%ebx)
+ psrlq $32,%mm3
+ movd %mm3,120(%ebx)
+ ## 26, 28
+ movq 104(%esi),%mm5
+ movq %mm5,%mm6
+ movd 116(%esi),%mm7
+ punpckldq 112(%esi),%mm7
+ pfadd %mm7,%mm5
+ pfsubr %mm7,%mm6
+ pfmul %mm1,%mm6
+ movq %mm5,104(%ebx)
+ movd %mm6,116(%ebx)
+ psrlq $32,%mm6
+ movd %mm6,112(%ebx)
+
+ ## 4
+ movl pnts+12,%eax
+ movq 0(%eax),%mm0
+ ## 0
+ movq 0(%ebx),%mm1
+ movq %mm1,%mm2
+ movd 12(%ebx),%mm3
+ punpckldq 8(%ebx),%mm3
+ pfadd %mm3,%mm1
+ pfsub %mm3,%mm2
+ pfmul %mm0,%mm2
+ movq %mm1,0(%esi)
+ movd %mm2,12(%esi)
+ psrlq $32,%mm2
+ movd %mm2,8(%esi)
+ ## 4
+ movq 16(%ebx),%mm4
+ movq %mm4,%mm5
+ movd 28(%ebx),%mm6
+ punpckldq 24(%ebx),%mm6
+ pfadd %mm6,%mm4
+ pfsubr %mm6,%mm5
+ pfmul %mm0,%mm5
+ movq %mm4,16(%esi)
+ movd %mm5,28(%esi)
+ psrlq $32,%mm5
+ movd %mm5,24(%esi)
+ ## 8
+ movq 32(%ebx),%mm1
+ movq %mm1,%mm2
+ movd 44(%ebx),%mm3
+ punpckldq 40(%ebx),%mm3
+ pfadd %mm3,%mm1
+ pfsub %mm3,%mm2
+ pfmul %mm0,%mm2
+ movq %mm1,32(%esi)
+ movd %mm2,44(%esi)
+ psrlq $32,%mm2
+ movd %mm2,40(%esi)
+ ## 12
+ movq 48(%ebx),%mm4
+ movq %mm4,%mm5
+ movd 60(%ebx),%mm6
+ punpckldq 56(%ebx),%mm6
+ pfadd %mm6,%mm4
+ pfsubr %mm6,%mm5
+ pfmul %mm0,%mm5
+ movq %mm4,48(%esi)
+ movd %mm5,60(%esi)
+ psrlq $32,%mm5
+ movd %mm5,56(%esi)
+ ## 16
+ movq 64(%ebx),%mm1
+ movq %mm1,%mm2
+ movd 76(%ebx),%mm3
+ punpckldq 72(%ebx),%mm3
+ pfadd %mm3,%mm1
+ pfsub %mm3,%mm2
+ pfmul %mm0,%mm2
+ movq %mm1,64(%esi)
+ movd %mm2,76(%esi)
+ psrlq $32,%mm2
+ movd %mm2,72(%esi)
+ ## 20
+ movq 80(%ebx),%mm4
+ movq %mm4,%mm5
+ movd 92(%ebx),%mm6
+ punpckldq 88(%ebx),%mm6
+ pfadd %mm6,%mm4
+ pfsubr %mm6,%mm5
+ pfmul %mm0,%mm5
+ movq %mm4,80(%esi)
+ movd %mm5,92(%esi)
+ psrlq $32,%mm5
+ movd %mm5,88(%esi)
+ ## 24
+ movq 96(%ebx),%mm1
+ movq %mm1,%mm2
+ movd 108(%ebx),%mm3
+ punpckldq 104(%ebx),%mm3
+ pfadd %mm3,%mm1
+ pfsub %mm3,%mm2
+ pfmul %mm0,%mm2
+ movq %mm1,96(%esi)
+ movd %mm2,108(%esi)
+ psrlq $32,%mm2
+ movd %mm2,104(%esi)
+ ## 28
+ movq 112(%ebx),%mm4
+ movq %mm4,%mm5
+ movd 124(%ebx),%mm6
+ punpckldq 120(%ebx),%mm6
+ pfadd %mm6,%mm4
+ pfsubr %mm6,%mm5
+ pfmul %mm0,%mm5
+ movq %mm4,112(%esi)
+ movd %mm5,124(%esi)
+ psrlq $32,%mm5
+ movd %mm5,120(%esi)
+
+ ## 5
+ movl $-1,%eax
+ movd %eax,%mm1
+ movl $1,%eax
+ ## L | H
+ movd %eax,%mm0
+ punpckldq %mm1,%mm0
+ ## 1.0 | -1.0
+ pi2fd %mm0,%mm0
+ movd %eax,%mm1
+ pi2fd %mm1,%mm1
+ movl pnts+16,%eax
+ movd 0(%eax),%mm2
+ ## 1.0 | cos0
+ punpckldq %mm2,%mm1
+ ## 0
+ movq 0(%esi),%mm2
+ movq %mm2,%mm3
+ pfmul %mm0,%mm3
+ pfacc %mm3,%mm2
+ pfmul %mm1,%mm2
+ movq %mm2,0(%ebx)
+ movq 8(%esi),%mm4
+ movq %mm4,%mm5
+ pfmul %mm0,%mm5
+ pfacc %mm5,%mm4
+ pfmul %mm0,%mm4
+ pfmul %mm1,%mm4
+ movq %mm4,%mm5
+ psrlq $32,%mm5
+ pfacc %mm5,%mm4
+ movq %mm4,8(%ebx)
+ ## 4
+ movq 16(%esi),%mm2
+ movq %mm2,%mm3
+ pfmul %mm0,%mm3
+ pfacc %mm3,%mm2
+ pfmul %mm1,%mm2
+ movq 24(%esi),%mm4
+ movq %mm4,%mm5
+ pfmul %mm0,%mm5
+ pfacc %mm5,%mm4
+ pfmul %mm0,%mm4
+ pfmul %mm1,%mm4
+ movq %mm4,%mm5
+ psrlq $32,%mm5
+ pfacc %mm5,%mm4
+ movq %mm2,%mm3
+ psrlq $32,%mm3
+ pfadd %mm4,%mm2
+ pfadd %mm3,%mm4
+ movq %mm2,16(%ebx)
+ movq %mm4,24(%ebx)
+ ## 8
+ movq 32(%esi),%mm2
+ movq %mm2,%mm3
+ pfmul %mm0,%mm3
+ pfacc %mm3,%mm2
+ pfmul %mm1,%mm2
+ movq %mm2,32(%ebx)
+ movq 40(%esi),%mm4
+ movq %mm4,%mm5
+ pfmul %mm0,%mm5
+ pfacc %mm5,%mm4
+ pfmul %mm0,%mm4
+ pfmul %mm1,%mm4
+ movq %mm4,%mm5
+ psrlq $32,%mm5
+ pfacc %mm5,%mm4
+ movq %mm4,40(%ebx)
+ ## 12
+ movq 48(%esi),%mm2
+ movq %mm2,%mm3
+ pfmul %mm0,%mm3
+ pfacc %mm3,%mm2
+ pfmul %mm1,%mm2
+ movq 56(%esi),%mm4
+ movq %mm4,%mm5
+ pfmul %mm0,%mm5
+ pfacc %mm5,%mm4
+ pfmul %mm0,%mm4
+ pfmul %mm1,%mm4
+ movq %mm4,%mm5
+ psrlq $32,%mm5
+ pfacc %mm5,%mm4
+ movq %mm2,%mm3
+ psrlq $32,%mm3
+ pfadd %mm4,%mm2
+ pfadd %mm3,%mm4
+ movq %mm2,48(%ebx)
+ movq %mm4,56(%ebx)
+ ## 16
+ movq 64(%esi),%mm2
+ movq %mm2,%mm3
+ pfmul %mm0,%mm3
+ pfacc %mm3,%mm2
+ pfmul %mm1,%mm2
+ movq %mm2,64(%ebx)
+ movq 72(%esi),%mm4
+ movq %mm4,%mm5
+ pfmul %mm0,%mm5
+ pfacc %mm5,%mm4
+ pfmul %mm0,%mm4
+ pfmul %mm1,%mm4
+ movq %mm4,%mm5
+ psrlq $32,%mm5
+ pfacc %mm5,%mm4
+ movq %mm4,72(%ebx)
+ ## 20
+ movq 80(%esi),%mm2
+ movq %mm2,%mm3
+ pfmul %mm0,%mm3
+ pfacc %mm3,%mm2
+ pfmul %mm1,%mm2
+ movq 88(%esi),%mm4
+ movq %mm4,%mm5
+ pfmul %mm0,%mm5
+ pfacc %mm5,%mm4
+ pfmul %mm0,%mm4
+ pfmul %mm1,%mm4
+ movq %mm4,%mm5
+ psrlq $32,%mm5
+ pfacc %mm5,%mm4
+ movq %mm2,%mm3
+ psrlq $32,%mm3
+ pfadd %mm4,%mm2
+ pfadd %mm3,%mm4
+ movq %mm2,80(%ebx)
+ movq %mm4,88(%ebx)
+ ## 24
+ movq 96(%esi),%mm2
+ movq %mm2,%mm3
+ pfmul %mm0,%mm3
+ pfacc %mm3,%mm2
+ pfmul %mm1,%mm2
+ movq %mm2,96(%ebx)
+ movq 104(%esi),%mm4
+ movq %mm4,%mm5
+ pfmul %mm0,%mm5
+ pfacc %mm5,%mm4
+ pfmul %mm0,%mm4
+ pfmul %mm1,%mm4
+ movq %mm4,%mm5
+ psrlq $32,%mm5
+ pfacc %mm5,%mm4
+ movq %mm4,104(%ebx)
+ ## 28
+ movq 112(%esi),%mm2
+ movq %mm2,%mm3
+ pfmul %mm0,%mm3
+ pfacc %mm3,%mm2
+ pfmul %mm1,%mm2
+ movq 120(%esi),%mm4
+ movq %mm4,%mm5
+ pfmul %mm0,%mm5
+ pfacc %mm5,%mm4
+ pfmul %mm0,%mm4
+ pfmul %mm1,%mm4
+ movq %mm4,%mm5
+ psrlq $32,%mm5
+ pfacc %mm5,%mm4
+ movq %mm2,%mm3
+ psrlq $32,%mm3
+ pfadd %mm4,%mm2
+ pfadd %mm3,%mm4
+ movq %mm2,112(%ebx)
+ movq %mm4,120(%ebx)
+
+ ## Phase6
+ movl 0(%ebx),%eax
+ movl %eax,1024(%ebp)
+ movl 4(%ebx),%eax
+ movl %eax,0(%ebp)
+ movl %eax,0(%edx)
+ movl 8(%ebx),%eax
+ movl %eax,512(%ebp)
+ movl 12(%ebx),%eax
+ movl %eax,512(%edx)
+
+ movl 16(%ebx),%eax
+ movl %eax,768(%ebp)
+ movl 20(%ebx),%eax
+ movl %eax,256(%edx)
+
+ movl 24(%ebx),%eax
+ movl %eax,256(%ebp)
+ movl 28(%ebx),%eax
+ movl %eax,768(%edx)
+
+ movq 32(%ebx),%mm0
+ movq 48(%ebx),%mm1
+ pfadd %mm1,%mm0
+ movd %mm0,896(%ebp)
+ psrlq $32,%mm0
+ movd %mm0,128(%edx)
+ movq 40(%ebx),%mm2
+ pfadd %mm2,%mm1
+ movd %mm1,640(%ebp)
+ psrlq $32,%mm1
+ movd %mm1,384(%edx)
+
+ movq 56(%ebx),%mm3
+ pfadd %mm3,%mm2
+ movd %mm2,384(%ebp)
+ psrlq $32,%mm2
+ movd %mm2,640(%edx)
+
+ movd 36(%ebx),%mm4
+ pfadd %mm4,%mm3
+ movd %mm3,128(%ebp)
+ psrlq $32,%mm3
+ movd %mm3,896(%edx)
+ movq 96(%ebx),%mm0
+ movq 64(%ebx),%mm1
+
+ movq 112(%ebx),%mm2
+ pfadd %mm2,%mm0
+ movq %mm0,%mm3
+ pfadd %mm1,%mm3
+ movd %mm3,960(%ebp)
+ psrlq $32,%mm3
+ movd %mm3,64(%edx)
+ movq 80(%ebx),%mm1
+ pfadd %mm1,%mm0
+ movd %mm0,832(%ebp)
+ psrlq $32,%mm0
+ movd %mm0,192(%edx)
+ movq 104(%ebx),%mm3
+ pfadd %mm3,%mm2
+ movq %mm2,%mm4
+ pfadd %mm1,%mm4
+ movd %mm4,704(%ebp)
+ psrlq $32,%mm4
+ movd %mm4,320(%edx)
+ movq 72(%ebx),%mm1
+ pfadd %mm1,%mm2
+ movd %mm2,576(%ebp)
+ psrlq $32,%mm2
+ movd %mm2,448(%edx)
+
+ movq 120(%ebx),%mm4
+ pfadd %mm4,%mm3
+ movq %mm3,%mm5
+ pfadd %mm1,%mm5
+ movd %mm5,448(%ebp)
+ psrlq $32,%mm5
+ movd %mm5,576(%edx)
+ movq 88(%ebx),%mm1
+ pfadd %mm1,%mm3
+ movd %mm3,320(%ebp)
+ psrlq $32,%mm3
+ movd %mm3,704(%edx)
+
+ movd 100(%ebx),%mm5
+ pfadd %mm5,%mm4
+ movq %mm4,%mm6
+ pfadd %mm1,%mm6
+ movd %mm6,192(%ebp)
+ psrlq $32,%mm6
+ movd %mm6,832(%edx)
+ movd 68(%ebx),%mm1
+ pfadd %mm1,%mm4
+ movd %mm4,64(%ebp)
+ psrlq $32,%mm4
+ movd %mm4,960(%edx)
+
+ # femms
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ popl %ebp
+ addl $256,%esp
+
+ ret
+
diff --git a/mpg123_artsplugin/mpg123/dct64_MMX.s b/mpg123_artsplugin/mpg123/dct64_MMX.s
new file mode 100644
index 00000000..965f4c6a
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/dct64_MMX.s
@@ -0,0 +1,836 @@
+.data
+ .align 32
+costab:
+ .long 1056974725
+ .long 1057056395
+ .long 1057223771
+ .long 1057485416
+ .long 1057855544
+ .long 1058356026
+ .long 1059019886
+ .long 1059897405
+ .long 1061067246
+ .long 1062657950
+ .long 1064892987
+ .long 1066774581
+ .long 1069414683
+ .long 1073984175
+ .long 1079645762
+ .long 1092815430
+ .long 1057005197
+ .long 1057342072
+ .long 1058087743
+ .long 1059427869
+ .long 1061799040
+ .long 1065862217
+ .long 1071413542
+ .long 1084439708
+ .long 1057128951
+ .long 1058664893
+ .long 1063675095
+ .long 1076102863
+ .long 1057655764
+ .long 1067924853
+ .long 1060439283
+
+.text
+
+ .align 32
+.globl dct64
+dct64:
+
+ xorl %ecx,%ecx
+.globl dct64_MMX
+dct64_MMX:
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ subl $256,%esp
+ movl 280(%esp),%eax
+ flds (%eax)
+ leal 128(%esp),%edx
+ fadds 124(%eax)
+ movl 272(%esp),%esi
+ fstps (%edx)
+ movl 276(%esp),%edi
+ flds 4(%eax)
+ movl $costab,%ebx
+ fadds 120(%eax)
+ orl %ecx,%ecx
+ fstps 4(%edx)
+ flds (%eax)
+ movl %esp,%ecx
+ fsubs 124(%eax)
+ fmuls (%ebx)
+ fstps 124(%edx)
+ flds 4(%eax)
+ fsubs 120(%eax)
+ fmuls 4(%ebx)
+ fstps 120(%edx)
+ flds 8(%eax)
+ fadds 116(%eax)
+ fstps 8(%edx)
+ flds 12(%eax)
+ fadds 112(%eax)
+ fstps 12(%edx)
+ flds 8(%eax)
+ fsubs 116(%eax)
+ fmuls 8(%ebx)
+ fstps 116(%edx)
+ flds 12(%eax)
+ fsubs 112(%eax)
+ fmuls 12(%ebx)
+ fstps 112(%edx)
+ flds 16(%eax)
+ fadds 108(%eax)
+ fstps 16(%edx)
+ flds 20(%eax)
+ fadds 104(%eax)
+ fstps 20(%edx)
+ flds 16(%eax)
+ fsubs 108(%eax)
+ fmuls 16(%ebx)
+ fstps 108(%edx)
+ flds 20(%eax)
+ fsubs 104(%eax)
+ fmuls 20(%ebx)
+ fstps 104(%edx)
+ flds 24(%eax)
+ fadds 100(%eax)
+ fstps 24(%edx)
+ flds 28(%eax)
+ fadds 96(%eax)
+ fstps 28(%edx)
+ flds 24(%eax)
+ fsubs 100(%eax)
+ fmuls 24(%ebx)
+ fstps 100(%edx)
+ flds 28(%eax)
+ fsubs 96(%eax)
+ fmuls 28(%ebx)
+ fstps 96(%edx)
+ flds 32(%eax)
+ fadds 92(%eax)
+ fstps 32(%edx)
+ flds 36(%eax)
+ fadds 88(%eax)
+ fstps 36(%edx)
+ flds 32(%eax)
+ fsubs 92(%eax)
+ fmuls 32(%ebx)
+ fstps 92(%edx)
+ flds 36(%eax)
+ fsubs 88(%eax)
+ fmuls 36(%ebx)
+ fstps 88(%edx)
+ flds 40(%eax)
+ fadds 84(%eax)
+ fstps 40(%edx)
+ flds 44(%eax)
+ fadds 80(%eax)
+ fstps 44(%edx)
+ flds 40(%eax)
+ fsubs 84(%eax)
+ fmuls 40(%ebx)
+ fstps 84(%edx)
+ flds 44(%eax)
+ fsubs 80(%eax)
+ fmuls 44(%ebx)
+ fstps 80(%edx)
+ flds 48(%eax)
+ fadds 76(%eax)
+ fstps 48(%edx)
+ flds 52(%eax)
+ fadds 72(%eax)
+ fstps 52(%edx)
+ flds 48(%eax)
+ fsubs 76(%eax)
+ fmuls 48(%ebx)
+ fstps 76(%edx)
+ flds 52(%eax)
+ fsubs 72(%eax)
+ fmuls 52(%ebx)
+ fstps 72(%edx)
+ flds 56(%eax)
+ fadds 68(%eax)
+ fstps 56(%edx)
+ flds 60(%eax)
+ fadds 64(%eax)
+ fstps 60(%edx)
+ flds 56(%eax)
+ fsubs 68(%eax)
+ fmuls 56(%ebx)
+ fstps 68(%edx)
+ flds 60(%eax)
+ fsubs 64(%eax)
+ fmuls 60(%ebx)
+ fstps 64(%edx)
+
+ flds (%edx)
+ fadds 60(%edx)
+ fstps (%ecx)
+ flds 4(%edx)
+ fadds 56(%edx)
+ fstps 4(%ecx)
+ flds (%edx)
+ fsubs 60(%edx)
+ fmuls 64(%ebx)
+ fstps 60(%ecx)
+ flds 4(%edx)
+ fsubs 56(%edx)
+ fmuls 68(%ebx)
+ fstps 56(%ecx)
+ flds 8(%edx)
+ fadds 52(%edx)
+ fstps 8(%ecx)
+ flds 12(%edx)
+ fadds 48(%edx)
+ fstps 12(%ecx)
+ flds 8(%edx)
+ fsubs 52(%edx)
+ fmuls 72(%ebx)
+ fstps 52(%ecx)
+ flds 12(%edx)
+ fsubs 48(%edx)
+ fmuls 76(%ebx)
+ fstps 48(%ecx)
+ flds 16(%edx)
+ fadds 44(%edx)
+ fstps 16(%ecx)
+ flds 20(%edx)
+ fadds 40(%edx)
+ fstps 20(%ecx)
+ flds 16(%edx)
+ fsubs 44(%edx)
+ fmuls 80(%ebx)
+ fstps 44(%ecx)
+ flds 20(%edx)
+ fsubs 40(%edx)
+ fmuls 84(%ebx)
+ fstps 40(%ecx)
+ flds 24(%edx)
+ fadds 36(%edx)
+ fstps 24(%ecx)
+ flds 28(%edx)
+ fadds 32(%edx)
+ fstps 28(%ecx)
+ flds 24(%edx)
+ fsubs 36(%edx)
+ fmuls 88(%ebx)
+ fstps 36(%ecx)
+ flds 28(%edx)
+ fsubs 32(%edx)
+ fmuls 92(%ebx)
+ fstps 32(%ecx)
+
+ flds 64(%edx)
+ fadds 124(%edx)
+ fstps 64(%ecx)
+ flds 68(%edx)
+ fadds 120(%edx)
+ fstps 68(%ecx)
+ flds 124(%edx)
+ fsubs 64(%edx)
+ fmuls 64(%ebx)
+ fstps 124(%ecx)
+ flds 120(%edx)
+ fsubs 68(%edx)
+ fmuls 68(%ebx)
+ fstps 120(%ecx)
+ flds 72(%edx)
+ fadds 116(%edx)
+ fstps 72(%ecx)
+ flds 76(%edx)
+ fadds 112(%edx)
+ fstps 76(%ecx)
+ flds 116(%edx)
+ fsubs 72(%edx)
+ fmuls 72(%ebx)
+ fstps 116(%ecx)
+ flds 112(%edx)
+ fsubs 76(%edx)
+ fmuls 76(%ebx)
+ fstps 112(%ecx)
+ flds 80(%edx)
+ fadds 108(%edx)
+ fstps 80(%ecx)
+ flds 84(%edx)
+ fadds 104(%edx)
+ fstps 84(%ecx)
+ flds 108(%edx)
+ fsubs 80(%edx)
+ fmuls 80(%ebx)
+ fstps 108(%ecx)
+ flds 104(%edx)
+ fsubs 84(%edx)
+ fmuls 84(%ebx)
+ fstps 104(%ecx)
+ flds 88(%edx)
+ fadds 100(%edx)
+ fstps 88(%ecx)
+ flds 92(%edx)
+ fadds 96(%edx)
+ fstps 92(%ecx)
+ flds 100(%edx)
+ fsubs 88(%edx)
+ fmuls 88(%ebx)
+ fstps 100(%ecx)
+ flds 96(%edx)
+ fsubs 92(%edx)
+ fmuls 92(%ebx)
+ fstps 96(%ecx)
+
+ flds (%ecx)
+ fadds 28(%ecx)
+ fstps (%edx)
+ flds (%ecx)
+ fsubs 28(%ecx)
+ fmuls 96(%ebx)
+ fstps 28(%edx)
+ flds 4(%ecx)
+ fadds 24(%ecx)
+ fstps 4(%edx)
+ flds 4(%ecx)
+ fsubs 24(%ecx)
+ fmuls 100(%ebx)
+ fstps 24(%edx)
+ flds 8(%ecx)
+ fadds 20(%ecx)
+ fstps 8(%edx)
+ flds 8(%ecx)
+ fsubs 20(%ecx)
+ fmuls 104(%ebx)
+ fstps 20(%edx)
+ flds 12(%ecx)
+ fadds 16(%ecx)
+ fstps 12(%edx)
+ flds 12(%ecx)
+ fsubs 16(%ecx)
+ fmuls 108(%ebx)
+ fstps 16(%edx)
+ flds 32(%ecx)
+ fadds 60(%ecx)
+ fstps 32(%edx)
+ flds 60(%ecx)
+ fsubs 32(%ecx)
+ fmuls 96(%ebx)
+ fstps 60(%edx)
+ flds 36(%ecx)
+ fadds 56(%ecx)
+ fstps 36(%edx)
+ flds 56(%ecx)
+ fsubs 36(%ecx)
+ fmuls 100(%ebx)
+ fstps 56(%edx)
+ flds 40(%ecx)
+ fadds 52(%ecx)
+ fstps 40(%edx)
+ flds 52(%ecx)
+ fsubs 40(%ecx)
+ fmuls 104(%ebx)
+ fstps 52(%edx)
+ flds 44(%ecx)
+ fadds 48(%ecx)
+ fstps 44(%edx)
+ flds 48(%ecx)
+ fsubs 44(%ecx)
+ fmuls 108(%ebx)
+ fstps 48(%edx)
+ flds 64(%ecx)
+ fadds 92(%ecx)
+ fstps 64(%edx)
+ flds 64(%ecx)
+ fsubs 92(%ecx)
+ fmuls 96(%ebx)
+ fstps 92(%edx)
+ flds 68(%ecx)
+ fadds 88(%ecx)
+ fstps 68(%edx)
+ flds 68(%ecx)
+ fsubs 88(%ecx)
+ fmuls 100(%ebx)
+ fstps 88(%edx)
+ flds 72(%ecx)
+ fadds 84(%ecx)
+ fstps 72(%edx)
+ flds 72(%ecx)
+ fsubs 84(%ecx)
+ fmuls 104(%ebx)
+ fstps 84(%edx)
+ flds 76(%ecx)
+ fadds 80(%ecx)
+ fstps 76(%edx)
+ flds 76(%ecx)
+ fsubs 80(%ecx)
+ fmuls 108(%ebx)
+ fstps 80(%edx)
+ flds 96(%ecx)
+ fadds 124(%ecx)
+ fstps 96(%edx)
+ flds 124(%ecx)
+ fsubs 96(%ecx)
+ fmuls 96(%ebx)
+ fstps 124(%edx)
+ flds 100(%ecx)
+ fadds 120(%ecx)
+ fstps 100(%edx)
+ flds 120(%ecx)
+ fsubs 100(%ecx)
+ fmuls 100(%ebx)
+ fstps 120(%edx)
+ flds 104(%ecx)
+ fadds 116(%ecx)
+ fstps 104(%edx)
+ flds 116(%ecx)
+ fsubs 104(%ecx)
+ fmuls 104(%ebx)
+ fstps 116(%edx)
+ flds 108(%ecx)
+ fadds 112(%ecx)
+ fstps 108(%edx)
+ flds 112(%ecx)
+ fsubs 108(%ecx)
+ fmuls 108(%ebx)
+ fstps 112(%edx)
+ flds (%edx)
+ fadds 12(%edx)
+ fstps (%ecx)
+ flds (%edx)
+ fsubs 12(%edx)
+ fmuls 112(%ebx)
+ fstps 12(%ecx)
+ flds 4(%edx)
+ fadds 8(%edx)
+ fstps 4(%ecx)
+ flds 4(%edx)
+ fsubs 8(%edx)
+ fmuls 116(%ebx)
+ fstps 8(%ecx)
+ flds 16(%edx)
+ fadds 28(%edx)
+ fstps 16(%ecx)
+ flds 28(%edx)
+ fsubs 16(%edx)
+ fmuls 112(%ebx)
+ fstps 28(%ecx)
+ flds 20(%edx)
+ fadds 24(%edx)
+ fstps 20(%ecx)
+ flds 24(%edx)
+ fsubs 20(%edx)
+ fmuls 116(%ebx)
+ fstps 24(%ecx)
+ flds 32(%edx)
+ fadds 44(%edx)
+ fstps 32(%ecx)
+ flds 32(%edx)
+ fsubs 44(%edx)
+ fmuls 112(%ebx)
+ fstps 44(%ecx)
+ flds 36(%edx)
+ fadds 40(%edx)
+ fstps 36(%ecx)
+ flds 36(%edx)
+ fsubs 40(%edx)
+ fmuls 116(%ebx)
+ fstps 40(%ecx)
+ flds 48(%edx)
+ fadds 60(%edx)
+ fstps 48(%ecx)
+ flds 60(%edx)
+ fsubs 48(%edx)
+ fmuls 112(%ebx)
+ fstps 60(%ecx)
+ flds 52(%edx)
+ fadds 56(%edx)
+ fstps 52(%ecx)
+ flds 56(%edx)
+ fsubs 52(%edx)
+ fmuls 116(%ebx)
+ fstps 56(%ecx)
+ flds 64(%edx)
+ fadds 76(%edx)
+ fstps 64(%ecx)
+ flds 64(%edx)
+ fsubs 76(%edx)
+ fmuls 112(%ebx)
+ fstps 76(%ecx)
+ flds 68(%edx)
+ fadds 72(%edx)
+ fstps 68(%ecx)
+ flds 68(%edx)
+ fsubs 72(%edx)
+ fmuls 116(%ebx)
+ fstps 72(%ecx)
+ flds 80(%edx)
+ fadds 92(%edx)
+ fstps 80(%ecx)
+ flds 92(%edx)
+ fsubs 80(%edx)
+ fmuls 112(%ebx)
+ fstps 92(%ecx)
+ flds 84(%edx)
+ fadds 88(%edx)
+ fstps 84(%ecx)
+ flds 88(%edx)
+ fsubs 84(%edx)
+ fmuls 116(%ebx)
+ fstps 88(%ecx)
+ flds 96(%edx)
+ fadds 108(%edx)
+ fstps 96(%ecx)
+ flds 96(%edx)
+ fsubs 108(%edx)
+ fmuls 112(%ebx)
+ fstps 108(%ecx)
+ flds 100(%edx)
+ fadds 104(%edx)
+ fstps 100(%ecx)
+ flds 100(%edx)
+ fsubs 104(%edx)
+ fmuls 116(%ebx)
+ fstps 104(%ecx)
+ flds 112(%edx)
+ fadds 124(%edx)
+ fstps 112(%ecx)
+ flds 124(%edx)
+ fsubs 112(%edx)
+ fmuls 112(%ebx)
+ fstps 124(%ecx)
+ flds 116(%edx)
+ fadds 120(%edx)
+ fstps 116(%ecx)
+ flds 120(%edx)
+ fsubs 116(%edx)
+ fmuls 116(%ebx)
+ fstps 120(%ecx)
+
+ flds 32(%ecx)
+ fadds 36(%ecx)
+ fstps 32(%edx)
+ flds 32(%ecx)
+ fsubs 36(%ecx)
+ fmuls 120(%ebx)
+ fstps 36(%edx)
+ flds 44(%ecx)
+ fsubs 40(%ecx)
+ fmuls 120(%ebx)
+ fsts 44(%edx)
+ fadds 40(%ecx)
+ fadds 44(%ecx)
+ fstps 40(%edx)
+ flds 48(%ecx)
+ fsubs 52(%ecx)
+ fmuls 120(%ebx)
+ flds 60(%ecx)
+ fsubs 56(%ecx)
+ fmuls 120(%ebx)
+ fld %st(0)
+ fadds 56(%ecx)
+ fadds 60(%ecx)
+ fld %st(0)
+ fadds 48(%ecx)
+ fadds 52(%ecx)
+ fstps 48(%edx)
+ fadd %st(2)
+ fstps 56(%edx)
+ fsts 60(%edx)
+ faddp %st(1)
+ fstps 52(%edx)
+ flds 64(%ecx)
+ fadds 68(%ecx)
+ fstps 64(%edx)
+ flds 64(%ecx)
+ fsubs 68(%ecx)
+ fmuls 120(%ebx)
+ fstps 68(%edx)
+ flds 76(%ecx)
+ fsubs 72(%ecx)
+ fmuls 120(%ebx)
+ fsts 76(%edx)
+ fadds 72(%ecx)
+ fadds 76(%ecx)
+ fstps 72(%edx)
+ flds 92(%ecx)
+ fsubs 88(%ecx)
+ fmuls 120(%ebx)
+ fsts 92(%edx)
+ fadds 92(%ecx)
+ fadds 88(%ecx)
+ fld %st(0)
+ fadds 80(%ecx)
+ fadds 84(%ecx)
+ fstps 80(%edx)
+ flds 80(%ecx)
+ fsubs 84(%ecx)
+ fmuls 120(%ebx)
+ fadd %st(0), %st(1)
+ fadds 92(%edx)
+ fstps 84(%edx)
+ fstps 88(%edx)
+ flds 96(%ecx)
+ fadds 100(%ecx)
+ fstps 96(%edx)
+ flds 96(%ecx)
+ fsubs 100(%ecx)
+ fmuls 120(%ebx)
+ fstps 100(%edx)
+ flds 108(%ecx)
+ fsubs 104(%ecx)
+ fmuls 120(%ebx)
+ fsts 108(%edx)
+ fadds 104(%ecx)
+ fadds 108(%ecx)
+ fstps 104(%edx)
+ flds 124(%ecx)
+ fsubs 120(%ecx)
+ fmuls 120(%ebx)
+ fsts 124(%edx)
+ fadds 120(%ecx)
+ fadds 124(%ecx)
+ fld %st(0)
+ fadds 112(%ecx)
+ fadds 116(%ecx)
+ fstps 112(%edx)
+ flds 112(%ecx)
+ fsubs 116(%ecx)
+ fmuls 120(%ebx)
+ fadd %st(0),%st(1)
+ fadds 124(%edx)
+ fstps 116(%edx)
+ fstps 120(%edx)
+ jnz .L01
+
+ flds (%ecx)
+ fadds 4(%ecx)
+ fstps 1024(%esi)
+ flds (%ecx)
+ fsubs 4(%ecx)
+ fmuls 120(%ebx)
+ fsts (%esi)
+ fstps (%edi)
+ flds 12(%ecx)
+ fsubs 8(%ecx)
+ fmuls 120(%ebx)
+ fsts 512(%edi)
+ fadds 12(%ecx)
+ fadds 8(%ecx)
+ fstps 512(%esi)
+ flds 16(%ecx)
+ fsubs 20(%ecx)
+ fmuls 120(%ebx)
+ flds 28(%ecx)
+ fsubs 24(%ecx)
+ fmuls 120(%ebx)
+ fsts 768(%edi)
+ fld %st(0)
+ fadds 24(%ecx)
+ fadds 28(%ecx)
+ fld %st(0)
+ fadds 16(%ecx)
+ fadds 20(%ecx)
+ fstps 768(%esi)
+ fadd %st(2)
+ fstps 256(%esi)
+ faddp %st(1)
+ fstps 256(%edi)
+
+ flds 32(%edx)
+ fadds 48(%edx)
+ fstps 896(%esi)
+ flds 48(%edx)
+ fadds 40(%edx)
+ fstps 640(%esi)
+ flds 40(%edx)
+ fadds 56(%edx)
+ fstps 384(%esi)
+ flds 56(%edx)
+ fadds 36(%edx)
+ fstps 128(%esi)
+ flds 36(%edx)
+ fadds 52(%edx)
+ fstps 128(%edi)
+ flds 52(%edx)
+ fadds 44(%edx)
+ fstps 384(%edi)
+ flds 60(%edx)
+ fsts 896(%edi)
+ fadds 44(%edx)
+ fstps 640(%edi)
+ flds 96(%edx)
+ fadds 112(%edx)
+ fld %st(0)
+ fadds 64(%edx)
+ fstps 960(%esi)
+ fadds 80(%edx)
+ fstps 832(%esi)
+ flds 112(%edx)
+ fadds 104(%edx)
+ fld %st(0)
+ fadds 80(%edx)
+ fstps 704(%esi)
+ fadds 72(%edx)
+ fstps 576(%esi)
+ flds 104(%edx)
+ fadds 120(%edx)
+ fld %st(0)
+ fadds 72(%edx)
+ fstps 448(%esi)
+ fadds 88(%edx)
+ fstps 320(%esi)
+ flds 120(%edx)
+ fadds 100(%edx)
+ fld %st(0)
+ fadds 88(%edx)
+ fstps 192(%esi)
+ fadds 68(%edx)
+ fstps 64(%esi)
+ flds 100(%edx)
+ fadds 116(%edx)
+ fld %st(0)
+ fadds 68(%edx)
+ fstps 64(%edi)
+ fadds 84(%edx)
+ fstps 192(%edi)
+ flds 116(%edx)
+ fadds 108(%edx)
+ fld %st(0)
+ fadds 84(%edx)
+ fstps 320(%edi)
+ fadds 76(%edx)
+ fstps 448(%edi)
+ flds 108(%edx)
+ fadds 124(%edx)
+ fld %st(0)
+ fadds 76(%edx)
+ fstps 576(%edi)
+ fadds 92(%edx)
+ fstps 704(%edi)
+ flds 124(%edx)
+ fsts 960(%edi)
+ fadds 92(%edx)
+ fstps 832(%edi)
+ addl $256,%esp
+ popl %edi
+ popl %esi
+ popl %ebx
+ ret
+.L01:
+ flds (%ecx)
+ fadds 4(%ecx)
+ fistp 512(%esi)
+ flds (%ecx)
+ fsubs 4(%ecx)
+ fmuls 120(%ebx)
+
+ fistp (%esi)
+
+ flds 12(%ecx)
+ fsubs 8(%ecx)
+ fmuls 120(%ebx)
+ fist 256(%edi)
+ fadds 12(%ecx)
+ fadds 8(%ecx)
+ fistp 256(%esi)
+ flds 16(%ecx)
+ fsubs 20(%ecx)
+ fmuls 120(%ebx)
+ flds 28(%ecx)
+ fsubs 24(%ecx)
+ fmuls 120(%ebx)
+ fist 384(%edi)
+ fld %st(0)
+ fadds 24(%ecx)
+ fadds 28(%ecx)
+ fld %st(0)
+ fadds 16(%ecx)
+ fadds 20(%ecx)
+ fistp 384(%esi)
+ fadd %st(2)
+ fistp 128(%esi)
+ faddp %st(1)
+ fistp 128(%edi)
+
+ flds 32(%edx)
+ fadds 48(%edx)
+ fistp 448(%esi)
+ flds 48(%edx)
+ fadds 40(%edx)
+ fistp 320(%esi)
+ flds 40(%edx)
+ fadds 56(%edx)
+ fistp 192(%esi)
+ flds 56(%edx)
+ fadds 36(%edx)
+ fistp 64(%esi)
+ flds 36(%edx)
+ fadds 52(%edx)
+ fistp 64(%edi)
+ flds 52(%edx)
+ fadds 44(%edx)
+ fistp 192(%edi)
+ flds 60(%edx)
+ fist 448(%edi)
+ fadds 44(%edx)
+ fistp 320(%edi)
+ flds 96(%edx)
+ fadds 112(%edx)
+ fld %st(0)
+ fadds 64(%edx)
+ fistp 480(%esi)
+ fadds 80(%edx)
+ fistp 416(%esi)
+ flds 112(%edx)
+ fadds 104(%edx)
+ fld %st(0)
+ fadds 80(%edx)
+ fistp 352(%esi)
+ fadds 72(%edx)
+ fistp 288(%esi)
+ flds 104(%edx)
+ fadds 120(%edx)
+ fld %st(0)
+ fadds 72(%edx)
+ fistp 224(%esi)
+ fadds 88(%edx)
+ fistp 160(%esi)
+ flds 120(%edx)
+ fadds 100(%edx)
+ fld %st(0)
+ fadds 88(%edx)
+ fistp 96(%esi)
+ fadds 68(%edx)
+ fistp 32(%esi)
+ flds 100(%edx)
+ fadds 116(%edx)
+ fld %st(0)
+ fadds 68(%edx)
+ fistp 32(%edi)
+ fadds 84(%edx)
+ fistp 96(%edi)
+ flds 116(%edx)
+ fadds 108(%edx)
+ fld %st(0)
+ fadds 84(%edx)
+ fistp 160(%edi)
+ fadds 76(%edx)
+ fistp 224(%edi)
+ flds 108(%edx)
+ fadds 124(%edx)
+ fld %st(0)
+ fadds 76(%edx)
+ fistp 288(%edi)
+ fadds 92(%edx)
+ fistp 352(%edi)
+ flds 124(%edx)
+ fist 480(%edi)
+ fadds 92(%edx)
+ fistp 416(%edi)
+ movsw
+ addl $256,%esp
+ popl %edi
+ popl %esi
+ popl %ebx
+ ret
+
+
diff --git a/mpg123_artsplugin/mpg123/dct64_i386.c b/mpg123_artsplugin/mpg123/dct64_i386.c
new file mode 100644
index 00000000..6d42c79d
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/dct64_i386.c
@@ -0,0 +1,329 @@
+
+/*
+ * Discrete Cosine Tansform (DCT) for subband synthesis
+ * optimized for machines with no auto-increment.
+ * The performance is highly compiler dependent. Maybe
+ * the dct64.c version for 'normal' processor may be faster
+ * even for Intel processors.
+ */
+
+#include "mpg123.h"
+
+static void dct64_1(real *out0,real *out1,real *b1,real *b2,real *samples)
+{
+ {
+ register real *costab = pnts[0];
+
+ b1[0x00] = samples[0x00] + samples[0x1F];
+ b1[0x01] = samples[0x01] + samples[0x1E];
+ b1[0x1F] = (samples[0x00] - samples[0x1F]) * costab[0x0];
+ b1[0x1E] = (samples[0x01] - samples[0x1E]) * costab[0x1];
+
+ b1[0x02] = samples[0x02] + samples[0x1D];
+ b1[0x03] = samples[0x03] + samples[0x1C];
+ b1[0x1D] = (samples[0x02] - samples[0x1D]) * costab[0x2];
+ b1[0x1C] = (samples[0x03] - samples[0x1C]) * costab[0x3];
+
+ b1[0x04] = samples[0x04] + samples[0x1B];
+ b1[0x05] = samples[0x05] + samples[0x1A];
+ b1[0x1B] = (samples[0x04] - samples[0x1B]) * costab[0x4];
+ b1[0x1A] = (samples[0x05] - samples[0x1A]) * costab[0x5];
+
+ b1[0x06] = samples[0x06] + samples[0x19];
+ b1[0x07] = samples[0x07] + samples[0x18];
+ b1[0x19] = (samples[0x06] - samples[0x19]) * costab[0x6];
+ b1[0x18] = (samples[0x07] - samples[0x18]) * costab[0x7];
+
+ b1[0x08] = samples[0x08] + samples[0x17];
+ b1[0x09] = samples[0x09] + samples[0x16];
+ b1[0x17] = (samples[0x08] - samples[0x17]) * costab[0x8];
+ b1[0x16] = (samples[0x09] - samples[0x16]) * costab[0x9];
+
+ b1[0x0A] = samples[0x0A] + samples[0x15];
+ b1[0x0B] = samples[0x0B] + samples[0x14];
+ b1[0x15] = (samples[0x0A] - samples[0x15]) * costab[0xA];
+ b1[0x14] = (samples[0x0B] - samples[0x14]) * costab[0xB];
+
+ b1[0x0C] = samples[0x0C] + samples[0x13];
+ b1[0x0D] = samples[0x0D] + samples[0x12];
+ b1[0x13] = (samples[0x0C] - samples[0x13]) * costab[0xC];
+ b1[0x12] = (samples[0x0D] - samples[0x12]) * costab[0xD];
+
+ b1[0x0E] = samples[0x0E] + samples[0x11];
+ b1[0x0F] = samples[0x0F] + samples[0x10];
+ b1[0x11] = (samples[0x0E] - samples[0x11]) * costab[0xE];
+ b1[0x10] = (samples[0x0F] - samples[0x10]) * costab[0xF];
+
+ }
+
+
+ {
+ register real *costab = pnts[1];
+
+ b2[0x00] = b1[0x00] + b1[0x0F];
+ b2[0x01] = b1[0x01] + b1[0x0E];
+ b2[0x0F] = (b1[0x00] - b1[0x0F]) * costab[0];
+ b2[0x0E] = (b1[0x01] - b1[0x0E]) * costab[1];
+
+ b2[0x02] = b1[0x02] + b1[0x0D];
+ b2[0x03] = b1[0x03] + b1[0x0C];
+ b2[0x0D] = (b1[0x02] - b1[0x0D]) * costab[2];
+ b2[0x0C] = (b1[0x03] - b1[0x0C]) * costab[3];
+
+ b2[0x04] = b1[0x04] + b1[0x0B];
+ b2[0x05] = b1[0x05] + b1[0x0A];
+ b2[0x0B] = (b1[0x04] - b1[0x0B]) * costab[4];
+ b2[0x0A] = (b1[0x05] - b1[0x0A]) * costab[5];
+
+ b2[0x06] = b1[0x06] + b1[0x09];
+ b2[0x07] = b1[0x07] + b1[0x08];
+ b2[0x09] = (b1[0x06] - b1[0x09]) * costab[6];
+ b2[0x08] = (b1[0x07] - b1[0x08]) * costab[7];
+
+ /* */
+
+ b2[0x10] = b1[0x10] + b1[0x1F];
+ b2[0x11] = b1[0x11] + b1[0x1E];
+ b2[0x1F] = (b1[0x1F] - b1[0x10]) * costab[0];
+ b2[0x1E] = (b1[0x1E] - b1[0x11]) * costab[1];
+
+ b2[0x12] = b1[0x12] + b1[0x1D];
+ b2[0x13] = b1[0x13] + b1[0x1C];
+ b2[0x1D] = (b1[0x1D] - b1[0x12]) * costab[2];
+ b2[0x1C] = (b1[0x1C] - b1[0x13]) * costab[3];
+
+ b2[0x14] = b1[0x14] + b1[0x1B];
+ b2[0x15] = b1[0x15] + b1[0x1A];
+ b2[0x1B] = (b1[0x1B] - b1[0x14]) * costab[4];
+ b2[0x1A] = (b1[0x1A] - b1[0x15]) * costab[5];
+
+ b2[0x16] = b1[0x16] + b1[0x19];
+ b2[0x17] = b1[0x17] + b1[0x18];
+ b2[0x19] = (b1[0x19] - b1[0x16]) * costab[6];
+ b2[0x18] = (b1[0x18] - b1[0x17]) * costab[7];
+ }
+
+ {
+ register real *costab = pnts[2];
+
+ b1[0x00] = b2[0x00] + b2[0x07];
+ b1[0x07] = (b2[0x00] - b2[0x07]) * costab[0];
+ b1[0x01] = b2[0x01] + b2[0x06];
+ b1[0x06] = (b2[0x01] - b2[0x06]) * costab[1];
+ b1[0x02] = b2[0x02] + b2[0x05];
+ b1[0x05] = (b2[0x02] - b2[0x05]) * costab[2];
+ b1[0x03] = b2[0x03] + b2[0x04];
+ b1[0x04] = (b2[0x03] - b2[0x04]) * costab[3];
+
+ b1[0x08] = b2[0x08] + b2[0x0F];
+ b1[0x0F] = (b2[0x0F] - b2[0x08]) * costab[0];
+ b1[0x09] = b2[0x09] + b2[0x0E];
+ b1[0x0E] = (b2[0x0E] - b2[0x09]) * costab[1];
+ b1[0x0A] = b2[0x0A] + b2[0x0D];
+ b1[0x0D] = (b2[0x0D] - b2[0x0A]) * costab[2];
+ b1[0x0B] = b2[0x0B] + b2[0x0C];
+ b1[0x0C] = (b2[0x0C] - b2[0x0B]) * costab[3];
+
+ b1[0x10] = b2[0x10] + b2[0x17];
+ b1[0x17] = (b2[0x10] - b2[0x17]) * costab[0];
+ b1[0x11] = b2[0x11] + b2[0x16];
+ b1[0x16] = (b2[0x11] - b2[0x16]) * costab[1];
+ b1[0x12] = b2[0x12] + b2[0x15];
+ b1[0x15] = (b2[0x12] - b2[0x15]) * costab[2];
+ b1[0x13] = b2[0x13] + b2[0x14];
+ b1[0x14] = (b2[0x13] - b2[0x14]) * costab[3];
+
+ b1[0x18] = b2[0x18] + b2[0x1F];
+ b1[0x1F] = (b2[0x1F] - b2[0x18]) * costab[0];
+ b1[0x19] = b2[0x19] + b2[0x1E];
+ b1[0x1E] = (b2[0x1E] - b2[0x19]) * costab[1];
+ b1[0x1A] = b2[0x1A] + b2[0x1D];
+ b1[0x1D] = (b2[0x1D] - b2[0x1A]) * costab[2];
+ b1[0x1B] = b2[0x1B] + b2[0x1C];
+ b1[0x1C] = (b2[0x1C] - b2[0x1B]) * costab[3];
+ }
+
+ {
+ register real const cos0 = pnts[3][0];
+ register real const cos1 = pnts[3][1];
+
+ b2[0x00] = b1[0x00] + b1[0x03];
+ b2[0x03] = (b1[0x00] - b1[0x03]) * cos0;
+ b2[0x01] = b1[0x01] + b1[0x02];
+ b2[0x02] = (b1[0x01] - b1[0x02]) * cos1;
+
+ b2[0x04] = b1[0x04] + b1[0x07];
+ b2[0x07] = (b1[0x07] - b1[0x04]) * cos0;
+ b2[0x05] = b1[0x05] + b1[0x06];
+ b2[0x06] = (b1[0x06] - b1[0x05]) * cos1;
+
+ b2[0x08] = b1[0x08] + b1[0x0B];
+ b2[0x0B] = (b1[0x08] - b1[0x0B]) * cos0;
+ b2[0x09] = b1[0x09] + b1[0x0A];
+ b2[0x0A] = (b1[0x09] - b1[0x0A]) * cos1;
+
+ b2[0x0C] = b1[0x0C] + b1[0x0F];
+ b2[0x0F] = (b1[0x0F] - b1[0x0C]) * cos0;
+ b2[0x0D] = b1[0x0D] + b1[0x0E];
+ b2[0x0E] = (b1[0x0E] - b1[0x0D]) * cos1;
+
+ b2[0x10] = b1[0x10] + b1[0x13];
+ b2[0x13] = (b1[0x10] - b1[0x13]) * cos0;
+ b2[0x11] = b1[0x11] + b1[0x12];
+ b2[0x12] = (b1[0x11] - b1[0x12]) * cos1;
+
+ b2[0x14] = b1[0x14] + b1[0x17];
+ b2[0x17] = (b1[0x17] - b1[0x14]) * cos0;
+ b2[0x15] = b1[0x15] + b1[0x16];
+ b2[0x16] = (b1[0x16] - b1[0x15]) * cos1;
+
+ b2[0x18] = b1[0x18] + b1[0x1B];
+ b2[0x1B] = (b1[0x18] - b1[0x1B]) * cos0;
+ b2[0x19] = b1[0x19] + b1[0x1A];
+ b2[0x1A] = (b1[0x19] - b1[0x1A]) * cos1;
+
+ b2[0x1C] = b1[0x1C] + b1[0x1F];
+ b2[0x1F] = (b1[0x1F] - b1[0x1C]) * cos0;
+ b2[0x1D] = b1[0x1D] + b1[0x1E];
+ b2[0x1E] = (b1[0x1E] - b1[0x1D]) * cos1;
+ }
+
+ {
+ register real const cos0 = pnts[4][0];
+
+ b1[0x00] = b2[0x00] + b2[0x01];
+ b1[0x01] = (b2[0x00] - b2[0x01]) * cos0;
+ b1[0x02] = b2[0x02] + b2[0x03];
+ b1[0x03] = (b2[0x03] - b2[0x02]) * cos0;
+ b1[0x02] += b1[0x03];
+
+ b1[0x04] = b2[0x04] + b2[0x05];
+ b1[0x05] = (b2[0x04] - b2[0x05]) * cos0;
+ b1[0x06] = b2[0x06] + b2[0x07];
+ b1[0x07] = (b2[0x07] - b2[0x06]) * cos0;
+ b1[0x06] += b1[0x07];
+ b1[0x04] += b1[0x06];
+ b1[0x06] += b1[0x05];
+ b1[0x05] += b1[0x07];
+
+ b1[0x08] = b2[0x08] + b2[0x09];
+ b1[0x09] = (b2[0x08] - b2[0x09]) * cos0;
+ b1[0x0A] = b2[0x0A] + b2[0x0B];
+ b1[0x0B] = (b2[0x0B] - b2[0x0A]) * cos0;
+ b1[0x0A] += b1[0x0B];
+
+ b1[0x0C] = b2[0x0C] + b2[0x0D];
+ b1[0x0D] = (b2[0x0C] - b2[0x0D]) * cos0;
+ b1[0x0E] = b2[0x0E] + b2[0x0F];
+ b1[0x0F] = (b2[0x0F] - b2[0x0E]) * cos0;
+ b1[0x0E] += b1[0x0F];
+ b1[0x0C] += b1[0x0E];
+ b1[0x0E] += b1[0x0D];
+ b1[0x0D] += b1[0x0F];
+
+ b1[0x10] = b2[0x10] + b2[0x11];
+ b1[0x11] = (b2[0x10] - b2[0x11]) * cos0;
+ b1[0x12] = b2[0x12] + b2[0x13];
+ b1[0x13] = (b2[0x13] - b2[0x12]) * cos0;
+ b1[0x12] += b1[0x13];
+
+ b1[0x14] = b2[0x14] + b2[0x15];
+ b1[0x15] = (b2[0x14] - b2[0x15]) * cos0;
+ b1[0x16] = b2[0x16] + b2[0x17];
+ b1[0x17] = (b2[0x17] - b2[0x16]) * cos0;
+ b1[0x16] += b1[0x17];
+ b1[0x14] += b1[0x16];
+ b1[0x16] += b1[0x15];
+ b1[0x15] += b1[0x17];
+
+ b1[0x18] = b2[0x18] + b2[0x19];
+ b1[0x19] = (b2[0x18] - b2[0x19]) * cos0;
+ b1[0x1A] = b2[0x1A] + b2[0x1B];
+ b1[0x1B] = (b2[0x1B] - b2[0x1A]) * cos0;
+ b1[0x1A] += b1[0x1B];
+
+ b1[0x1C] = b2[0x1C] + b2[0x1D];
+ b1[0x1D] = (b2[0x1C] - b2[0x1D]) * cos0;
+ b1[0x1E] = b2[0x1E] + b2[0x1F];
+ b1[0x1F] = (b2[0x1F] - b2[0x1E]) * cos0;
+ b1[0x1E] += b1[0x1F];
+ b1[0x1C] += b1[0x1E];
+ b1[0x1E] += b1[0x1D];
+ b1[0x1D] += b1[0x1F];
+ }
+
+ out0[0x10*16] = b1[0x00];
+ out0[0x10*12] = b1[0x04];
+ out0[0x10* 8] = b1[0x02];
+ out0[0x10* 4] = b1[0x06];
+ out0[0x10* 0] = b1[0x01];
+ out1[0x10* 0] = b1[0x01];
+ out1[0x10* 4] = b1[0x05];
+ out1[0x10* 8] = b1[0x03];
+ out1[0x10*12] = b1[0x07];
+
+#if 1
+ out0[0x10*14] = b1[0x08] + b1[0x0C];
+ out0[0x10*10] = b1[0x0C] + b1[0x0a];
+ out0[0x10* 6] = b1[0x0A] + b1[0x0E];
+ out0[0x10* 2] = b1[0x0E] + b1[0x09];
+ out1[0x10* 2] = b1[0x09] + b1[0x0D];
+ out1[0x10* 6] = b1[0x0D] + b1[0x0B];
+ out1[0x10*10] = b1[0x0B] + b1[0x0F];
+ out1[0x10*14] = b1[0x0F];
+#else
+ b1[0x08] += b1[0x0C];
+ out0[0x10*14] = b1[0x08];
+ b1[0x0C] += b1[0x0a];
+ out0[0x10*10] = b1[0x0C];
+ b1[0x0A] += b1[0x0E];
+ out0[0x10* 6] = b1[0x0A];
+ b1[0x0E] += b1[0x09];
+ out0[0x10* 2] = b1[0x0E];
+ b1[0x09] += b1[0x0D];
+ out1[0x10* 2] = b1[0x09];
+ b1[0x0D] += b1[0x0B];
+ out1[0x10* 6] = b1[0x0D];
+ b1[0x0B] += b1[0x0F];
+ out1[0x10*10] = b1[0x0B];
+ out1[0x10*14] = b1[0x0F];
+#endif
+
+ {
+ real tmp;
+ tmp = b1[0x18] + b1[0x1C];
+ out0[0x10*15] = tmp + b1[0x10];
+ out0[0x10*13] = tmp + b1[0x14];
+ tmp = b1[0x1C] + b1[0x1A];
+ out0[0x10*11] = tmp + b1[0x14];
+ out0[0x10* 9] = tmp + b1[0x12];
+ tmp = b1[0x1A] + b1[0x1E];
+ out0[0x10* 7] = tmp + b1[0x12];
+ out0[0x10* 5] = tmp + b1[0x16];
+ tmp = b1[0x1E] + b1[0x19];
+ out0[0x10* 3] = tmp + b1[0x16];
+ out0[0x10* 1] = tmp + b1[0x11];
+ tmp = b1[0x19] + b1[0x1D];
+ out1[0x10* 1] = tmp + b1[0x11];
+ out1[0x10* 3] = tmp + b1[0x15];
+ tmp = b1[0x1D] + b1[0x1B];
+ out1[0x10* 5] = tmp + b1[0x15];
+ out1[0x10* 7] = tmp + b1[0x13];
+ tmp = b1[0x1B] + b1[0x1F];
+ out1[0x10* 9] = tmp + b1[0x13];
+ out1[0x10*11] = tmp + b1[0x17];
+ out1[0x10*13] = b1[0x17] + b1[0x1F];
+ out1[0x10*15] = b1[0x1F];
+ }
+}
+
+/*
+ * the call via dct64 is a trick to force GCC to use
+ * (new) registers for the b1,b2 pointer to the bufs[xx] field
+ */
+void dct64(real *a,real *b,real *c)
+{
+ real bufs[0x40];
+ dct64_1(a,b,bufs,bufs+0x20,c);
+}
+
diff --git a/mpg123_artsplugin/mpg123/dct64_i486-a.s b/mpg123_artsplugin/mpg123/dct64_i486-a.s
new file mode 100644
index 00000000..37e91730
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/dct64_i486-a.s
@@ -0,0 +1,831 @@
+.section .rodata
+ .align 8
+.LC48:
+ .long 0x80000000,0x42400000
+.text
+ .align 16
+ .globl dct64_1_486_a
+ .type dct64_1_486_a,@function
+dct64_1_486_a:
+ pushl %ebx
+ pushl %edi
+ pushl %esi
+ movl 16(%esp),%esi
+ movl 20(%esp),%ebx
+ fldl .LC48
+
+ fld %st(0)
+ fadds (%esi)
+ fstpl (%ebx)
+
+ fld %st(0)
+ fadds 4(%esi)
+ fstpl 4(%ebx)
+
+ fld %st(0)
+ fadds 8(%esi)
+ fstpl 8(%ebx)
+
+ fld %st(0)
+ fadds 12(%esi)
+ fstpl 12(%ebx)
+
+ fld %st(0)
+ fadds 16(%esi)
+ fstpl 16(%ebx)
+
+ fld %st(0)
+ fadds 20(%esi)
+ fstpl 20(%ebx)
+
+ fld %st(0)
+ fadds 24(%esi)
+ fstpl 24(%ebx)
+
+ fld %st(0)
+ fadds 28(%esi)
+ fstpl 28(%ebx)
+
+ fld %st(0)
+ fadds 32(%esi)
+ fstpl 32(%ebx)
+
+ fld %st(0)
+ fadds 36(%esi)
+ fstpl 36(%ebx)
+
+ fld %st(0)
+ fadds 40(%esi)
+ fstpl 40(%ebx)
+
+ fld %st(0)
+ fadds 44(%esi)
+ fstpl 44(%ebx)
+
+ fld %st(0)
+ fadds 48(%esi)
+ fstpl 48(%ebx)
+
+ fld %st(0)
+ fadds 52(%esi)
+ fstpl 52(%ebx)
+
+ fld %st(0)
+ fadds 56(%esi)
+ fstpl 56(%ebx)
+
+ fld %st(0)
+ fadds 60(%esi)
+ fstpl 60(%ebx)
+
+ fld %st(0)
+ fadds 64(%esi)
+ fstpl 64(%ebx)
+
+ fld %st(0)
+ fadds 68(%esi)
+ fstpl 68(%ebx)
+
+ fld %st(0)
+ fadds 72(%esi)
+ fstpl 72(%ebx)
+
+ fld %st(0)
+ fadds 76(%esi)
+ fstpl 76(%ebx)
+
+ fld %st(0)
+ fadds 80(%esi)
+ fstpl 80(%ebx)
+
+ fld %st(0)
+ fadds 84(%esi)
+ fstpl 84(%ebx)
+
+ fld %st(0)
+ fadds 88(%esi)
+ fstpl 88(%ebx)
+
+ fld %st(0)
+ fadds 92(%esi)
+ fstpl 92(%ebx)
+
+ fld %st(0)
+ fadds 96(%esi)
+ fstpl 96(%ebx)
+
+ fld %st(0)
+ fadds 100(%esi)
+ fstpl 100(%ebx)
+
+ fld %st(0)
+ fadds 104(%esi)
+ fstpl 104(%ebx)
+
+ fld %st(0)
+ fadds 108(%esi)
+ fstpl 108(%ebx)
+
+ fld %st(0)
+ fadds 112(%esi)
+ fstpl 112(%ebx)
+
+ fld %st(0)
+ fadds 116(%esi)
+ fstpl 116(%ebx)
+
+ fld %st(0)
+ fadds 120(%esi)
+ fstpl 120(%ebx)
+
+ fadds 124(%esi)
+ fstpl 124(%ebx)
+
+ mov (%ebx),%eax
+ mov 124(%ebx),%edx
+ add %edx, (%ebx)
+ sub %edx,%eax
+ mov $16403,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,124(%ebx)
+
+ mov 4(%ebx),%eax
+ mov 120(%ebx),%edx
+ add %edx,4(%ebx)
+ sub %edx,%eax
+ mov $16563,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,120(%ebx)
+
+ mov 8(%ebx),%eax
+ mov 116(%ebx),%edx
+ add %edx,8(%ebx)
+ sub %edx,%eax
+ mov $16890,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,116(%ebx)
+
+ mov 12(%ebx),%eax
+ mov 112(%ebx),%edx
+ add %edx,12(%ebx)
+ sub %edx,%eax
+ mov $17401,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,112(%ebx)
+
+ mov 16(%ebx),%eax
+ mov 108(%ebx),%edx
+ add %edx,16(%ebx)
+ sub %edx,%eax
+ mov $18124,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,108(%ebx)
+
+ mov 20(%ebx),%eax
+ mov 104(%ebx),%edx
+ add %edx,20(%ebx)
+ sub %edx,%eax
+ mov $19101,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,104(%ebx)
+
+ mov 24(%ebx),%eax
+ mov 100(%ebx),%edx
+ add %edx,24(%ebx)
+ sub %edx,%eax
+ mov $20398,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,100(%ebx)
+
+ mov 28(%ebx),%eax
+ mov 96(%ebx),%edx
+ add %edx,28(%ebx)
+ sub %edx,%eax
+ mov $22112,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,96(%ebx)
+
+ mov 32(%ebx),%eax
+ mov 92(%ebx),%edx
+ add %edx,32(%ebx)
+ sub %edx,%eax
+ mov $24396,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,92(%ebx)
+
+ mov 36(%ebx),%eax
+ mov 88(%ebx),%edx
+ add %edx,36(%ebx)
+ sub %edx,%eax
+ mov $27503,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,88(%ebx)
+
+ mov 40(%ebx),%eax
+ mov 84(%ebx),%edx
+ add %edx,40(%ebx)
+ sub %edx,%eax
+ mov $31869,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,84(%ebx)
+
+ mov 44(%ebx),%eax
+ mov 80(%ebx),%edx
+ add %edx,44(%ebx)
+ sub %edx,%eax
+ mov $38320,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,80(%ebx)
+
+ mov 48(%ebx),%eax
+ mov 76(%ebx),%edx
+ add %edx,48(%ebx)
+ sub %edx,%eax
+ mov $48633,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,76(%ebx)
+
+ mov 52(%ebx),%eax
+ mov 72(%ebx),%edx
+ add %edx,52(%ebx)
+ sub %edx,%eax
+ mov $67429,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,72(%ebx)
+
+ mov 56(%ebx),%eax
+ mov 68(%ebx),%edx
+ add %edx,56(%ebx)
+ sub %edx,%eax
+ mov $111660,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,68(%ebx)
+
+ mov 60(%ebx),%eax
+ mov 64(%ebx),%edx
+ add %edx,60(%ebx)
+ sub %edx,%eax
+ mov $333906,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,64(%ebx)
+
+ mov (%ebx),%eax
+ mov 60(%ebx),%edx
+ add %edx, (%ebx)
+ sub %edx,%eax
+ mov $16463,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,60(%ebx)
+
+ mov 4(%ebx),%eax
+ mov 56(%ebx),%edx
+ add %edx,4(%ebx)
+ sub %edx,%eax
+ mov $17121,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,56(%ebx)
+
+ mov 8(%ebx),%eax
+ mov 52(%ebx),%edx
+ add %edx,8(%ebx)
+ sub %edx,%eax
+ mov $18577,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,52(%ebx)
+
+ mov 12(%ebx),%eax
+ mov 48(%ebx),%edx
+ add %edx,12(%ebx)
+ sub %edx,%eax
+ mov $21195,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,48(%ebx)
+
+ mov 16(%ebx),%eax
+ mov 44(%ebx),%edx
+ add %edx,16(%ebx)
+ sub %edx,%eax
+ mov $25826,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,44(%ebx)
+
+ mov 20(%ebx),%eax
+ mov 40(%ebx),%edx
+ add %edx,20(%ebx)
+ sub %edx,%eax
+ mov $34756,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,40(%ebx)
+
+ mov 24(%ebx),%eax
+ mov 36(%ebx),%edx
+ add %edx,24(%ebx)
+ sub %edx,%eax
+ mov $56441,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,36(%ebx)
+
+ mov 28(%ebx),%eax
+ mov 32(%ebx),%edx
+ add %edx,28(%ebx)
+ sub %edx,%eax
+ mov $167154,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,32(%ebx)
+
+ mov 124(%ebx),%eax
+ mov 64(%ebx),%edx
+ add %eax,64(%ebx)
+ sub %edx,%eax
+ mov $16463,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,124(%ebx)
+
+ mov 120(%ebx),%eax
+ mov 68(%ebx),%edx
+ add %eax,68(%ebx)
+ sub %edx,%eax
+ mov $17121,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,120(%ebx)
+
+ mov 116(%ebx),%eax
+ mov 72(%ebx),%edx
+ add %eax,72(%ebx)
+ sub %edx,%eax
+ mov $18577,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,116(%ebx)
+
+ mov 112(%ebx),%eax
+ mov 76(%ebx),%edx
+ add %eax,76(%ebx)
+ sub %edx,%eax
+ mov $21195,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,112(%ebx)
+
+ mov 108(%ebx),%eax
+ mov 80(%ebx),%edx
+ add %eax,80(%ebx)
+ sub %edx,%eax
+ mov $25826,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,108(%ebx)
+
+ mov 104(%ebx),%eax
+ mov 84(%ebx),%edx
+ add %eax,84(%ebx)
+ sub %edx,%eax
+ mov $34756,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,104(%ebx)
+
+ mov 100(%ebx),%eax
+ mov 88(%ebx),%edx
+ add %eax,88(%ebx)
+ sub %edx,%eax
+ mov $56441,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,100(%ebx)
+
+ mov 96(%ebx),%eax
+ mov 92(%ebx),%edx
+ add %eax,92(%ebx)
+ sub %edx,%eax
+ mov $167154,%edx
+ imul %edx
+ shrdl $15,%edx,%eax
+ movl %eax,96(%ebx)
+
+ mov $16704,%edi
+ mov $19704,%esi
+
+ mov (%ebx),%eax
+ mov 28(%ebx),%edx
+ add %edx, (%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,28(%ebx)
+
+ mov 4(%ebx),%eax
+ mov 24(%ebx),%edx
+ add %edx,4(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,24(%ebx)
+
+ mov 60(%ebx),%eax
+ mov 32(%ebx),%edx
+ add %eax,32(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,60(%ebx)
+
+ mov 56(%ebx),%eax
+ mov 36(%ebx),%edx
+ add %eax,36(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,56(%ebx)
+
+ mov 64(%ebx),%eax
+ mov 92(%ebx),%edx
+ add %edx,64(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,92(%ebx)
+
+ mov 68(%ebx),%eax
+ mov 88(%ebx),%edx
+ add %edx,68(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,88(%ebx)
+
+ mov 124(%ebx),%eax
+ mov 96(%ebx),%edx
+ add %eax,96(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,124(%ebx)
+
+ mov 120(%ebx),%eax
+ mov 100(%ebx),%edx
+ add %eax,100(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,120(%ebx)
+
+ mov $29490,%edi
+ mov $83981,%esi
+
+ mov 8(%ebx),%eax
+ mov 20(%ebx),%edx
+ add %edx,8(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,20(%ebx)
+
+ mov 12(%ebx),%eax
+ mov 16(%ebx),%edx
+ add %edx,12(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,16(%ebx)
+
+ mov 52(%ebx),%eax
+ mov 40(%ebx),%edx
+ add %eax,40(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,52(%ebx)
+
+ mov 48(%ebx),%eax
+ mov 44(%ebx),%edx
+ add %eax,44(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,48(%ebx)
+
+ mov 72(%ebx),%eax
+ mov 84(%ebx),%edx
+ add %edx,72(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,84(%ebx)
+
+ mov 76(%ebx),%eax
+ mov 80(%ebx),%edx
+ add %edx,76(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,80(%ebx)
+
+ mov 116(%ebx),%eax
+ mov 104(%ebx),%edx
+ add %eax,104(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,116(%ebx)
+
+ mov 112(%ebx),%eax
+ mov 108(%ebx),%edx
+ add %eax,108(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,112(%ebx)
+
+ mov $17733,%edi
+ mov $42813,%esi
+
+ mov (%ebx),%eax
+ mov 12(%ebx),%edx
+ add %edx, (%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,12(%ebx)
+
+ mov 4(%ebx),%eax
+ mov 8(%ebx),%edx
+ add %edx,4(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,8(%ebx)
+
+ mov 28(%ebx),%eax
+ mov 16(%ebx),%edx
+ add %eax,16(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,28(%ebx)
+
+ mov 24(%ebx),%eax
+ mov 20(%ebx),%edx
+ add %eax,20(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,24(%ebx)
+
+ mov 32(%ebx),%eax
+ mov 44(%ebx),%edx
+ add %edx,32(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,44(%ebx)
+
+ mov 36(%ebx),%eax
+ mov 40(%ebx),%edx
+ add %edx,36(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,40(%ebx)
+
+ mov 60(%ebx),%eax
+ mov 48(%ebx),%edx
+ add %eax,48(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,60(%ebx)
+
+ mov 56(%ebx),%eax
+ mov 52(%ebx),%edx
+ add %eax,52(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,56(%ebx)
+
+ mov 64(%ebx),%eax
+ mov 76(%ebx),%edx
+ add %edx,64(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,76(%ebx)
+
+ mov 68(%ebx),%eax
+ mov 72(%ebx),%edx
+ add %edx,68(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,72(%ebx)
+
+ mov 92(%ebx),%eax
+ mov 80(%ebx),%edx
+ add %eax,80(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,92(%ebx)
+
+ mov 88(%ebx),%eax
+ mov 84(%ebx),%edx
+ add %eax,84(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,88(%ebx)
+
+ mov 96(%ebx),%eax
+ mov 108(%ebx),%edx
+ add %edx,96(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,108(%ebx)
+
+ mov 100(%ebx),%eax
+ mov 104(%ebx),%edx
+ add %edx,100(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,104(%ebx)
+
+ mov 124(%ebx),%eax
+ mov 112(%ebx),%edx
+ add %eax,112(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,124(%ebx)
+
+ mov 120(%ebx),%eax
+ mov 116(%ebx),%edx
+ add %eax,116(%ebx)
+ sub %edx,%eax
+ imul %esi
+ shrdl $15,%edx,%eax
+ movl %eax,120(%ebx)
+
+ mov $23170,%edi
+
+ mov (%ebx),%eax
+ mov 4(%ebx),%edx
+ add %edx, (%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,4(%ebx)
+
+ mov 12(%ebx),%eax
+ mov 8(%ebx),%edx
+ add %eax,8(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,12(%ebx)
+
+ mov 16(%ebx),%eax
+ mov 20(%ebx),%edx
+ add %edx,16(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,20(%ebx)
+
+ mov 28(%ebx),%eax
+ mov 24(%ebx),%edx
+ add %eax,24(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,28(%ebx)
+
+ mov 32(%ebx),%eax
+ mov 36(%ebx),%edx
+ add %edx,32(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,36(%ebx)
+
+ mov 44(%ebx),%eax
+ mov 40(%ebx),%edx
+ add %eax,40(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,44(%ebx)
+
+ mov 48(%ebx),%eax
+ mov 52(%ebx),%edx
+ add %edx,48(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,52(%ebx)
+
+ mov 60(%ebx),%eax
+ mov 56(%ebx),%edx
+ add %eax,56(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,60(%ebx)
+
+ mov 64(%ebx),%eax
+ mov 68(%ebx),%edx
+ add %edx,64(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,68(%ebx)
+
+ mov 76(%ebx),%eax
+ mov 72(%ebx),%edx
+ add %eax,72(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,76(%ebx)
+
+ mov 80(%ebx),%eax
+ mov 84(%ebx),%edx
+ add %edx,80(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,84(%ebx)
+
+ mov 92(%ebx),%eax
+ mov 88(%ebx),%edx
+ add %eax,88(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,92(%ebx)
+
+ mov 96(%ebx),%eax
+ mov 100(%ebx),%edx
+ add %edx,96(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,100(%ebx)
+
+ mov 108(%ebx),%eax
+ mov 104(%ebx),%edx
+ add %eax,104(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,108(%ebx)
+
+ mov 112(%ebx),%eax
+ mov 116(%ebx),%edx
+ add %edx,112(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,116(%ebx)
+
+ mov 124(%ebx),%eax
+ mov 120(%ebx),%edx
+ add %eax,120(%ebx)
+ sub %edx,%eax
+ imul %edi
+ shrdl $15,%edx,%eax
+ movl %eax,124(%ebx)
+
+ popl %esi
+ popl %edi
+ popl %ebx
+ ret
+
diff --git a/mpg123_artsplugin/mpg123/dct64_i486-b.c b/mpg123_artsplugin/mpg123/dct64_i486-b.c
new file mode 100644
index 00000000..cb57f57f
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/dct64_i486-b.c
@@ -0,0 +1,140 @@
+/* Discrete Cosine Tansform (DCT) for subband synthesis.
+ *
+ * This code is optimized for 80486. It should be compiled with gcc
+ * 2.7.2 or higher.
+ *
+ * Note: This code does not give the necessary accuracy. Moreover, no
+ * overflow test are done.
+ *
+ * (c) 1998 Fabrice Bellard.
+ *
+ * Rewrite to asm with algorithm and memory optimization
+ *
+ * (c) 2000 Petr Salinger
+ *
+ * GPL clean
+ *
+ */
+
+#include "mpg123.h"
+
+#define COS_0_0 16403
+#define COS_0_1 16563
+#define COS_0_2 16890
+#define COS_0_3 17401
+#define COS_0_4 18124
+#define COS_0_5 19101
+#define COS_0_6 20398
+#define COS_0_7 22112
+#define COS_0_8 24396
+#define COS_0_9 27503
+#define COS_0_10 31869
+#define COS_0_11 38320
+#define COS_0_12 48633
+#define COS_0_13 67429
+#define COS_0_14 111660
+#define COS_0_15 333906
+#define COS_1_0 16463
+#define COS_1_1 17121
+#define COS_1_2 18577
+#define COS_1_3 21195
+#define COS_1_4 25826
+#define COS_1_5 34756
+#define COS_1_6 56441
+#define COS_1_7 167154
+#define COS_2_0 16704
+#define COS_2_1 19704
+#define COS_2_2 29490
+#define COS_2_3 83981
+#define COS_3_0 17733
+#define COS_3_1 42813
+#define COS_4_0 23170
+
+#define SETOUT(out,n,expr) out[FIR_BUFFER_SIZE*(n)]=(expr)
+#define MUL(a,b) (((a)*(b)) >> 15)
+#define MULL(a,b) (((long long)(a)*(long long)(b)) >> 15)
+#define TOINT(a) ((int)((a)*32768.0))
+
+void dct64_1_486_a(real *samples, int *bx);
+
+void dct64_1_486_b(int *out0, int *out1, int *b1)
+{
+ b1[0x02] += b1[0x03];
+ b1[0x06] += b1[0x07];
+ b1[0x04] += b1[0x06];
+ b1[0x06] += b1[0x05];
+ b1[0x05] += b1[0x07];
+
+ b1[0x0A] += b1[0x0B];
+ b1[0x0E] += b1[0x0F];
+ b1[0x0C] += b1[0x0E];
+ b1[0x0E] += b1[0x0D];
+ b1[0x0D] += b1[0x0F];
+
+ b1[0x12] += b1[0x13];
+ b1[0x16] += b1[0x17];
+ b1[0x14] += b1[0x16];
+ b1[0x16] += b1[0x15];
+ b1[0x15] += b1[0x17];
+
+ b1[0x1A] += b1[0x1B];
+ b1[0x1E] += b1[0x1F];
+ b1[0x1C] += b1[0x1E];
+ b1[0x1E] += b1[0x1D];
+ b1[0x1D] += b1[0x1F];
+
+ SETOUT(out0,16,b1[0x00]);
+ SETOUT(out0,12,b1[0x04]);
+ SETOUT(out0, 8,b1[0x02]);
+ SETOUT(out0, 4,b1[0x06]);
+ SETOUT(out0, 0,b1[0x01]);
+ SETOUT(out1, 0,b1[0x01]);
+ SETOUT(out1, 4,b1[0x05]);
+ SETOUT(out1, 8,b1[0x03]);
+ SETOUT(out1,12,b1[0x07]);
+
+ SETOUT(out0,14, b1[0x08] + b1[0x0C]);
+ SETOUT(out0,10, b1[0x0C] + b1[0x0A]);
+ SETOUT(out0, 6, b1[0x0A] + b1[0x0E]);
+ SETOUT(out0, 2, b1[0x0E] + b1[0x09]);
+ SETOUT(out1, 2, b1[0x09] + b1[0x0D]);
+ SETOUT(out1, 6, b1[0x0D] + b1[0x0B]);
+ SETOUT(out1,10, b1[0x0B] + b1[0x0F]);
+ SETOUT(out1,14, b1[0x0F]);
+
+ b1[0x18] += b1[0x1C];
+ SETOUT(out0,15,b1[0x10] + b1[0x18]);
+ SETOUT(out0,13,b1[0x18] + b1[0x14]);
+ b1[0x1C] += b1[0x1a];
+ SETOUT(out0,11,b1[0x14] + b1[0x1C]);
+ SETOUT(out0, 9,b1[0x1C] + b1[0x12]);
+ b1[0x1A] += b1[0x1E];
+ SETOUT(out0, 7,b1[0x12] + b1[0x1A]);
+ SETOUT(out0, 5,b1[0x1A] + b1[0x16]);
+ b1[0x1E] += b1[0x19];
+ SETOUT(out0, 3,b1[0x16] + b1[0x1E]);
+ SETOUT(out0, 1,b1[0x1E] + b1[0x11]);
+ b1[0x19] += b1[0x1D];
+ SETOUT(out1, 1,b1[0x11] + b1[0x19]);
+ SETOUT(out1, 3,b1[0x19] + b1[0x15]);
+ b1[0x1D] += b1[0x1B];
+ SETOUT(out1, 5,b1[0x15] + b1[0x1D]);
+ SETOUT(out1, 7,b1[0x1D] + b1[0x13]);
+ b1[0x1B] += b1[0x1F];
+ SETOUT(out1, 9,b1[0x13] + b1[0x1B]);
+ SETOUT(out1,11,b1[0x1B] + b1[0x17]);
+ SETOUT(out1,13,b1[0x17] + b1[0x1F]);
+ SETOUT(out1,15,b1[0x1F]);
+}
+
+/*
+ * main DCT function
+ */
+void dct64_486(int *a,int *b,real *samples)
+{
+ int bufs[33]; /* 32 + 1 extra for 8B store from x87 */
+
+ dct64_1_486_a(samples,bufs);
+ dct64_1_486_b(a,b,bufs);
+}
+
diff --git a/mpg123_artsplugin/mpg123/dct64_i486.c b/mpg123_artsplugin/mpg123/dct64_i486.c
new file mode 100644
index 00000000..b8f5d08b
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/dct64_i486.c
@@ -0,0 +1,322 @@
+
+/* Discrete Cosine Tansform (DCT) for subband synthesis.
+ *
+ * This code is optimized for 80486. It should be compiled with gcc
+ * 2.7.2 or higher.
+ *
+ * Note: This code does not give the necessary accuracy. Moreover, no
+ * overflow test are done.
+ *
+ * (c) 1998 Fabrice Bellard.
+ *
+ * GPL clean
+ */
+
+#include "mpg123.h"
+
+#define COS_0_0 16403
+#define COS_0_1 16563
+#define COS_0_2 16890
+#define COS_0_3 17401
+#define COS_0_4 18124
+#define COS_0_5 19101
+#define COS_0_6 20398
+#define COS_0_7 22112
+#define COS_0_8 24396
+#define COS_0_9 27503
+#define COS_0_10 31869
+#define COS_0_11 38320
+#define COS_0_12 48633
+#define COS_0_13 67429
+#define COS_0_14 111660
+#define COS_0_15 333906
+#define COS_1_0 16463
+#define COS_1_1 17121
+#define COS_1_2 18577
+#define COS_1_3 21195
+#define COS_1_4 25826
+#define COS_1_5 34756
+#define COS_1_6 56441
+#define COS_1_7 167154
+#define COS_2_0 16704
+#define COS_2_1 19704
+#define COS_2_2 29490
+#define COS_2_3 83981
+#define COS_3_0 17733
+#define COS_3_1 42813
+#define COS_4_0 23170
+
+#define SETOUT(out,n,expr) out[FIR_BUFFER_SIZE*(n)]=(expr)
+#define MUL(a,b) (((a)*(b)) >> 15)
+#define MULL(a,b) (((long long)(a)*(long long)(b)) >> 15)
+#ifdef REAL_IS_FIXED
+#define TOINT(a) ((a) * 32768 / (int)REAL_FACTOR)
+#else
+#define TOINT(a) ((int)((a)*32768.0))
+#endif
+
+void dct64_1_486(int *out0,int *out1,int *b1,int *b2)
+{
+ b1[0x00] = b2[0x00] + b2[0x1F];
+ b1[0x1F] = MUL((b2[0x00] - b2[0x1F]),COS_0_0);
+
+ b1[0x01] = b2[0x01] + b2[0x1E];
+ b1[0x1E] = MUL((b2[0x01] - b2[0x1E]),COS_0_1);
+
+ b1[0x02] = b2[0x02] + b2[0x1D];
+ b1[0x1D] = MUL((b2[0x02] - b2[0x1D]),COS_0_2);
+
+ b1[0x03] = b2[0x03] + b2[0x1C];
+ b1[0x1C] = MUL((b2[0x03] - b2[0x1C]),COS_0_3);
+
+ b1[0x04] = b2[0x04] + b2[0x1B];
+ b1[0x1B] = MUL((b2[0x04] - b2[0x1B]),COS_0_4);
+
+ b1[0x05] = b2[0x05] + b2[0x1A];
+ b1[0x1A] = MUL((b2[0x05] - b2[0x1A]),COS_0_5);
+
+ b1[0x06] = b2[0x06] + b2[0x19];
+ b1[0x19] = MUL((b2[0x06] - b2[0x19]),COS_0_6);
+
+ b1[0x07] = b2[0x07] + b2[0x18];
+ b1[0x18] = MUL((b2[0x07] - b2[0x18]),COS_0_7);
+
+ b1[0x08] = b2[0x08] + b2[0x17];
+ b1[0x17] = MUL((b2[0x08] - b2[0x17]),COS_0_8);
+
+ b1[0x09] = b2[0x09] + b2[0x16];
+ b1[0x16] = MUL((b2[0x09] - b2[0x16]),COS_0_9);
+
+ b1[0x0A] = b2[0x0A] + b2[0x15];
+ b1[0x15] = MUL((b2[0x0A] - b2[0x15]),COS_0_10);
+
+ b1[0x0B] = b2[0x0B] + b2[0x14];
+ b1[0x14] = MUL((b2[0x0B] - b2[0x14]),COS_0_11);
+
+ b1[0x0C] = b2[0x0C] + b2[0x13];
+ b1[0x13] = MUL((b2[0x0C] - b2[0x13]),COS_0_12);
+
+ b1[0x0D] = b2[0x0D] + b2[0x12];
+ b1[0x12] = MULL((b2[0x0D] - b2[0x12]),COS_0_13);
+
+ b1[0x0E] = b2[0x0E] + b2[0x11];
+ b1[0x11] = MULL((b2[0x0E] - b2[0x11]),COS_0_14);
+
+ b1[0x0F] = b2[0x0F] + b2[0x10];
+ b1[0x10] = MULL((b2[0x0F] - b2[0x10]),COS_0_15);
+
+
+ b2[0x00] = b1[0x00] + b1[0x0F];
+ b2[0x0F] = MUL((b1[0x00] - b1[0x0F]),COS_1_0);
+ b2[0x01] = b1[0x01] + b1[0x0E];
+ b2[0x0E] = MUL((b1[0x01] - b1[0x0E]),COS_1_1);
+ b2[0x02] = b1[0x02] + b1[0x0D];
+ b2[0x0D] = MUL((b1[0x02] - b1[0x0D]),COS_1_2);
+ b2[0x03] = b1[0x03] + b1[0x0C];
+ b2[0x0C] = MUL((b1[0x03] - b1[0x0C]),COS_1_3);
+ b2[0x04] = b1[0x04] + b1[0x0B];
+ b2[0x0B] = MUL((b1[0x04] - b1[0x0B]),COS_1_4);
+ b2[0x05] = b1[0x05] + b1[0x0A];
+ b2[0x0A] = MUL((b1[0x05] - b1[0x0A]),COS_1_5);
+ b2[0x06] = b1[0x06] + b1[0x09];
+ b2[0x09] = MUL((b1[0x06] - b1[0x09]),COS_1_6);
+ b2[0x07] = b1[0x07] + b1[0x08];
+ b2[0x08] = MULL((b1[0x07] - b1[0x08]),COS_1_7);
+
+ b2[0x10] = b1[0x10] + b1[0x1F];
+ b2[0x1F] = MUL((b1[0x1F] - b1[0x10]),COS_1_0);
+ b2[0x11] = b1[0x11] + b1[0x1E];
+ b2[0x1E] = MUL((b1[0x1E] - b1[0x11]),COS_1_1);
+ b2[0x12] = b1[0x12] + b1[0x1D];
+ b2[0x1D] = MUL((b1[0x1D] - b1[0x12]),COS_1_2);
+ b2[0x13] = b1[0x13] + b1[0x1C];
+ b2[0x1C] = MUL((b1[0x1C] - b1[0x13]),COS_1_3);
+ b2[0x14] = b1[0x14] + b1[0x1B];
+ b2[0x1B] = MUL((b1[0x1B] - b1[0x14]),COS_1_4);
+ b2[0x15] = b1[0x15] + b1[0x1A];
+ b2[0x1A] = MUL((b1[0x1A] - b1[0x15]),COS_1_5);
+ b2[0x16] = b1[0x16] + b1[0x19];
+ b2[0x19] = MUL((b1[0x19] - b1[0x16]),COS_1_6);
+ b2[0x17] = b1[0x17] + b1[0x18];
+ b2[0x18] = MULL((b1[0x18] - b1[0x17]),COS_1_7);
+
+
+ b1[0x00] = b2[0x00] + b2[0x07];
+ b1[0x07] = MUL((b2[0x00] - b2[0x07]),COS_2_0);
+ b1[0x01] = b2[0x01] + b2[0x06];
+ b1[0x06] = MUL((b2[0x01] - b2[0x06]),COS_2_1);
+ b1[0x02] = b2[0x02] + b2[0x05];
+ b1[0x05] = MUL((b2[0x02] - b2[0x05]),COS_2_2);
+ b1[0x03] = b2[0x03] + b2[0x04];
+ b1[0x04] = MULL((b2[0x03] - b2[0x04]),COS_2_3);
+
+ b1[0x08] = b2[0x08] + b2[0x0F];
+ b1[0x0F] = MUL((b2[0x0F] - b2[0x08]),COS_2_0);
+ b1[0x09] = b2[0x09] + b2[0x0E];
+ b1[0x0E] = MUL((b2[0x0E] - b2[0x09]),COS_2_1);
+ b1[0x0A] = b2[0x0A] + b2[0x0D];
+ b1[0x0D] = MUL((b2[0x0D] - b2[0x0A]),COS_2_2);
+ b1[0x0B] = b2[0x0B] + b2[0x0C];
+ b1[0x0C] = MULL((b2[0x0C] - b2[0x0B]),COS_2_3);
+
+ b1[0x10] = b2[0x10] + b2[0x17];
+ b1[0x17] = MUL((b2[0x10] - b2[0x17]),COS_2_0);
+ b1[0x11] = b2[0x11] + b2[0x16];
+ b1[0x16] = MUL((b2[0x11] - b2[0x16]),COS_2_1);
+ b1[0x12] = b2[0x12] + b2[0x15];
+ b1[0x15] = MUL((b2[0x12] - b2[0x15]),COS_2_2);
+ b1[0x13] = b2[0x13] + b2[0x14];
+ b1[0x14] = MULL((b2[0x13] - b2[0x14]),COS_2_3);
+
+ b1[0x18] = b2[0x18] + b2[0x1F];
+ b1[0x1F] = MUL((b2[0x1F] - b2[0x18]),COS_2_0);
+ b1[0x19] = b2[0x19] + b2[0x1E];
+ b1[0x1E] = MUL((b2[0x1E] - b2[0x19]),COS_2_1);
+ b1[0x1A] = b2[0x1A] + b2[0x1D];
+ b1[0x1D] = MUL((b2[0x1D] - b2[0x1A]),COS_2_2);
+ b1[0x1B] = b2[0x1B] + b2[0x1C];
+ b1[0x1C] = MULL((b2[0x1C] - b2[0x1B]),COS_2_3);
+
+
+ b2[0x00] = b1[0x00] + b1[0x03];
+ b2[0x03] = MUL((b1[0x00] - b1[0x03]),COS_3_0);
+ b2[0x01] = b1[0x01] + b1[0x02];
+ b2[0x02] = MUL((b1[0x01] - b1[0x02]),COS_3_1);
+
+ b2[0x04] = b1[0x04] + b1[0x07];
+ b2[0x07] = MUL((b1[0x07] - b1[0x04]),COS_3_0);
+ b2[0x05] = b1[0x05] + b1[0x06];
+ b2[0x06] = MUL((b1[0x06] - b1[0x05]),COS_3_1);
+
+ b2[0x08] = b1[0x08] + b1[0x0B];
+ b2[0x0B] = MUL((b1[0x08] - b1[0x0B]),COS_3_0);
+ b2[0x09] = b1[0x09] + b1[0x0A];
+ b2[0x0A] = MUL((b1[0x09] - b1[0x0A]),COS_3_1);
+
+ b2[0x0C] = b1[0x0C] + b1[0x0F];
+ b2[0x0F] = MUL((b1[0x0F] - b1[0x0C]),COS_3_0);
+ b2[0x0D] = b1[0x0D] + b1[0x0E];
+ b2[0x0E] = MUL((b1[0x0E] - b1[0x0D]),COS_3_1);
+
+ b2[0x10] = b1[0x10] + b1[0x13];
+ b2[0x13] = MUL((b1[0x10] - b1[0x13]),COS_3_0);
+ b2[0x11] = b1[0x11] + b1[0x12];
+ b2[0x12] = MUL((b1[0x11] - b1[0x12]),COS_3_1);
+
+ b2[0x14] = b1[0x14] + b1[0x17];
+ b2[0x17] = MUL((b1[0x17] - b1[0x14]),COS_3_0);
+ b2[0x15] = b1[0x15] + b1[0x16];
+ b2[0x16] = MUL((b1[0x16] - b1[0x15]),COS_3_1);
+
+ b2[0x18] = b1[0x18] + b1[0x1B];
+ b2[0x1B] = MUL((b1[0x18] - b1[0x1B]),COS_3_0);
+ b2[0x19] = b1[0x19] + b1[0x1A];
+ b2[0x1A] = MUL((b1[0x19] - b1[0x1A]),COS_3_1);
+
+ b2[0x1C] = b1[0x1C] + b1[0x1F];
+ b2[0x1F] = MUL((b1[0x1F] - b1[0x1C]),COS_3_0);
+ b2[0x1D] = b1[0x1D] + b1[0x1E];
+ b2[0x1E] = MUL((b1[0x1E] - b1[0x1D]),COS_3_1);
+
+ {
+ int i;
+ for(i=0;i<32;i+=4) {
+ b1[i+0x00] = b2[i+0x00] + b2[i+0x01];
+ b1[i+0x01] = MUL((b2[i+0x00] - b2[i+0x01]),COS_4_0);
+ b1[i+0x02] = b2[i+0x02] + b2[i+0x03];
+ b1[i+0x03] = MUL((b2[i+0x03] - b2[i+0x02]),COS_4_0);
+ }
+ }
+
+ b1[0x02] += b1[0x03];
+ b1[0x06] += b1[0x07];
+ b1[0x04] += b1[0x06];
+ b1[0x06] += b1[0x05];
+ b1[0x05] += b1[0x07];
+
+ b1[0x0A] += b1[0x0B];
+ b1[0x0E] += b1[0x0F];
+ b1[0x0C] += b1[0x0E];
+ b1[0x0E] += b1[0x0D];
+ b1[0x0D] += b1[0x0F];
+
+ b1[0x12] += b1[0x13];
+ b1[0x16] += b1[0x17];
+ b1[0x14] += b1[0x16];
+ b1[0x16] += b1[0x15];
+ b1[0x15] += b1[0x17];
+
+ b1[0x1A] += b1[0x1B];
+ b1[0x1E] += b1[0x1F];
+ b1[0x1C] += b1[0x1E];
+ b1[0x1E] += b1[0x1D];
+ b1[0x1D] += b1[0x1F];
+
+ SETOUT(out0,16,b1[0x00]);
+ SETOUT(out0,12,b1[0x04]);
+ SETOUT(out0, 8,b1[0x02]);
+ SETOUT(out0, 4,b1[0x06]);
+ SETOUT(out0, 0,b1[0x01]);
+ SETOUT(out1, 0,b1[0x01]);
+ SETOUT(out1, 4,b1[0x05]);
+ SETOUT(out1, 8,b1[0x03]);
+ SETOUT(out1,12,b1[0x07]);
+
+ b1[0x08] += b1[0x0C];
+ SETOUT(out0,14,b1[0x08]);
+ b1[0x0C] += b1[0x0a];
+ SETOUT(out0,10,b1[0x0C]);
+ b1[0x0A] += b1[0x0E];
+ SETOUT(out0, 6,b1[0x0A]);
+ b1[0x0E] += b1[0x09];
+ SETOUT(out0, 2,b1[0x0E]);
+ b1[0x09] += b1[0x0D];
+ SETOUT(out1, 2,b1[0x09]);
+ b1[0x0D] += b1[0x0B];
+ SETOUT(out1, 6,b1[0x0D]);
+ b1[0x0B] += b1[0x0F];
+ SETOUT(out1,10,b1[0x0B]);
+ SETOUT(out1,14,b1[0x0F]);
+
+ b1[0x18] += b1[0x1C];
+ SETOUT(out0,15,b1[0x10] + b1[0x18]);
+ SETOUT(out0,13,b1[0x18] + b1[0x14]);
+ b1[0x1C] += b1[0x1a];
+ SETOUT(out0,11,b1[0x14] + b1[0x1C]);
+ SETOUT(out0, 9,b1[0x1C] + b1[0x12]);
+ b1[0x1A] += b1[0x1E];
+ SETOUT(out0, 7,b1[0x12] + b1[0x1A]);
+ SETOUT(out0, 5,b1[0x1A] + b1[0x16]);
+ b1[0x1E] += b1[0x19];
+ SETOUT(out0, 3,b1[0x16] + b1[0x1E]);
+ SETOUT(out0, 1,b1[0x1E] + b1[0x11]);
+ b1[0x19] += b1[0x1D];
+ SETOUT(out1, 1,b1[0x11] + b1[0x19]);
+ SETOUT(out1, 3,b1[0x19] + b1[0x15]);
+ b1[0x1D] += b1[0x1B];
+ SETOUT(out1, 5,b1[0x15] + b1[0x1D]);
+ SETOUT(out1, 7,b1[0x1D] + b1[0x13]);
+ b1[0x1B] += b1[0x1F];
+ SETOUT(out1, 9,b1[0x13] + b1[0x1B]);
+ SETOUT(out1,11,b1[0x1B] + b1[0x17]);
+ SETOUT(out1,13,b1[0x17] + b1[0x1F]);
+ SETOUT(out1,15,b1[0x1F]);
+}
+
+
+/*
+ * the call via dct64 is a trick to force GCC to use
+ * (new) registers for the b1,b2 pointer to the bufs[xx] field
+ */
+void dct64_486(int *a,int *b,real *samples)
+{
+ int bufs[64];
+ int i;
+
+ for(i=0;i<32;i++) {
+ bufs[i+32]=TOINT(samples[i]);
+ }
+
+ dct64_1_486(a,b,bufs,bufs+0x20);
+}
+
diff --git a/mpg123_artsplugin/mpg123/decode.c b/mpg123_artsplugin/mpg123/decode.c
new file mode 100644
index 00000000..0c7036a8
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/decode.c
@@ -0,0 +1,223 @@
+/*
+ * Mpeg Layer-1,2,3 audio decoder
+ * ------------------------------
+ * copyright (c) 1995,1996,1997 by Michael Hipp, All rights reserved.
+ * See also 'README'
+ *
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include "mpg123.h"
+
+#define WRITE_SAMPLE(samples,sum,clip) \
+ if( (sum) > REAL_PLUS_32767) { *(samples) = 0x7fff; (clip)++; } \
+ else if( (sum) < REAL_MINUS_32768) { *(samples) = -0x8000; (clip)++; } \
+ else { *(samples) = REAL_TO_SHORT(sum); }
+
+int synth_1to1_8bit(real *bandPtr,int channel,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[64];
+ short *tmp1 = samples_tmp + channel;
+ int i,ret;
+ int pnt1=0;
+
+ ret = synth_1to1(bandPtr,channel,(unsigned char *) samples_tmp,&pnt1);
+ samples += channel + *pnt;
+
+ for(i=0;i<32;i++) {
+ *samples = conv16to8[*tmp1>>AUSHIFT];
+ samples += 2;
+ tmp1 += 2;
+ }
+ *pnt += 64;
+
+ return ret;
+}
+
+int synth_1to1_8bit_mono(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[64];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_1to1(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<32;i++) {
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ tmp1 += 2;
+ }
+ *pnt += 32;
+
+ return ret;
+}
+
+int synth_1to1_8bit_mono2stereo(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[64];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_1to1(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<32;i++) {
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ tmp1 += 2;
+ }
+ *pnt += 64;
+
+ return ret;
+}
+
+int synth_1to1_mono(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[64];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_1to1(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<32;i++) {
+ *( (short *)samples) = *tmp1;
+ samples += 2;
+ tmp1 += 2;
+ }
+ *pnt += 64;
+
+ return ret;
+}
+
+
+int synth_1to1_mono2stereo(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ int i,ret;
+
+ ret = synth_1to1(bandPtr,0,samples,pnt);
+ samples = samples + *pnt - 128;
+
+ for(i=0;i<32;i++) {
+ ((short *)samples)[1] = ((short *)samples)[0];
+ samples+=4;
+ }
+
+ return ret;
+}
+
+
+int synth_1to1(real *bandPtr,int channel,unsigned char *out,int *pnt)
+{
+ static real buffs[2][2][0x110];
+ static const int step = 2;
+ static int bo = 1;
+ short *samples = (short *) (out+*pnt);
+
+ real *b0,(*buf)[0x110];
+ int clip = 0;
+ int bo1;
+
+#ifndef NO_EQUALIZER
+ if(param.enable_equalizer)
+ do_equalizer(bandPtr,channel);
+#endif
+
+ if(!channel) {
+ bo--;
+ bo &= 0xf;
+ buf = buffs[0];
+ }
+ else {
+ samples++;
+ buf = buffs[1];
+ }
+
+ if(bo & 0x1) {
+ b0 = buf[0];
+ bo1 = bo;
+ dct64(buf[1]+((bo+1)&0xf),buf[0]+bo,bandPtr);
+ }
+ else {
+ b0 = buf[1];
+ bo1 = bo+1;
+ dct64(buf[0]+bo,buf[1]+bo+1,bandPtr);
+ }
+
+
+ {
+ register int j;
+ real *window = decwin + 16 - bo1;
+
+ for (j=16;j;j--,window+=0x10,samples+=step)
+ {
+ real sum;
+ sum = REAL_MUL(*window++, *b0++);
+ sum -= REAL_MUL(*window++, *b0++);
+ sum += REAL_MUL(*window++, *b0++);
+ sum -= REAL_MUL(*window++, *b0++);
+ sum += REAL_MUL(*window++, *b0++);
+ sum -= REAL_MUL(*window++, *b0++);
+ sum += REAL_MUL(*window++, *b0++);
+ sum -= REAL_MUL(*window++, *b0++);
+ sum += REAL_MUL(*window++, *b0++);
+ sum -= REAL_MUL(*window++, *b0++);
+ sum += REAL_MUL(*window++, *b0++);
+ sum -= REAL_MUL(*window++, *b0++);
+ sum += REAL_MUL(*window++, *b0++);
+ sum -= REAL_MUL(*window++, *b0++);
+ sum += REAL_MUL(*window++, *b0++);
+ sum -= REAL_MUL(*window++, *b0++);
+
+ WRITE_SAMPLE(samples,sum,clip);
+ }
+
+ {
+ real sum;
+ sum = REAL_MUL(window[0x0], b0[0x0]);
+ sum += REAL_MUL(window[0x2], b0[0x2]);
+ sum += REAL_MUL(window[0x4], b0[0x4]);
+ sum += REAL_MUL(window[0x6], b0[0x6]);
+ sum += REAL_MUL(window[0x8], b0[0x8]);
+ sum += REAL_MUL(window[0xA], b0[0xA]);
+ sum += REAL_MUL(window[0xC], b0[0xC]);
+ sum += REAL_MUL(window[0xE], b0[0xE]);
+ WRITE_SAMPLE(samples,sum,clip);
+ b0-=0x10,window-=0x20,samples+=step;
+ }
+ window += bo1<<1;
+
+ for (j=15;j;j--,b0-=0x20,window-=0x10,samples+=step)
+ {
+ real sum;
+ sum = -REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+ sum -= REAL_MUL(*(--window), *b0++);
+
+ WRITE_SAMPLE(samples,sum,clip);
+ }
+ }
+
+ *pnt += 128;
+
+ return clip;
+}
diff --git a/mpg123_artsplugin/mpg123/decode_2to1.c b/mpg123_artsplugin/mpg123/decode_2to1.c
new file mode 100644
index 00000000..2eb5e07d
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/decode_2to1.c
@@ -0,0 +1,233 @@
+/*
+ * Mpeg Layer-1,2,3 audio decoder
+ * ------------------------------
+ * copyright (c) 1995 by Michael Hipp, All rights reserved. See also 'README'
+ * version for slower machines .. decodes only every second sample
+ * sounds like 24000,22050 or 16000 kHz .. (depending on original sample freq.)
+ *
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include "mpg123.h"
+
+#define WRITE_SAMPLE(samples,sum,clip) \
+ if( (sum) > 32767.0) { *(samples) = 0x7fff; (clip)++; } \
+ else if( (sum) < -32768.0) { *(samples) = -0x8000; (clip)++; } \
+ else { *(samples) = sum; }
+
+int synth_2to1_8bit(real *bandPtr,int channel,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[32];
+ short *tmp1 = samples_tmp + channel;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_2to1(bandPtr,channel,(unsigned char *) samples_tmp,&pnt1);
+ samples += channel + *pnt;
+
+ for(i=0;i<16;i++) {
+ *samples = conv16to8[*tmp1>>AUSHIFT];
+ samples += 2;
+ tmp1 += 2;
+ }
+ *pnt += 32;
+
+ return ret;
+}
+
+int synth_2to1_8bit_mono(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[32];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_2to1(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<16;i++) {
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ tmp1 += 2;
+ }
+ *pnt += 16;
+
+ return ret;
+}
+
+
+int synth_2to1_8bit_mono2stereo(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[32];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_2to1(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<16;i++) {
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ tmp1 += 2;
+ }
+ *pnt += 32;
+
+ return ret;
+}
+
+int synth_2to1_mono(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[32];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1=0;
+
+ ret = synth_2to1(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<16;i++) {
+ *( (short *) samples) = *tmp1;
+ samples += 2;
+ tmp1 += 2;
+ }
+ *pnt += 32;
+
+ return ret;
+}
+
+int synth_2to1_mono2stereo(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ int i,ret;
+
+ ret = synth_2to1(bandPtr,0,samples,pnt);
+ samples = samples + *pnt - 64;
+
+ for(i=0;i<16;i++) {
+ ((short *)samples)[1] = ((short *)samples)[0];
+ samples+=4;
+ }
+
+ return ret;
+}
+
+int synth_2to1(real *bandPtr,int channel,unsigned char *out,int *pnt)
+{
+ static real buffs[2][2][0x110];
+ static const int step = 2;
+ static int bo = 1;
+ short *samples = (short *) (out + *pnt);
+
+ real *b0,(*buf)[0x110];
+ int clip = 0;
+ int bo1;
+
+#ifndef NO_EQUALIZER
+ if(param.enable_equalizer)
+ do_equalizer(bandPtr,channel);
+#endif
+
+ if(!channel) {
+ bo--;
+ bo &= 0xf;
+ buf = buffs[0];
+ }
+ else {
+ samples++;
+ buf = buffs[1];
+ }
+
+ if(bo & 0x1) {
+ b0 = buf[0];
+ bo1 = bo;
+ dct64(buf[1]+((bo+1)&0xf),buf[0]+bo,bandPtr);
+ }
+ else {
+ b0 = buf[1];
+ bo1 = bo+1;
+ dct64(buf[0]+bo,buf[1]+bo+1,bandPtr);
+ }
+
+ {
+ register int j;
+ real *window = decwin + 16 - bo1;
+
+ for (j=8;j;j--,b0+=0x10,window+=0x30)
+ {
+ real sum;
+ sum = *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+#if 0
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+#endif
+ }
+
+ {
+ real sum;
+ sum = window[0x0] * b0[0x0];
+ sum += window[0x2] * b0[0x2];
+ sum += window[0x4] * b0[0x4];
+ sum += window[0x6] * b0[0x6];
+ sum += window[0x8] * b0[0x8];
+ sum += window[0xA] * b0[0xA];
+ sum += window[0xC] * b0[0xC];
+ sum += window[0xE] * b0[0xE];
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+#if 0
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+#endif
+ b0-=0x20,window-=0x40;
+ }
+ window += bo1<<1;
+
+ for (j=7;j;j--,b0-=0x30,window-=0x30)
+ {
+ real sum;
+ sum = -*(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+#if 0
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+#endif
+ }
+ }
+
+ *pnt += 64;
+
+ return clip;
+}
+
+
diff --git a/mpg123_artsplugin/mpg123/decode_3dnow.s b/mpg123_artsplugin/mpg123/decode_3dnow.s
new file mode 100644
index 00000000..fd39429a
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/decode_3dnow.s
@@ -0,0 +1,279 @@
+#
+# decode_3dnow.s - 3DNow! optimized synth_1to1()
+#
+# This code based 'decode_3dnow.s' by Syuuhei Kashiyama
+# <squash@mb.kcom.ne.jp>,only two types of changes have been made:
+#
+# - remove PREFETCH instruction for speedup
+# - change function name for support 3DNow! automatic detect
+# - femms moved to before 'call dct64_3dnow'
+#
+# You can find Kashiyama's original 3dnow! support patch
+# (for mpg123-0.59o) at
+# http:#/user.ecc.u-tokyo.ac.jp/~g810370/linux-simd/ (Japanese).
+#
+# by KIMURA Takuhiro <kim@hannah.ipc.miyakyo-u.ac.jp> - until 31.Mar.1999
+# <kim@comtec.co.jp> - after 1.Apr.1999
+#
+
+##/
+##/ Replacement of synth_1to1() with AMD's 3DNow! SIMD operations support
+##/
+##/ Syuuhei Kashiyama <squash@mb.kcom.ne.jp>
+##/
+##/ The author of this program disclaim whole expressed or implied
+##/ warranties with regard to this program, and in no event shall the
+##/ author of this program liable to whatever resulted from the use of
+##/ this program. Use it at your own risk.
+##/
+
+ .local buffs.40
+ .comm buffs.40,4352,32
+.data
+ .align 4
+ .type bo.42,@object
+ .size bo.42,4
+bo.42:
+ .long 1
+.text
+.globl synth_1to1_3dnow
+ .type synth_1to1_3dnow,@function
+synth_1to1_3dnow:
+ subl $24,%esp
+ pushl %ebp
+ pushl %edi
+ xorl %ebp,%ebp
+ pushl %esi
+ pushl %ebx
+ movl 56(%esp),%esi
+ movl 52(%esp),%edi
+ movl 0(%esi),%esi
+ movl 48(%esp),%ebx
+ addl %edi,%esi
+ movl %esi,16(%esp)
+
+ femms
+
+ # fixed by Takuhiro
+ cmpl $0,param+348
+ je .L25
+ pushl %ebx
+ pushl 48(%esp)
+ call do_equalizer_3dnow
+ addl $8,%esp
+.L25:
+ testl %ebx,%ebx
+ jne .L26
+ decl bo.42
+ movl $buffs.40,%ecx
+ andl $15,bo.42
+ jmp .L27
+.L26:
+ addl $2,16(%esp)
+ movl $buffs.40+2176,%ecx
+.L27:
+ movl bo.42,%edx
+ testb $1,%dl
+ je .L28
+ movl %edx,36(%esp)
+ movl %ecx,%ebx
+ movl 44(%esp),%esi
+ movl %edx,%edi
+ pushl %esi
+ sall $2,%edi
+ movl %ebx,%eax
+ movl %edi,24(%esp)
+ addl %edi,%eax
+ pushl %eax
+ movl %edx,%eax
+ incl %eax
+ andl $15,%eax
+ leal 1088(,%eax,4),%eax
+ addl %ebx,%eax
+ pushl %eax
+ call dct64_3dnow
+ addl $12,%esp
+ jmp .L29
+.L28:
+ leal 1(%edx),%esi
+ movl 44(%esp),%edi
+ movl %esi,36(%esp)
+ leal 1092(%ecx,%edx,4),%eax
+ pushl %edi
+ leal 1088(%ecx),%ebx
+ pushl %eax
+ sall $2,%esi
+ leal (%ecx,%edx,4),%eax
+ pushl %eax
+ call dct64_3dnow
+ addl $12,%esp
+ movl %esi,20(%esp)
+.L29:
+ movl $decwin+64,%edx
+ movl $16,%ecx
+ subl 20(%esp),%edx
+ movl 16(%esp),%edi
+
+ movq (%edx),%mm0
+ movq (%ebx),%mm1
+ .align 32
+.L33:
+ movq 8(%edx),%mm3
+ pfmul %mm1,%mm0
+ movq 8(%ebx),%mm4
+ movq 16(%edx),%mm5
+ pfmul %mm4,%mm3
+ movq 16(%ebx),%mm6
+ pfadd %mm3,%mm0
+ movq 24(%edx),%mm1
+ pfmul %mm6,%mm5
+ movq 24(%ebx),%mm2
+ pfadd %mm5,%mm0
+ movq 32(%edx),%mm3
+ pfmul %mm2,%mm1
+ movq 32(%ebx),%mm4
+ pfadd %mm1,%mm0
+ movq 40(%edx),%mm5
+ pfmul %mm4,%mm3
+ movq 40(%ebx),%mm6
+ pfadd %mm3,%mm0
+ movq 48(%edx),%mm1
+ pfmul %mm6,%mm5
+ movq 48(%ebx),%mm2
+ pfadd %mm0,%mm5
+ movq 56(%edx),%mm3
+ pfmul %mm1,%mm2
+ movq 56(%ebx),%mm4
+ pfadd %mm5,%mm2
+ addl $64,%ebx
+ subl $-128,%edx
+ movq (%edx),%mm0
+ pfmul %mm4,%mm3
+ movq (%ebx),%mm1
+ pfadd %mm3,%mm2
+ movq %mm2,%mm3
+ psrlq $32,%mm3
+ pfsub %mm3,%mm2
+ incl %ebp
+ pf2id %mm2,%mm2
+ packssdw %mm2,%mm2
+ movd %mm2,%eax
+ movw %ax,0(%edi)
+ addl $4,%edi
+ decl %ecx
+ jnz .L33
+
+ movd (%ebx),%mm0
+ movd (%edx),%mm1
+ punpckldq 8(%ebx),%mm0
+ punpckldq 8(%edx),%mm1
+ movd 16(%ebx),%mm3
+ movd 16(%edx),%mm4
+ pfmul %mm1,%mm0
+ punpckldq 24(%ebx),%mm3
+ punpckldq 24(%edx),%mm4
+ movd 32(%ebx),%mm5
+ movd 32(%edx),%mm6
+ pfmul %mm4,%mm3
+ punpckldq 40(%ebx),%mm5
+ punpckldq 40(%edx),%mm6
+ pfadd %mm3,%mm0
+ movd 48(%ebx),%mm1
+ movd 48(%edx),%mm2
+ pfmul %mm6,%mm5
+ punpckldq 56(%ebx),%mm1
+ punpckldq 56(%edx),%mm2
+ pfadd %mm5,%mm0
+ pfmul %mm2,%mm1
+ pfadd %mm1,%mm0
+ pfacc %mm1,%mm0
+ pf2id %mm0,%mm0
+ packssdw %mm0,%mm0
+ movd %mm0,%eax
+ movw %ax,0(%edi)
+ incl %ebp
+ movl 36(%esp),%esi
+ addl $-64,%ebx
+ movl $15,%ebp
+ addl $4,%edi
+ leal -128(%edx,%esi,8),%edx
+
+ movl $15,%ecx
+ movd (%ebx),%mm0
+ movd -4(%edx),%mm1
+ punpckldq 4(%ebx),%mm0
+ punpckldq -8(%edx),%mm1
+ .align 32
+.L46:
+ movd 8(%ebx),%mm3
+ movd -12(%edx),%mm4
+ pfmul %mm1,%mm0
+ punpckldq 12(%ebx),%mm3
+ punpckldq -16(%edx),%mm4
+ movd 16(%ebx),%mm5
+ movd -20(%edx),%mm6
+ pfmul %mm4,%mm3
+ punpckldq 20(%ebx),%mm5
+ punpckldq -24(%edx),%mm6
+ pfadd %mm3,%mm0
+ movd 24(%ebx),%mm1
+ movd -28(%edx),%mm2
+ pfmul %mm6,%mm5
+ punpckldq 28(%ebx),%mm1
+ punpckldq -32(%edx),%mm2
+ pfadd %mm5,%mm0
+ movd 32(%ebx),%mm3
+ movd -36(%edx),%mm4
+ pfmul %mm2,%mm1
+ punpckldq 36(%ebx),%mm3
+ punpckldq -40(%edx),%mm4
+ pfadd %mm1,%mm0
+ movd 40(%ebx),%mm5
+ movd -44(%edx),%mm6
+ pfmul %mm4,%mm3
+ punpckldq 44(%ebx),%mm5
+ punpckldq -48(%edx),%mm6
+ pfadd %mm3,%mm0
+ movd 48(%ebx),%mm1
+ movd -52(%edx),%mm2
+ pfmul %mm6,%mm5
+ punpckldq 52(%ebx),%mm1
+ punpckldq -56(%edx),%mm2
+ pfadd %mm0,%mm5
+ movd 56(%ebx),%mm3
+ movd -60(%edx),%mm4
+ pfmul %mm2,%mm1
+ punpckldq 60(%ebx),%mm3
+ punpckldq (%edx),%mm4
+ pfadd %mm1,%mm5
+ addl $-128,%edx
+ addl $-64,%ebx
+ movd (%ebx),%mm0
+ movd -4(%edx),%mm1
+ pfmul %mm4,%mm3
+ punpckldq 4(%ebx),%mm0
+ punpckldq -8(%edx),%mm1
+ pfadd %mm5,%mm3
+ pfacc %mm3,%mm3
+ incl %ebp
+ pf2id %mm3,%mm3
+ movd %mm3,%eax
+ negl %eax
+ movd %eax,%mm3
+ packssdw %mm3,%mm3
+ movd %mm3,%eax
+ movw %ax,(%edi)
+ addl $4,%edi
+ decl %ecx
+ jnz .L46
+
+ femms
+ movl 56(%esp),%esi
+ movl %ebp,%eax
+ subl $-128,0(%esi)
+ popl %ebx
+ popl %esi
+ popl %edi
+ popl %ebp
+ addl $24,%esp
+ ret
diff --git a/mpg123_artsplugin/mpg123/decode_4to1.c b/mpg123_artsplugin/mpg123/decode_4to1.c
new file mode 100644
index 00000000..00f6b038
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/decode_4to1.c
@@ -0,0 +1,240 @@
+/*
+ * Mpeg Layer-1,2,3 audio decoder
+ * ------------------------------
+ * copyright (c) 1995,1996,1997 by Michael Hipp, All rights reserved.
+ * See also 'README'
+ * version for slower machines .. decodes only every fourth sample
+ * dunno why it sounds THIS annoying (maybe we should adapt the window?)
+ * absolutely not optimized for this operation
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include "mpg123.h"
+
+#define WRITE_SAMPLE(samples,sum,clip) \
+ if( (sum) > 32767.0) { *(samples) = 0x7fff; (clip)++; } \
+ else if( (sum) < -32768.0) { *(samples) = -0x8000; (clip)++; } \
+ else { *(samples) = sum; }
+
+int synth_4to1_8bit(real *bandPtr,int channel,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[16];
+ short *tmp1 = samples_tmp + channel;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_4to1(bandPtr,channel,(unsigned char *) samples_tmp,&pnt1);
+ samples += channel + *pnt;
+
+ for(i=0;i<8;i++) {
+ *samples = conv16to8[*tmp1>>AUSHIFT];
+ samples += 2;
+ tmp1 += 2;
+ }
+ *pnt += 16;
+
+ return ret;
+}
+
+int synth_4to1_8bit_mono(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[16];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_4to1(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<8;i++) {
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ tmp1 += 2;
+ }
+ *pnt += 8;
+
+ return ret;
+}
+
+
+int synth_4to1_8bit_mono2stereo(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[16];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_4to1(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<8;i++) {
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ tmp1 += 2;
+ }
+ *pnt += 16;
+
+ return ret;
+}
+
+int synth_4to1_mono(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[16];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_4to1(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<8;i++) {
+ *( (short *)samples) = *tmp1;
+ samples += 2;
+ tmp1 += 2;
+ }
+ *pnt += 16;
+
+ return ret;
+}
+
+int synth_4to1_mono2stereo(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ int i,ret;
+
+ ret = synth_4to1(bandPtr,0,samples,pnt);
+ samples = samples + *pnt - 32;
+
+ for(i=0;i<8;i++) {
+ ((short *)samples)[1] = ((short *)samples)[0];
+ samples+=4;
+ }
+
+ return ret;
+}
+
+int synth_4to1(real *bandPtr,int channel,unsigned char *out,int *pnt)
+{
+ static real buffs[2][2][0x110];
+ static const int step = 2;
+ static int bo = 1;
+ short *samples = (short *) (out + *pnt);
+
+ real *b0,(*buf)[0x110];
+ int clip = 0;
+ int bo1;
+
+#ifndef NO_EQUALIZER
+ if(param.enable_equalizer)
+ do_equalizer(bandPtr,channel);
+#endif
+
+ if(!channel) {
+ bo--;
+ bo &= 0xf;
+ buf = buffs[0];
+ }
+ else {
+ samples++;
+ buf = buffs[1];
+ }
+
+ if(bo & 0x1) {
+ b0 = buf[0];
+ bo1 = bo;
+ dct64(buf[1]+((bo+1)&0xf),buf[0]+bo,bandPtr);
+ }
+ else {
+ b0 = buf[1];
+ bo1 = bo+1;
+ dct64(buf[0]+bo,buf[1]+bo+1,bandPtr);
+ }
+
+ {
+ register int j;
+ real *window = decwin + 16 - bo1;
+
+ for (j=4;j;j--,b0+=0x30,window+=0x70)
+ {
+ real sum;
+ sum = *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+#if 0
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+#endif
+ }
+
+ {
+ real sum;
+ sum = window[0x0] * b0[0x0];
+ sum += window[0x2] * b0[0x2];
+ sum += window[0x4] * b0[0x4];
+ sum += window[0x6] * b0[0x6];
+ sum += window[0x8] * b0[0x8];
+ sum += window[0xA] * b0[0xA];
+ sum += window[0xC] * b0[0xC];
+ sum += window[0xE] * b0[0xE];
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+#if 0
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+#endif
+ b0-=0x40,window-=0x80;
+ }
+ window += bo1<<1;
+
+ for (j=3;j;j--,b0-=0x50,window-=0x70)
+ {
+ real sum;
+ sum = -*(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+#if 0
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+ WRITE_SAMPLE(samples,sum,clip); samples += step;
+#endif
+ }
+ }
+
+ *pnt += 32;
+
+ return clip;
+}
+
+
diff --git a/mpg123_artsplugin/mpg123/decode_MMX.s b/mpg123_artsplugin/mpg123/decode_MMX.s
new file mode 100644
index 00000000..1c9a1adb
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/decode_MMX.s
@@ -0,0 +1,108 @@
+# this code comes under GPL
+
+.text
+
+.globl synth_1to1_MMX
+
+synth_1to1_MMX:
+ pushl %ebp
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ movl 24(%esp),%ecx
+ movl 28(%esp),%edi
+ movl $15,%ebx
+ movl 36(%esp),%edx
+ leal (%edi,%ecx,2),%edi
+ decl %ecx
+ movl 32(%esp),%esi
+ movl (%edx),%eax
+ jecxz .L1
+ decl %eax
+ andl %ebx,%eax
+ leal 1088(%esi),%esi
+ movl %eax,(%edx)
+.L1:
+ leal (%esi,%eax,2),%edx
+ movl %eax,%ebp
+ incl %eax
+ pushl 20(%esp)
+ andl %ebx,%eax
+ leal 544(%esi,%eax,2),%ecx
+ incl %ebx
+ testl $1, %eax
+ jnz .L2
+ xchgl %edx,%ecx
+ incl %ebp
+ leal 544(%esi),%esi
+.L2:
+ pushl %edx
+ pushl %ecx
+ call dct64_MMX
+ addl $12,%esp
+ leal 1(%ebx), %ecx
+ subl %ebp,%ebx
+
+ leal decwins(%ebx,%ebx,1), %edx
+.L3:
+ movq (%edx),%mm0
+ pmaddwd (%esi),%mm0
+ movq 8(%edx),%mm1
+ pmaddwd 8(%esi),%mm1
+ movq 16(%edx),%mm2
+ pmaddwd 16(%esi),%mm2
+ movq 24(%edx),%mm3
+ pmaddwd 24(%esi),%mm3
+ paddd %mm1,%mm0
+ paddd %mm2,%mm0
+ paddd %mm3,%mm0
+ movq %mm0,%mm1
+ psrlq $32,%mm1
+ paddd %mm1,%mm0
+ psrad $13,%mm0
+ packssdw %mm0,%mm0
+ movd %mm0,%eax
+ movw %ax, (%edi)
+
+ leal 32(%esi),%esi
+ leal 64(%edx),%edx
+ leal 4(%edi),%edi
+ loop .L3
+
+
+ subl $64,%esi
+ movl $15,%ecx
+.L4:
+ movq (%edx),%mm0
+ pmaddwd (%esi),%mm0
+ movq 8(%edx),%mm1
+ pmaddwd 8(%esi),%mm1
+ movq 16(%edx),%mm2
+ pmaddwd 16(%esi),%mm2
+ movq 24(%edx),%mm3
+ pmaddwd 24(%esi),%mm3
+ paddd %mm1,%mm0
+ paddd %mm2,%mm0
+ paddd %mm3,%mm0
+ movq %mm0,%mm1
+ psrlq $32,%mm1
+ paddd %mm0,%mm1
+ psrad $13,%mm1
+ packssdw %mm1,%mm1
+ psubd %mm0,%mm0
+ psubsw %mm1,%mm0
+ movd %mm0,%eax
+ movw %ax,(%edi)
+
+ subl $32,%esi
+ addl $64,%edx
+ leal 4(%edi),%edi
+ loop .L4
+ emms
+ popl %ebx
+ popl %esi
+ popl %edi
+ popl %ebp
+ ret
+
+
diff --git a/mpg123_artsplugin/mpg123/decode_i386.c b/mpg123_artsplugin/mpg123/decode_i386.c
new file mode 100644
index 00000000..d39795f8
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/decode_i386.c
@@ -0,0 +1,257 @@
+/*
+ * Mpeg Layer-1,2,3 audio decoder
+ * ------------------------------
+ * copyright (c) 1995,1996,1997 by Michael Hipp, All rights reserved.
+ * See also 'README'
+ *
+ * slighlty optimized for machines without autoincrement/decrement.
+ * The performance is highly compiler dependent. Maybe
+ * the decode.c version for 'normal' processor may be faster
+ * even for Intel processors.
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include "mpg123.h"
+
+#if 0
+ /* old WRITE_SAMPLE */
+#define WRITE_SAMPLE(samples,sum,clip) \
+ if( (sum) > 32767.0) { *(samples) = 0x7fff; (clip)++; } \
+ else if( (sum) < -32768.0) { *(samples) = -0x8000; (clip)++; } \
+ else { *(samples) = sum; }
+#else
+ /* new WRITE_SAMPLE */
+#define WRITE_SAMPLE(samples,sum,clip) { \
+ double dtemp; int v; /* sizeof(int) == 4 */ \
+ dtemp = ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0)) + (sum); \
+ v = ((*(int *)&dtemp) - 0x80000000); \
+ if( v > 32767) { *(samples) = 0x7fff; (clip)++; } \
+ else if( v < -32768) { *(samples) = -0x8000; (clip)++; } \
+ else { *(samples) = v; } \
+}
+#endif
+
+int synth_1to1_8bit(real *bandPtr,int channel,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[64];
+ short *tmp1 = samples_tmp + channel;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_1to1(bandPtr,channel,(unsigned char *)samples_tmp,&pnt1);
+ samples += channel + *pnt;
+
+ for(i=0;i<32;i++) {
+ *samples = conv16to8[*tmp1>>AUSHIFT];
+ samples += 2;
+ tmp1 += 2;
+ }
+ *pnt += 64;
+
+ return ret;
+}
+
+int synth_1to1_8bit_mono(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[64];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_1to1(bandPtr,0,(unsigned char *)samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<32;i++) {
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ tmp1+=2;
+ }
+ *pnt += 32;
+
+ return ret;
+}
+
+int synth_1to1_8bit_mono2stereo(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[64];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_1to1(bandPtr,0,(unsigned char *)samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<32;i++) {
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ tmp1 += 2;
+ }
+ *pnt += 64;
+
+ return ret;
+}
+
+int synth_1to1_mono(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[64];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_1to1(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<32;i++) {
+ *( (short *) samples) = *tmp1;
+ samples += 2;
+ tmp1 += 2;
+ }
+ *pnt += 64;
+
+ return ret;
+}
+
+
+int synth_1to1_mono2stereo(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ int i,ret;
+
+ ret = synth_1to1(bandPtr,0,samples,pnt);
+ samples = samples + *pnt - 128;
+
+ for(i=0;i<32;i++) {
+ ((short *)samples)[1] = ((short *)samples)[0];
+ samples+=4;
+ }
+
+ return ret;
+}
+
+int synth_1to1(real *bandPtr,int channel,unsigned char *out,int *pnt)
+{
+#ifndef PENTIUM_OPT
+ static real buffs[2][2][0x110];
+ static const int step = 2;
+ static int bo = 1;
+ short *samples = (short *) (out + *pnt);
+
+ real *b0,(*buf)[0x110];
+ int clip = 0;
+ int bo1;
+#endif
+
+#ifndef NO_EQUALIZER
+ if(param.enable_equalizer)
+ do_equalizer(bandPtr,channel);
+#endif
+
+#ifndef PENTIUM_OPT
+ if(!channel) {
+ bo--;
+ bo &= 0xf;
+ buf = buffs[0];
+ }
+ else {
+ samples++;
+ buf = buffs[1];
+ }
+
+ if(bo & 0x1) {
+ b0 = buf[0];
+ bo1 = bo;
+ dct64(buf[1]+((bo+1)&0xf),buf[0]+bo,bandPtr);
+ }
+ else {
+ b0 = buf[1];
+ bo1 = bo+1;
+ dct64(buf[0]+bo,buf[1]+bo+1,bandPtr);
+ }
+
+ {
+ register int j;
+ real *window = decwin + 16 - bo1;
+
+ for (j=16;j;j--,b0+=0x10,window+=0x20,samples+=step)
+ {
+ real sum;
+ sum = window[0x0] * b0[0x0];
+ sum -= window[0x1] * b0[0x1];
+ sum += window[0x2] * b0[0x2];
+ sum -= window[0x3] * b0[0x3];
+ sum += window[0x4] * b0[0x4];
+ sum -= window[0x5] * b0[0x5];
+ sum += window[0x6] * b0[0x6];
+ sum -= window[0x7] * b0[0x7];
+ sum += window[0x8] * b0[0x8];
+ sum -= window[0x9] * b0[0x9];
+ sum += window[0xA] * b0[0xA];
+ sum -= window[0xB] * b0[0xB];
+ sum += window[0xC] * b0[0xC];
+ sum -= window[0xD] * b0[0xD];
+ sum += window[0xE] * b0[0xE];
+ sum -= window[0xF] * b0[0xF];
+
+ WRITE_SAMPLE(samples,sum,clip);
+ }
+
+ {
+ real sum;
+ sum = window[0x0] * b0[0x0];
+ sum += window[0x2] * b0[0x2];
+ sum += window[0x4] * b0[0x4];
+ sum += window[0x6] * b0[0x6];
+ sum += window[0x8] * b0[0x8];
+ sum += window[0xA] * b0[0xA];
+ sum += window[0xC] * b0[0xC];
+ sum += window[0xE] * b0[0xE];
+ WRITE_SAMPLE(samples,sum,clip);
+ b0-=0x10,window-=0x20,samples+=step;
+ }
+ window += bo1<<1;
+
+ for (j=15;j;j--,b0-=0x10,window-=0x20,samples+=step)
+ {
+ real sum;
+ sum = -window[-0x1] * b0[0x0];
+ sum -= window[-0x2] * b0[0x1];
+ sum -= window[-0x3] * b0[0x2];
+ sum -= window[-0x4] * b0[0x3];
+ sum -= window[-0x5] * b0[0x4];
+ sum -= window[-0x6] * b0[0x5];
+ sum -= window[-0x7] * b0[0x6];
+ sum -= window[-0x8] * b0[0x7];
+ sum -= window[-0x9] * b0[0x8];
+ sum -= window[-0xA] * b0[0x9];
+ sum -= window[-0xB] * b0[0xA];
+ sum -= window[-0xC] * b0[0xB];
+ sum -= window[-0xD] * b0[0xC];
+ sum -= window[-0xE] * b0[0xD];
+ sum -= window[-0xF] * b0[0xE];
+ sum -= window[-0x0] * b0[0xF];
+
+ WRITE_SAMPLE(samples,sum,clip);
+ }
+ }
+ *pnt += 128;
+
+ return clip;
+#elif defined(USE_MMX)
+ {
+ static short buffs[2][2][0x110];
+ static int bo = 1;
+ short *samples = (short *) (out + *pnt);
+ synth_1to1_MMX(bandPtr, channel, samples, (short *) buffs, &bo);
+ *pnt += 128;
+ return 0;
+ }
+#else
+ {
+ int ret;
+ ret = synth_1to1_pent(bandPtr,channel,out+*pnt);
+ *pnt += 128;
+ return ret;
+ }
+#endif
+}
diff --git a/mpg123_artsplugin/mpg123/decode_i486.c b/mpg123_artsplugin/mpg123/decode_i486.c
new file mode 100644
index 00000000..b0378f32
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/decode_i486.c
@@ -0,0 +1,250 @@
+/*
+ * Subband Synthesis for MPEG Audio.
+ *
+ * Version optimized for 80486 by using integer arithmetic,
+ * multiplications by shift and add, and by increasing locality in
+ * order to fit the 8KB L1 cache. This code should be compiled with gcc
+ * 2.7.2 or higher.
+ *
+ * Note: this version does not guaranty a good accuracy. The filter
+ * coefficients are quantified on 14 bits.
+ *
+ * (c) 1998 Fabrice Bellard
+ *
+ * GPL clean
+ */
+
+#include <stdlib.h>
+
+#include "mpg123.h"
+
+#define FIR_SIZE 16
+
+#define FIR16_1(pos,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15) \
+{\
+ int sum;\
+ sum=(c0)*b0[0]+(c1)*b0[1]+(c2)*b0[2]+(c3)*b0[3]+\
+ (c4)*b0[4]+(c5)*b0[5]+(c6)*b0[6]+(c7)*b0[7]+\
+ (c8)*b0[8]+(c9)*b0[9]+(c10)*b0[10]+(c11)*b0[11]+\
+ (c12)*b0[12]+(c13)*b0[13]+(c14)*b0[14]+(c15)*b0[15];\
+ sum=(sum+(1 << 13))>>14;\
+ if (sum<-32768) sum=-32768;\
+ else if (sum>32767) sum=32767;\
+ samples[2*(pos)]=sum;\
+ b0+=FIR_BUFFER_SIZE;\
+}
+
+#define FIR16_2(pos1,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,\
+ pos2,d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15) \
+{\
+ int sum1,sum2,v;\
+\
+ v=b0[0];\
+ sum1=(c0)*v;\
+ sum2=(d0)*v;\
+ v=b0[1];\
+ sum1+=(c1)*v;\
+ sum2+=(d1)*v;\
+ v=b0[2];\
+ sum1+=(c2)*v;\
+ sum2+=(d2)*v;\
+ v=b0[3];\
+ sum1+=(c3)*v;\
+ sum2+=(d3)*v;\
+ v=b0[4];\
+ sum1+=(c4)*v;\
+ sum2+=(d4)*v;\
+ v=b0[5];\
+ sum1+=(c5)*v;\
+ sum2+=(d5)*v;\
+ v=b0[6];\
+ sum1+=(c6)*v;\
+ sum2+=(d6)*v;\
+ v=b0[7];\
+ sum1+=(c7)*v;\
+ sum2+=(d7)*v;\
+ v=b0[8];\
+ sum1+=(c8)*v;\
+ sum2+=(d8)*v;\
+ v=b0[9];\
+ sum1+=(c9)*v;\
+ sum2+=(d9)*v;\
+ v=b0[10];\
+ sum1+=(c10)*v;\
+ sum2+=(d10)*v;\
+ v=b0[11];\
+ sum1+=(c11)*v;\
+ sum2+=(d11)*v;\
+ v=b0[12];\
+ sum1+=(c12)*v;\
+ sum2+=(d12)*v;\
+ v=b0[13];\
+ sum1+=(c13)*v;\
+ sum2+=(d13)*v;\
+ v=b0[14];\
+ sum1+=(c14)*v;\
+ sum2+=(d14)*v;\
+ v=b0[15];\
+ sum1+=(c15)*v;\
+ sum2+=(d15)*v;\
+\
+ sum1=(sum1+(1<<13))>>14;\
+ sum2=(sum2+(1<<13))>>14;\
+\
+ if (sum1<-32768) sum1=-32768;\
+ else if (sum1>32767) sum1=32767;\
+ samples[(pos1)*2]=sum1;\
+\
+ if (sum2<-32768) sum2=-32768;\
+ else if (sum2>32767) sum2=32767;\
+ samples[(pos2)*2]=sum2;\
+ b0+=FIR_BUFFER_SIZE;\
+}
+
+int synth_1to1_486(real *bandPtr,int channel,unsigned char *out,int nb_blocks)
+{
+ static int buffs[2][2][17*FIR_BUFFER_SIZE];
+ static int bo[2] = { FIR_SIZE-1, FIR_SIZE-1 };
+ short *samples = (short *) out;
+ int *b0,(*buf)[17*FIR_BUFFER_SIZE];
+ int clip = 0;
+ int block,b,bo_start;
+
+ /* samples address */
+ samples+=channel;
+
+ bo_start=bo[channel];
+ buf = buffs[channel];
+
+ b=bo_start;
+ for(block=0;block<nb_blocks;block++) {
+
+ /* FIR offset */
+ b++;
+ if (b >= FIR_BUFFER_SIZE) {
+ int *p,*q;
+ int c,i,j;
+
+ /* we shift the buffers */
+ for(c=0;c<2;c++) {
+ p=&buf[c][0]+1;
+ q=p+(FIR_BUFFER_SIZE-FIR_SIZE);
+ for(i=0;i<17;i++) {
+ for(j=0;j<FIR_SIZE-1;j++) p[j]=q[j];
+ p+=FIR_BUFFER_SIZE;
+ q+=FIR_BUFFER_SIZE;
+ }
+ }
+ /* we update 'bo' accordingly */
+ b=bo[channel]=FIR_SIZE;
+ }
+
+ if(b & 1) {
+ dct64_486(buf[1]+b,buf[0]+b,bandPtr);
+ } else {
+ dct64_486(buf[0]+b,buf[1]+b,bandPtr);
+ }
+ bandPtr+=32;
+ }
+ bo[channel]=b;
+
+ /* filter bank: part 1 */
+ b=bo_start;
+ for(block=0;block<nb_blocks;block++) {
+ b++;
+ if (b >= FIR_BUFFER_SIZE) b=FIR_SIZE;
+ if(b & 1) {
+ b0 = buf[0] + b - (FIR_SIZE-1);
+ } else {
+ b0 = buf[1] + b - (FIR_SIZE-1);
+ }
+
+ FIR16_1(0,-7,53,-114,509,-1288,1643,-9372,18759,9372,1643,1288,509,114,53,7,0);
+ FIR16_2(1,-6,52,-100,515,-1197,1783,-8910,18748,9834,1489,1379,500,129,54,7,0,
+ 31,0,-7,54,-129,500,-1379,1489,-9834,18748,8910,1783,1197,515,100,52,6);
+ FIR16_2(2,-6,50,-86,520,-1106,1910,-8447,18714,10294,1322,1469,488,145,55,8,0,
+ 30,0,-8,55,-145,488,-1469,1322,-10294,18714,8447,1910,1106,520,86,50,6);
+ FIR16_2(3,-5,49,-73,521,-1015,2023,-7986,18657,10751,1140,1559,473,161,56,9,0,
+ 29,0,-9,56,-161,473,-1559,1140,-10751,18657,7986,2023,1015,521,73,49,5);
+ samples+=64;
+ }
+ samples-=64*nb_blocks;
+
+ /* filter bank: part 2 */
+
+ b=bo_start;
+ for(block=0;block<nb_blocks;block++) {
+ b++;
+ if (b >= FIR_BUFFER_SIZE) b=FIR_SIZE;
+ if(b & 1) {
+ b0 = buf[0] + b - (FIR_SIZE-1) + 4*FIR_BUFFER_SIZE;
+ } else {
+ b0 = buf[1] + b - (FIR_SIZE-1) + 4*FIR_BUFFER_SIZE;
+ }
+
+ FIR16_2(4,-4,47,-61,521,-926,2123,-7528,18578,11205,944,1647,455,177,56,10,0,
+ 28,0,-10,56,-177,455,-1647,944,-11205,18578,7528,2123,926,521,61,47,4);
+ FIR16_2(5,-4,45,-49,518,-837,2210,-7072,18477,11654,733,1733,434,194,57,11,0,
+ 27,0,-11,57,-194,434,-1733,733,-11654,18477,7072,2210,837,518,49,45,4);
+ FIR16_2(6,-4,44,-38,514,-751,2284,-6620,18353,12097,509,1817,411,212,57,12,0,
+ 26,0,-12,57,-212,411,-1817,509,-12097,18353,6620,2284,751,514,38,44,4);
+ FIR16_2(7,-3,42,-27,508,-665,2347,-6173,18208,12534,270,1899,383,229,56,13,0,
+ 25,0,-13,56,-229,383,-1899,270,-12534,18208,6173,2347,665,508,27,42,3);
+
+ samples+=64;
+ }
+ samples-=64*nb_blocks;
+
+ /* filter bank: part 3 */
+
+ b=bo_start;
+ for(block=0;block<nb_blocks;block++) {
+ b++;
+ if (b >= FIR_BUFFER_SIZE) b=FIR_SIZE;
+ if(b & 1) {
+ b0 = buf[0] + b - (FIR_SIZE-1) + 8*FIR_BUFFER_SIZE;
+ } else {
+ b0 = buf[1] + b - (FIR_SIZE-1) + 8*FIR_BUFFER_SIZE;
+ }
+
+ FIR16_2(8,-3,40,-18,500,-582,2398,-5732,18042,12963,17,1977,353,247,56,14,0,
+ 24,0,-14,56,-247,353,-1977,17,-12963,18042,5732,2398,582,500,18,40,3);
+ FIR16_2(9,-2,38,-9,490,-501,2437,-5297,17855,13383,-249,2052,320,266,55,15,0,
+ 23,0,-15,55,-266,320,-2052,-249,-13383,17855,5297,2437,501,490,9,38,2);
+ FIR16_2(10,-2,36,0,479,-423,2465,-4869,17647,13794,-530,2122,282,284,53,17,0,
+ 22,0,-17,53,-284,282,-2122,-530,-13794,17647,4869,2465,423,479,0,36,2);
+ FIR16_2(11,-2,34,7,467,-347,2483,-4449,17419,14194,-825,2188,242,302,52,18,0,
+ 21,0,-18,52,-302,242,-2188,-825,-14194,17419,4449,2483,347,467,-7,34,2);
+
+ samples+=64;
+ }
+ samples-=64*nb_blocks;
+
+ /* filter bank: part 4 */
+
+ b=bo_start;
+ for(block=0;block<nb_blocks;block++) {
+ b++;
+ if (b >= FIR_BUFFER_SIZE) b=FIR_SIZE;
+ if(b & 1) {
+ b0 = buf[0] + b - (FIR_SIZE-1) + 12*FIR_BUFFER_SIZE;
+ } else {
+ b0 = buf[1] + b - (FIR_SIZE-1) + 12*FIR_BUFFER_SIZE;
+ }
+
+ FIR16_2(12,-2,33,14,454,-273,2491,-4038,17173,14583,-1133,2249,198,320,50,19,0,
+ 20,0,-19,50,-320,198,-2249,-1133,-14583,17173,4038,2491,273,454,-14,33,2);
+ FIR16_2(13,-1,31,20,439,-203,2489,-3637,16907,14959,-1454,2304,151,339,47,21,-1,
+ 19,-1,-21,47,-339,151,-2304,-1454,-14959,16907,3637,2489,203,439,-20,31,1);
+ FIR16_2(14,-1,29,26,424,-136,2479,-3245,16623,15322,-1788,2354,100,357,44,22,-1,
+ 18,-1,-22,44,-357,100,-2354,-1788,-15322,16623,3245,2479,136,424,-26,29,1);
+ FIR16_2(15,-1,27,31,408,-72,2459,-2863,16322,15671,-2135,2396,46,374,40,24,-1,
+ 17,-1,-24,40,-374,46,-2396,-2135,-15671,16322,2863,2459,72,408,-31,27,1);
+ FIR16_1(16,-1,0,36,0,-11,0,-2493,0,16004,0,2431,0,391,0,26,0);
+
+ samples+=64;
+ }
+
+ return clip;
+}
+
diff --git a/mpg123_artsplugin/mpg123/decode_i586.s b/mpg123_artsplugin/mpg123/decode_i586.s
new file mode 100644
index 00000000..5b5169a5
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/decode_i586.s
@@ -0,0 +1,323 @@
+#
+# synth_1to1 works the same way as the c version of this
+# file. only two types of changes have been made:
+# - reordered floating point instructions to
+# prevent pipline stalls
+# - made WRITE_SAMPLE use integer instead of
+# (slower) floating point
+# all kinds of x86 processors should benefit from these
+# modifications.
+#
+# useful sources of information on optimizing x86 code include:
+#
+# Intel Architecture Optimization Manual
+# http:#/www.intel.com/design/pentium/manuals/242816.htm
+#
+# Cyrix 6x86 Instruction Set Summary
+# ftp:#/ftp.cyrix.com/6x86/6x-dbch6.pdf
+#
+# AMD-K5 Processor Software Development
+# http:#/www.amd.com/products/cpg/techdocs/appnotes/20007e.pdf
+#
+# Stefan Bieschewski <stb@acm.org>
+#
+# You can use this part under GPL.
+#
+# $Id$
+#
+.bss
+ .comm buffs,4352,4
+.data
+ .align 4
+bo:
+ .long 1
+.section .rodata
+ .align 8
+.LC0:
+ .long 0x0,0x40dfffc0
+ .align 8
+.LC1:
+ .long 0x0,0xc0e00000
+ .align 8
+.text
+.globl synth_1to1_pent
+synth_1to1_pent:
+ subl $12,%esp
+ pushl %ebp
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ movl 32(%esp),%eax
+ movl 40(%esp),%esi
+ xorl %edi,%edi
+ movl bo,%ebp
+ cmpl %edi,36(%esp)
+ jne .L48
+ decl %ebp
+ andl $15,%ebp
+ movl %ebp,bo
+ movl $buffs,%ecx
+ jmp .L49
+.L48:
+ addl $2,%esi
+ movl $buffs+2176,%ecx
+.L49:
+ testl $1,%ebp
+ je .L50
+ movl %ecx,%ebx
+ movl %ebp,16(%esp)
+ pushl %eax
+ movl 20(%esp),%edx
+ leal (%ebx,%edx,4),%eax
+ pushl %eax
+ movl 24(%esp),%eax
+ incl %eax
+ andl $15,%eax
+ leal 1088(,%eax,4),%eax
+ addl %ebx,%eax
+ jmp .L74
+.L50:
+ leal 1088(%ecx),%ebx
+ leal 1(%ebp),%edx
+ movl %edx,16(%esp)
+ pushl %eax
+ leal 1092(%ecx,%ebp,4),%eax
+ pushl %eax
+ leal (%ecx,%ebp,4),%eax
+.L74:
+ pushl %eax
+ call dct64
+ addl $12,%esp
+ movl 16(%esp),%edx
+ leal 0(,%edx,4),%edx
+ movl $decwin+64,%eax
+ movl %eax,%ecx
+ subl %edx,%ecx
+ movl $16,%ebp
+.L55:
+ flds (%ecx)
+ fmuls (%ebx)
+ flds 4(%ecx)
+ fmuls 4(%ebx)
+ fxch %st(1)
+ flds 8(%ecx)
+ fmuls 8(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds 12(%ecx)
+ fmuls 12(%ebx)
+ fxch %st(2)
+ faddp %st,%st(1)
+ flds 16(%ecx)
+ fmuls 16(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds 20(%ecx)
+ fmuls 20(%ebx)
+ fxch %st(2)
+ faddp %st,%st(1)
+ flds 24(%ecx)
+ fmuls 24(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds 28(%ecx)
+ fmuls 28(%ebx)
+ fxch %st(2)
+ faddp %st,%st(1)
+ flds 32(%ecx)
+ fmuls 32(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds 36(%ecx)
+ fmuls 36(%ebx)
+ fxch %st(2)
+ faddp %st,%st(1)
+ flds 40(%ecx)
+ fmuls 40(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds 44(%ecx)
+ fmuls 44(%ebx)
+ fxch %st(2)
+ faddp %st,%st(1)
+ flds 48(%ecx)
+ fmuls 48(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds 52(%ecx)
+ fmuls 52(%ebx)
+ fxch %st(2)
+ faddp %st,%st(1)
+ flds 56(%ecx)
+ fmuls 56(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds 60(%ecx)
+ fmuls 60(%ebx)
+ fxch %st(2)
+ subl $4,%esp
+ faddp %st,%st(1)
+ fxch %st(1)
+ fsubrp %st,%st(1)
+ fistpl (%esp)
+ popl %eax
+ cmpl $32767,%eax
+ jg 1f
+ cmpl $-32768,%eax
+ jl 2f
+ movw %ax,(%esi)
+ jmp 4f
+1: movw $32767,(%esi)
+ jmp 3f
+2: movw $-32768,(%esi)
+3: incl %edi
+4:
+.L54:
+ addl $64,%ebx
+ subl $-128,%ecx
+ addl $4,%esi
+ decl %ebp
+ jnz .L55
+ flds (%ecx)
+ fmuls (%ebx)
+ flds 8(%ecx)
+ fmuls 8(%ebx)
+ flds 16(%ecx)
+ fmuls 16(%ebx)
+ fxch %st(2)
+ faddp %st,%st(1)
+ flds 24(%ecx)
+ fmuls 24(%ebx)
+ fxch %st(2)
+ faddp %st,%st(1)
+ flds 32(%ecx)
+ fmuls 32(%ebx)
+ fxch %st(2)
+ faddp %st,%st(1)
+ flds 40(%ecx)
+ fmuls 40(%ebx)
+ fxch %st(2)
+ faddp %st,%st(1)
+ flds 48(%ecx)
+ fmuls 48(%ebx)
+ fxch %st(2)
+ faddp %st,%st(1)
+ flds 56(%ecx)
+ fmuls 56(%ebx)
+ fxch %st(2)
+ subl $4,%esp
+ faddp %st,%st(1)
+ fxch %st(1)
+ faddp %st,%st(1)
+ fistpl (%esp)
+ popl %eax
+ cmpl $32767,%eax
+ jg 1f
+ cmpl $-32768,%eax
+ jl 2f
+ movw %ax,(%esi)
+ jmp 4f
+1: movw $32767,(%esi)
+ jmp 3f
+2: movw $-32768,(%esi)
+3: incl %edi
+4:
+.L62:
+ addl $-64,%ebx
+ addl $4,%esi
+ movl 16(%esp),%edx
+ leal -128(%ecx,%edx,8),%ecx
+ movl $15,%ebp
+.L68:
+ flds -4(%ecx)
+ fchs
+ fmuls (%ebx)
+ flds -8(%ecx)
+ fmuls 4(%ebx)
+ fxch %st(1)
+ flds -12(%ecx)
+ fmuls 8(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds -16(%ecx)
+ fmuls 12(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds -20(%ecx)
+ fmuls 16(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds -24(%ecx)
+ fmuls 20(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds -28(%ecx)
+ fmuls 24(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds -32(%ecx)
+ fmuls 28(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds -36(%ecx)
+ fmuls 32(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds -40(%ecx)
+ fmuls 36(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds -44(%ecx)
+ fmuls 40(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds -48(%ecx)
+ fmuls 44(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds -52(%ecx)
+ fmuls 48(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds -56(%ecx)
+ fmuls 52(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds -60(%ecx)
+ fmuls 56(%ebx)
+ fxch %st(2)
+ fsubrp %st,%st(1)
+ flds (%ecx)
+ fmuls 60(%ebx)
+ fxch %st(2)
+ subl $4,%esp
+ fsubrp %st,%st(1)
+ fxch %st(1)
+ fsubrp %st,%st(1)
+ fistpl (%esp)
+ popl %eax
+ cmpl $32767,%eax
+ jg 1f
+ cmpl $-32768,%eax
+ jl 2f
+ movw %ax,(%esi)
+ jmp 4f
+1: movw $32767,(%esi)
+ jmp 3f
+2: movw $-32768,(%esi)
+3: incl %edi
+4:
+.L67:
+ addl $-64,%ebx
+ addl $-128,%ecx
+ addl $4,%esi
+ decl %ebp
+ jnz .L68
+ movl %edi,%eax
+ popl %ebx
+ popl %esi
+ popl %edi
+ popl %ebp
+ addl $12,%esp
+ ret
+
diff --git a/mpg123_artsplugin/mpg123/decode_ntom.c b/mpg123_artsplugin/mpg123/decode_ntom.c
new file mode 100644
index 00000000..41ca0dc0
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/decode_ntom.c
@@ -0,0 +1,290 @@
+/*
+ * Mpeg Layer-1,2,3 audio decoder
+ * ------------------------------
+ * copyright (c) 1995,1996,1997 by Michael Hipp, All rights reserved.
+ * See also 'README'
+ *
+ * N->M down/up sampling. Not optimized for speed.
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include "mpg123.h"
+
+#define WRITE_SAMPLE(samples,sum,clip) \
+ if( (sum) > 32767.0) { *(samples) = 0x7fff; (clip)++; } \
+ else if( (sum) < -32768.0) { *(samples) = -0x8000; (clip)++; } \
+ else { *(samples) = sum; }
+
+#define NTOM_MUL (32768)
+static unsigned long ntom_val[2] = { NTOM_MUL>>1,NTOM_MUL>>1 };
+static unsigned long ntom_step = NTOM_MUL;
+
+
+void synth_ntom_set_step(long m,long n)
+{
+ if(param.verbose > 1)
+ fprintf(stderr,"Init rate converter: %ld->%ld\n",m,n);
+
+ if(n >= 96000 || m >= 96000 || m == 0 || n == 0) {
+ fprintf(stderr,"NtoM converter: illegal rates\n");
+ exit(1);
+ }
+
+ n *= NTOM_MUL;
+ ntom_step = n / m;
+
+ if(ntom_step > 8*NTOM_MUL) {
+ fprintf(stderr,"max. 1:8 conversion allowed!\n");
+ exit(1);
+ }
+
+ ntom_val[0] = ntom_val[1] = NTOM_MUL>>1;
+}
+
+int synth_ntom_8bit(real *bandPtr,int channel,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[8*64];
+ short *tmp1 = samples_tmp + channel;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_ntom(bandPtr,channel,(unsigned char *) samples_tmp,&pnt1);
+ samples += channel + *pnt;
+
+ for(i=0;i<(pnt1>>2);i++) {
+ *samples = conv16to8[*tmp1>>AUSHIFT];
+ samples += 2;
+ tmp1 += 2;
+ }
+ *pnt += pnt1>>1;
+
+ return ret;
+}
+
+int synth_ntom_8bit_mono(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[8*64];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_ntom(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<(pnt1>>2);i++) {
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ tmp1 += 2;
+ }
+ *pnt += pnt1 >> 2;
+
+ return ret;
+}
+
+int synth_ntom_8bit_mono2stereo(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[8*64];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_ntom(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<(pnt1>>2);i++) {
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ *samples++ = conv16to8[*tmp1>>AUSHIFT];
+ tmp1 += 2;
+ }
+ *pnt += pnt1 >> 1;
+
+ return ret;
+}
+
+int synth_ntom_mono(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[8*64];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_ntom(bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<(pnt1>>2);i++) {
+ *( (short *)samples) = *tmp1;
+ samples += 2;
+ tmp1 += 2;
+ }
+ *pnt += pnt1 >> 1;
+
+ return ret;
+}
+
+
+int synth_ntom_mono2stereo(real *bandPtr,unsigned char *samples,int *pnt)
+{
+ int i,ret;
+ int pnt1 = *pnt;
+
+ ret = synth_ntom(bandPtr,0,samples,pnt);
+ samples += pnt1;
+
+ for(i=0;i<((*pnt-pnt1)>>2);i++) {
+ ((short *)samples)[1] = ((short *)samples)[0];
+ samples+=4;
+ }
+
+ return ret;
+}
+
+
+int synth_ntom(real *bandPtr,int channel,unsigned char *out,int *pnt)
+{
+ static real buffs[2][2][0x110];
+ static const int step = 2;
+ static int bo = 1;
+ short *samples = (short *) (out + *pnt);
+
+ real *b0,(*buf)[0x110];
+ int clip = 0;
+ int bo1;
+ int ntom;
+
+#ifndef NO_EQUALIZER
+ if(param.enable_equalizer)
+ do_equalizer(bandPtr,channel);
+#endif
+
+ if(!channel) {
+ bo--;
+ bo &= 0xf;
+ buf = buffs[0];
+ ntom = ntom_val[1] = ntom_val[0];
+ }
+ else {
+ samples++;
+ out += 2; /* to compute the right *pnt value */
+ buf = buffs[1];
+ ntom = ntom_val[1];
+ }
+
+ if(bo & 0x1) {
+ b0 = buf[0];
+ bo1 = bo;
+ dct64(buf[1]+((bo+1)&0xf),buf[0]+bo,bandPtr);
+ }
+ else {
+ b0 = buf[1];
+ bo1 = bo+1;
+ dct64(buf[0]+bo,buf[1]+bo+1,bandPtr);
+ }
+
+
+ {
+ register int j;
+ real *window = decwin + 16 - bo1;
+
+ for (j=16;j;j--,window+=0x10)
+ {
+ real sum;
+
+ ntom += ntom_step;
+ if(ntom < NTOM_MUL) {
+ window += 16;
+ b0 += 16;
+ continue;
+ }
+
+ sum = *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+ sum += *window++ * *b0++;
+ sum -= *window++ * *b0++;
+
+ while(ntom >= NTOM_MUL) {
+ WRITE_SAMPLE(samples,sum,clip);
+ samples += step;
+ ntom -= NTOM_MUL;
+ }
+ }
+
+ ntom += ntom_step;
+ if(ntom >= NTOM_MUL)
+ {
+ real sum;
+ sum = window[0x0] * b0[0x0];
+ sum += window[0x2] * b0[0x2];
+ sum += window[0x4] * b0[0x4];
+ sum += window[0x6] * b0[0x6];
+ sum += window[0x8] * b0[0x8];
+ sum += window[0xA] * b0[0xA];
+ sum += window[0xC] * b0[0xC];
+ sum += window[0xE] * b0[0xE];
+
+ while(ntom >= NTOM_MUL) {
+ WRITE_SAMPLE(samples,sum,clip);
+ samples += step;
+ ntom -= NTOM_MUL;
+ }
+ }
+
+ b0-=0x10,window-=0x20;
+ window += bo1<<1;
+
+ for (j=15;j;j--,b0-=0x20,window-=0x10)
+ {
+ real sum;
+
+ ntom += ntom_step;
+ if(ntom < NTOM_MUL) {
+ window -= 16;
+ b0 += 16;
+ continue;
+ }
+
+ sum = -*(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+ sum -= *(--window) * *b0++;
+
+ while(ntom >= NTOM_MUL) {
+ WRITE_SAMPLE(samples,sum,clip);
+ samples += step;
+ ntom -= NTOM_MUL;
+ }
+ }
+ }
+
+ ntom_val[channel] = ntom;
+ *pnt = ((unsigned char *) samples - out);
+
+ return clip;
+}
+
+
diff --git a/mpg123_artsplugin/mpg123/genre.h b/mpg123_artsplugin/mpg123/genre.h
new file mode 100644
index 00000000..3a6c5ba3
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/genre.h
@@ -0,0 +1,263 @@
+char *genre_table[] =
+{
+ "Blues",
+ "Classic Rock",
+ "Country",
+ "Dance",
+ "Disco",
+ "Funk",
+ "Grunge",
+ "Hip-Hop",
+ "Jazz",
+ "Metal",
+ "New Age",
+ "Oldies",
+ "Other",
+ "Pop",
+ "R&B",
+ "Rap",
+ "Reggae",
+ "Rock",
+ "Techno",
+ "Industrial",
+ "Alternative",
+ "Ska",
+ "Death Metal",
+ "Pranks",
+ "Soundtrack",
+ "Euro-Techno",
+ "Ambient",
+ "Trip-Hop",
+ "Vocal",
+ "Jazz+Funk",
+ "Fusion",
+ "Trance",
+ "Classical",
+ "Instrumental",
+ "Acid",
+ "House",
+ "Game",
+ "Sound Clip",
+ "Gospel",
+ "Noise",
+ "AlternRock",
+ "Bass",
+ "Soul",
+ "Punk",
+ "Space",
+ "Meditative",
+ "Instrumental Pop",
+ "Instrumental Rock",
+ "Ethnic",
+ "Gothic",
+ "Darkwave",
+ "Techno-Industrial",
+ "Electronic",
+ "Pop-Folk",
+ "Eurodance",
+ "Dream",
+ "Southern Rock",
+ "Comedy",
+ "Cult",
+ "Gangsta",
+ "Top 40",
+ "Christian Rap",
+ "Pop/Funk",
+ "Jungle",
+ "Native American",
+ "Cabaret",
+ "New Wave",
+ "Psychadelic",
+ "Rave",
+ "Showtunes",
+ "Trailer",
+ "Lo-Fi",
+ "Tribal",
+ "Acid Punk",
+ "Acid Jazz",
+ "Polka",
+ "Retro",
+ "Musical",
+ "Rock & Roll",
+ "Hard Rock",
+ "Folk",
+ "Folk/Rock",
+ "National folk",
+ "Swing",
+ "Fast-fusion",
+ "Bebob",
+ "Latin",
+ "Revival",
+ "Celtic",
+ "Bluegrass",
+ "Avantgarde",
+ "Gothic Rock",
+ "Progressive Rock",
+ "Psychedelic Rock",
+ "Symphonic Rock",
+ "Slow Rock",
+ "Big Band",
+ "Chorus",
+ "Easy Listening",
+ "Acoustic",
+ "Humour",
+ "Speech",
+ "Chanson",
+ "Opera",
+ "Chamber Music",
+ "Sonata",
+ "Symphony",
+ "Booty Bass",
+ "Primus",
+ "Porn Groove",
+ "Satire",
+ "Slow Jam",
+ "Club",
+ "Tango",
+ "Samba",
+ "Folklore",
+ "Ballad",
+ "Powder Ballad",
+ "Rhythmic Soul",
+ "Freestyle",
+ "Duet",
+ "Punk Rock",
+ "Drum Solo",
+ "A Capella",
+ "Euro-House",
+ "Dance Hall",
+ "Goa",
+ "Drum & Bass",
+ "Club House",
+ "Hardcore",
+ "Terror",
+ "Indie",
+ "BritPop",
+ "NegerPunk",
+ "Polsk Punk",
+ "Beat",
+ "Christian Gangsta",
+ "Heavy Metal",
+ "Black Metal",
+ "Crossover",
+ "Contemporary C",
+ "Christian Rock",
+ "Merengue",
+ "Salsa",
+ "Thrash Metal",
+ "Anime",
+ "JPop",
+ "SynthPop"
+/* ,
+ "Unknown",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+*/
+};
+
+const int genre_count = ((int)(sizeof(genre_table)/sizeof(char*))-1);
diff --git a/mpg123_artsplugin/mpg123/getbits.c b/mpg123_artsplugin/mpg123/getbits.c
new file mode 100644
index 00000000..3ed993cb
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/getbits.c
@@ -0,0 +1,116 @@
+#include "mpg123.h"
+#include "common.h"
+
+void backbits(struct bitstream_info *bitbuf,int number_of_bits)
+{
+ bitbuf->bitindex -= number_of_bits;
+ bitbuf->wordpointer += (bitbuf->bitindex>>3);
+ bitbuf->bitindex &= 0x7;
+}
+
+int getbitoffset(struct bitstream_info *bitbuf)
+{
+ return (-bitbuf->bitindex)&0x7;
+}
+
+int getbyte(struct bitstream_info *bitbuf)
+{
+#ifdef DEBUG_GETBITS
+ if(bitbuf->bitindex)
+ fprintf(stderr,"getbyte called unsynched!\n");
+#endif
+ return *bitbuf->wordpointer++;
+}
+
+unsigned int getbits(struct bitstream_info *bitbuf,int number_of_bits)
+{
+ unsigned long rval;
+
+#ifdef DEBUG_GETBITS
+fprintf(stderr,"g%d",number_of_bits);
+#endif
+
+ if(!number_of_bits)
+ return 0;
+
+#if 0
+ check_buffer_range(number_of_bits+bitbuf->bitindex);
+#endif
+
+ {
+ rval = bitbuf->wordpointer[0];
+ rval <<= 8;
+ rval |= bitbuf->wordpointer[1];
+ rval <<= 8;
+ rval |= bitbuf->wordpointer[2];
+
+ rval <<= bitbuf->bitindex;
+ rval &= 0xffffff;
+
+ bitbuf->bitindex += number_of_bits;
+
+ rval >>= (24-number_of_bits);
+
+ bitbuf->wordpointer += (bitbuf->bitindex>>3);
+ bitbuf->bitindex &= 7;
+ }
+
+#ifdef DEBUG_GETBITS
+fprintf(stderr,":%x ",rval);
+#endif
+
+ return rval;
+}
+
+unsigned int getbits_fast(struct bitstream_info *bitbuf,int number_of_bits)
+{
+ unsigned int rval;
+#ifdef DEBUG_GETBITS
+fprintf(stderr,"g%d",number_of_bits);
+#endif
+
+#if 0
+ check_buffer_range(number_of_bits+bitbuf->bitindex);
+#endif
+
+ rval = (unsigned char) (bitbuf->wordpointer[0] << bitbuf->bitindex);
+ rval |= ((unsigned int) bitbuf->wordpointer[1]<<bitbuf->bitindex)>>8;
+ rval <<= number_of_bits;
+ rval >>= 8;
+
+ bitbuf->bitindex += number_of_bits;
+
+ bitbuf->wordpointer += (bitbuf->bitindex>>3);
+ bitbuf->bitindex &= 7;
+
+#ifdef DEBUG_GETBITS
+fprintf(stderr,":%x ",rval);
+#endif
+ return rval;
+}
+
+unsigned int get1bit(struct bitstream_info *bitbuf)
+{
+ unsigned char rval;
+
+#ifdef DEBUG_GETBITS
+fprintf(stderr,"g%d",1);
+#endif
+
+#if 0
+ check_buffer_range(1+bitbuf->bitindex);
+#endif
+
+ rval = *(bitbuf->wordpointer) << bitbuf->bitindex;
+
+ bitbuf->bitindex++;
+ bitbuf->wordpointer += (bitbuf->bitindex>>3);
+ bitbuf->bitindex &= 7;
+
+#ifdef DEBUG_GETBITS
+fprintf(stderr,":%d ",rval>>7);
+#endif
+
+ return rval>>7;
+}
+
diff --git a/mpg123_artsplugin/mpg123/getbits.h b/mpg123_artsplugin/mpg123/getbits.h
new file mode 100644
index 00000000..65e3e745
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/getbits.h
@@ -0,0 +1,33 @@
+
+/* that's the same file as getits.c but with defines to
+ force inlining */
+
+static unsigned long rval;
+static unsigned char rval_uc;
+
+#define backbits(bitbuf,nob) ((void)( \
+ (*(bitbuf)).bitindex -= (nob), \
+ (*(bitbuf)).wordpointer += ((*(bitbuf)).bitindex>>3), \
+ (*(bitbuf)).bitindex &= 0x7 ))
+
+#define getbitoffset(bitbuf) ((-(*(bitbuf)).bitindex)&0x7)
+#define getbyte(bitbuf) (*(*(bitbuf)).wordpointer++)
+
+#define getbits(bitbuf,nob) ( \
+ rval = (*(bitbuf)).wordpointer[0], rval <<= 8, rval |= (*(bitbuf)).wordpointer[1], \
+ rval <<= 8, rval |= (*(bitbuf)).wordpointer[2], rval <<= (*(bitbuf)).bitindex, \
+ rval &= 0xffffff, (*(bitbuf)).bitindex += (nob), \
+ rval >>= (24-(nob)), (*(bitbuf)).wordpointer += ((*(bitbuf)).bitindex>>3), \
+ (*(bitbuf)).bitindex &= 7,rval)
+
+#define getbits_fast(bitbuf,nob) ( \
+ rval = (unsigned char) ((*(bitbuf)).wordpointer[0] << (*(bitbuf)).bitindex), \
+ rval |= ((unsigned long) (*(bitbuf)).wordpointer[1]<<(*(bitbuf)).bitindex)>>8, \
+ rval <<= (nob), rval >>= 8, \
+ (*(bitbuf)).bitindex += (nob), (*(bitbuf)).wordpointer += ((*(bitbuf)).bitindex>>3), \
+ (*(bitbuf)).bitindex &= 7, rval )
+
+#define get1bit(bitbuf) ( \
+ rval_uc = *(*(bitbuf)).wordpointer << (*(bitbuf)).bitindex, (*(bitbuf)).bitindex++, \
+ (*(bitbuf)).wordpointer += ((*(bitbuf)).bitindex>>3), (*(bitbuf)).bitindex &= 7, rval_uc>>7 )
+
diff --git a/mpg123_artsplugin/mpg123/httpget.c b/mpg123_artsplugin/mpg123/httpget.c
new file mode 100644
index 00000000..71750115
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/httpget.c
@@ -0,0 +1,481 @@
+/*
+ * httpget.c
+ *
+ * Oliver Fromme <oliver.fromme@heim3.tu-clausthal.de>
+ * Wed Apr 9 20:57:47 MET DST 1997
+ */
+
+#undef ALSA
+
+#if !defined(WIN32) && !defined(GENERIC)
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <netdb.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/errno.h>
+#include <ctype.h>
+
+extern int errno;
+
+#include "mpg123.h"
+
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+void writestring (int fd, char *string)
+{
+ int result, bytes = strlen(string);
+
+ while (bytes) {
+ if ((result = write(fd, string, bytes)) < 0 && errno != EINTR) {
+ perror ("write");
+ exit (1);
+ }
+ else if (result == 0) {
+ fprintf (stderr, "write: %s\n",
+ "socket closed unexpectedly");
+ exit (1);
+ }
+ string += result;
+ bytes -= result;
+ }
+}
+
+void readstring (char *string, int maxlen, FILE *f)
+{
+#if 0
+ char *result;
+#endif
+ int pos = 0;
+
+ while(1) {
+ if( read(fileno(f),string+pos,1) == 1) {
+ pos++;
+ if(string[pos-1] == '\n') {
+ string[pos] = 0;
+ break;
+ }
+ }
+ else if(errno != EINTR) {
+ fprintf (stderr, "Error reading from socket or unexpected EOF.\n");
+ exit(1);
+ }
+ }
+#if 0
+ do {
+ result = fgets(string, maxlen, f);
+ } while (!result && errno == EINTR);
+ if (!result) {
+ fprintf (stderr, "Error reading from socket or unexpected EOF.\n");
+ exit (1);
+ }
+#endif
+
+}
+
+void encode64 (char *source,char *destination)
+{
+ static char *Base64Digits =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ int n = 0;
+ int ssiz=strlen(source);
+ int i;
+
+ for (i = 0 ; i < ssiz ; i += 3) {
+ unsigned int buf;
+ buf = ((unsigned char *)source)[i] << 16;
+ if (i+1 < ssiz)
+ buf |= ((unsigned char *)source)[i+1] << 8;
+ if (i+2 < ssiz)
+ buf |= ((unsigned char *)source)[i+2];
+
+ destination[n++] = Base64Digits[(buf >> 18) % 64];
+ destination[n++] = Base64Digits[(buf >> 12) % 64];
+ if (i+1 < ssiz)
+ destination[n++] = Base64Digits[(buf >> 6) % 64];
+ else
+ destination[n++] = '=';
+ if (i+2 < ssiz)
+ destination[n++] = Base64Digits[buf % 64];
+ else
+ destination[n++] = '=';
+ }
+ destination[n++] = 0;
+}
+
+/* VERY simple auth-from-URL grabber */
+int getauthfromURL(char *url,char *auth)
+{
+ char *pos;
+
+ *auth = 0;
+
+ if (!(strncasecmp(url, "http://", 7)))
+ url += 7;
+
+ if (!(strncasecmp(url, "ftp://", 6)))
+ url += 6;
+
+ if( (pos = strchr(url,'@')) ) {
+ int i;
+ for(i=0;i<pos-url;i++) {
+ if( url[i] == '/' )
+ return 0;
+ }
+ strncpy(auth,url,pos-url);
+ auth[pos-url] = 0;
+ strcpy(url,pos+1);
+ return 1;
+ }
+ return 0;
+}
+
+static char *defaultportstr = "80";
+
+char *url2hostport (char *url, char **hname, unsigned long *hip, unsigned char **port)
+{
+ char *h, *p;
+ char *hostptr;
+ char *r_hostptr;
+ char *pathptr;
+ char *portptr;
+ char *p0;
+ size_t stringlength;
+
+ p = url;
+ if (strncasecmp(p, "http://", 7) == 0)
+ p += 7;
+
+ if (strncasecmp(p, "ftp://", 6) == 0)
+ p += 6;
+
+ hostptr = p;
+ while (*p && *p != '/')
+ p++;
+ pathptr = p;
+
+ r_hostptr = --p;
+ while (*p && hostptr < p && *p != ':' && *p != ']')
+ p--;
+
+ if (!*p || p < hostptr || *p != ':') {
+ portptr = NULL;
+ }
+ else{
+ portptr = p + 1;
+ r_hostptr = p - 1;
+ }
+ if (*hostptr == '[' && *r_hostptr == ']') {
+ hostptr++;
+ r_hostptr--;
+ }
+
+ stringlength = r_hostptr - hostptr + 1;
+ h = malloc(stringlength + 1); /* removed the strndup for better portability */
+ if (h == NULL) {
+ *hname = NULL;
+ *port = NULL;
+ return NULL;
+ }
+ strncpy(h, hostptr, stringlength);
+ *(h+stringlength) = '\0';
+ *hname = h;
+
+ if (portptr) {
+ stringlength = (pathptr - portptr);
+ if(!stringlength) portptr = NULL;
+ }
+ if (portptr == NULL) {
+ portptr = defaultportstr;
+ stringlength = strlen(defaultportstr);
+ }
+ p0 = malloc(stringlength + 1);
+ if (p0 == NULL) {
+ free(h);
+ *hname = NULL;
+ *port = NULL;
+ return NULL;
+ }
+ strncpy(p0, portptr, stringlength);
+ *(p0 + stringlength) = '\0';
+
+ for (p = p0; *p && isdigit((unsigned char) *p); p++) ;
+
+ *p = '\0';
+ *port = (unsigned char *) p0;
+
+ return pathptr;
+}
+
+char *proxyurl = NULL;
+unsigned long proxyip = 0;
+unsigned char *proxyport;
+
+#define ACCEPT_HEAD "Accept: audio/mpeg, audio/x-mpegurl, */*\r\n"
+
+char *httpauth = NULL;
+char httpauth1[256];
+
+int http_open (const char *url)
+{
+ char *purl, *host, *request, *sptr;
+ int linelength;
+ unsigned long myip;
+ unsigned char *myport;
+ int sock;
+ int relocate, numrelocs = 0;
+ FILE *myfile;
+#ifdef INET6
+ struct addrinfo hints, *res, *res0;
+ int error;
+#else
+ struct hostent *hp;
+ struct sockaddr_in sin;
+#endif
+
+ host = NULL;
+ proxyport = NULL;
+ myport = NULL;
+ if (!proxyip) {
+ if (!proxyurl)
+ if (!(proxyurl = getenv("MP3_HTTP_PROXY")))
+ if (!(proxyurl = getenv("http_proxy")))
+ proxyurl = getenv("HTTP_PROXY");
+ if (proxyurl && proxyurl[0] && strcmp(proxyurl, "none")) {
+ if (!(url2hostport(proxyurl, &host, &proxyip, &proxyport))) {
+ fprintf (stderr, "Unknown proxy host \"%s\".\n",
+ host ? host : "");
+ exit (1);
+ }
+#if 0
+ if (host)
+ free (host);
+#endif
+ }
+ else
+ proxyip = INADDR_NONE;
+ }
+
+
+ if (proxyip == INADDR_NONE)
+ if (strncasecmp(url, "ftp://", 6) == 0){
+ fprintf(stderr,"Downloading from ftp servers without PROXY not allowed\n");
+ exit(1);
+ }
+
+
+ if ((linelength = strlen(url)+200) < 1024)
+ linelength = 1024;
+ if (!(request = malloc(linelength)) || !(purl = malloc(1024))) {
+ fprintf (stderr, "malloc() failed, out of memory.\n");
+ exit (1);
+ }
+ /*
+ * 2000-10-21:
+ * We would like spaces to be automatically converted to %20's when
+ * fetching via HTTP.
+ * -- Martin Sjögren <md9ms@mdstud.chalmers.se>
+ */
+ if ((sptr = strchr(url, ' ')) == NULL) {
+ strncpy (purl, url, 1023);
+ purl[1023] = '\0';
+ }
+ else {
+ int purllength = 0;
+ char *urlptr = url;
+ purl[0] = '\0';
+ do {
+ purllength += sptr-urlptr + 3;
+ if (purllength >= 1023)
+ break;
+ strncat (purl, urlptr, sptr-urlptr);
+ /*purl[sptr-url] = '\0';*/
+ strcat (purl, "%20");
+ urlptr = sptr + 1;
+ }
+ while ((sptr = strchr (urlptr, ' ')) != NULL);
+ strcat (purl, urlptr);
+ }
+
+
+ getauthfromURL(purl,httpauth1);
+
+ do {
+ strcpy (request, "GET ");
+ if (proxyip != INADDR_NONE) {
+ if (strncasecmp(url, "http://", 7) != 0 && strncasecmp(url,"ftp://", 6) != 0)
+ strcat (request, "http://");
+ strcat (request, purl);
+ myport = proxyport;
+ myip = proxyip;
+ }
+ else {
+ if (host) {
+ free(host);
+ host=NULL;
+ }
+ if (proxyport) {
+ free(proxyport);
+ proxyport=NULL;
+ }
+ if (!(sptr = url2hostport(purl, &host, &myip, &myport))) {
+ fprintf (stderr, "Unknown host \"%s\".\n",
+ host ? host : "");
+ exit (1);
+ }
+ strcat (request, sptr);
+ }
+ sprintf (request + strlen(request),
+ " HTTP/1.0\r\nUser-Agent: %s/%s\r\n",
+ prgName, prgVersion);
+ if (host) {
+ sprintf(request + strlen(request),
+ "Host: %s:%s\r\n", host, myport);
+#if 0
+ free (host);
+#endif
+ }
+ strcat (request, ACCEPT_HEAD);
+
+#ifdef INET6
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ error = getaddrinfo(host, (char *)myport, &hints, &res0);
+ if (error) {
+ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error));
+ exit(1);
+ }
+
+ sock = -1;
+ for (res = res0; res; res = res->ai_next) {
+ if ((sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) {
+ continue;
+ }
+ if (connect(sock, res->ai_addr, res->ai_addrlen)) {
+ close(sock);
+ sock = -1;
+ continue;
+ }
+ break;
+ }
+
+ freeaddrinfo(res0);
+#else
+ sock = -1;
+ hp = gethostbyname(host);
+ if (!hp)
+ goto fail;
+ if (hp->h_length != sizeof(sin.sin_addr))
+ goto fail;
+ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (sock < 0)
+ goto fail;
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ /* sin.sin_len = sizeof(struct sockaddr_in); */
+ memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
+ sin.sin_port = htons(atoi( (char *) myport));
+ if (connect(sock, (struct sockaddr *)&sin, sizeof(struct sockaddr_in) ) < 0) {
+ close(sock);
+ sock = -1;
+ }
+fail:
+#endif
+
+ if (sock < 0) {
+ perror("socket");
+ exit(1);
+ }
+
+ if (strlen(httpauth1) || httpauth) {
+ char buf[1023];
+ strcat (request,"Authorization: Basic ");
+ if(strlen(httpauth1))
+ encode64(httpauth1,buf);
+ else
+ encode64(httpauth,buf);
+ strcat (request,buf);
+ strcat (request,"\r\n");
+ }
+ strcat (request, "\r\n");
+
+ writestring (sock, request);
+ if (!(myfile = fdopen(sock, "rb"))) {
+ perror ("fdopen");
+ exit (1);
+ };
+ relocate = FALSE;
+ purl[0] = '\0';
+ readstring (request, linelength-1, myfile);
+ if ((sptr = strchr(request, ' '))) {
+ switch (sptr[1]) {
+ case '3':
+ relocate = TRUE;
+ case '2':
+ break;
+ default:
+ fprintf (stderr, "HTTP request failed: %s",
+ sptr+1); /* '\n' is included */
+ exit (1);
+ }
+ }
+ do {
+ readstring (request, linelength-1, myfile);
+ if (!strncmp(request, "Location:", 9))
+ strncpy (purl, request+10, 1023);
+ } while (request[0] != '\r' && request[0] != '\n');
+ } while (relocate && purl[0] && numrelocs++ < 5);
+ if (relocate) {
+ fprintf (stderr, "Too many HTTP relocations.\n");
+ exit (1);
+ }
+ free (purl);
+ free (request);
+ free(host);
+ free(proxyport);
+ free(myport);
+
+ return sock;
+}
+
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+extern int errno;
+
+#include "mpg123.h"
+
+void writestring (int fd, char *string)
+{
+}
+
+void readstring (char *string, int maxlen, FILE *f)
+{
+}
+
+char *url2hostport (char *url, char **hname, unsigned long *hip, unsigned int *port)
+{
+}
+
+char *proxyurl = NULL;
+unsigned long proxyip = 0;
+unsigned int proxyport;
+
+#define ACCEPT_HEAD "Accept: audio/mpeg, audio/x-mpegurl, */*\r\n"
+
+int http_open (char *url)
+{
+}
+#endif
+
+/* EOF */
+
diff --git a/mpg123_artsplugin/mpg123/huffman.h b/mpg123_artsplugin/mpg123/huffman.h
new file mode 100644
index 00000000..7fec0d58
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/huffman.h
@@ -0,0 +1,332 @@
+/*
+ * huffman tables ... recalcualted to work with my optimzed
+ * decoder scheme (MH)
+ *
+ * probably we could save a few bytes of memory, because the
+ * smaller tables are often the part of a bigger table
+ */
+
+struct newhuff
+{
+ unsigned int linbits;
+ short *table;
+};
+
+static short tab0[] =
+{
+ 0
+};
+
+static short tab1[] =
+{
+ -5, -3, -1, 17, 1, 16, 0
+};
+
+static short tab2[] =
+{
+ -15, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 17, -1, 1,
+ 16, 0
+};
+
+static short tab3[] =
+{
+ -13, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 16, 17, -1,
+ 1, 0
+};
+
+static short tab5[] =
+{
+ -29, -25, -23, -15, -7, -5, -3, -1, 51, 35, 50, 49, -3, -1, 19,
+ 3, -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, 17, -1, 1, 16,
+ 0
+};
+
+static short tab6[] =
+{
+ -25, -19, -13, -9, -5, -3, -1, 51, 3, 35, -1, 50, 48, -1, 19,
+ 49, -3, -1, 34, 2, 18, -3, -1, 33, 32, 1, -1, 17, -1, 16,
+ 0
+};
+
+static short tab7[] =
+{
+ -69, -65, -57, -39, -29, -17, -11, -7, -3, -1, 85, 69, -1, 84, 83,
+ -1, 53, 68, -3, -1, 37, 82, 21, -5, -1, 81, -1, 5, 52, -1,
+ 80, -1, 67, 51, -5, -3, -1, 36, 66, 20, -1, 65, 64, -11, -7,
+ -3, -1, 4, 35, -1, 50, 3, -1, 19, 49, -3, -1, 48, 34, 18,
+ -5, -1, 33, -1, 2, 32, 17, -1, 1, 16, 0
+};
+
+static short tab8[] =
+{
+ -65, -63, -59, -45, -31, -19, -13, -7, -5, -3, -1, 85, 84, 69, 83,
+ -3, -1, 53, 68, 37, -3, -1, 82, 5, 21, -5, -1, 81, -1, 52,
+ 67, -3, -1, 80, 51, 36, -5, -3, -1, 66, 20, 65, -3, -1, 4,
+ 64, -1, 35, 50, -9, -7, -3, -1, 19, 49, -1, 3, 48, 34, -1,
+ 2, 32, -1, 18, 33, 17, -3, -1, 1, 16, 0
+};
+
+static short tab9[] =
+{
+ -63, -53, -41, -29, -19, -11, -5, -3, -1, 85, 69, 53, -1, 83, -1,
+ 84, 5, -3, -1, 68, 37, -1, 82, 21, -3, -1, 81, 52, -1, 67,
+ -1, 80, 4, -7, -3, -1, 36, 66, -1, 51, 64, -1, 20, 65, -5,
+ -3, -1, 35, 50, 19, -1, 49, -1, 3, 48, -5, -3, -1, 34, 2,
+ 18, -1, 33, 32, -3, -1, 17, 1, -1, 16, 0
+};
+
+static short tab10[] =
+{
+-125,-121,-111, -83, -55, -35, -21, -13, -7, -3, -1, 119, 103, -1, 118,
+ 87, -3, -1, 117, 102, 71, -3, -1, 116, 86, -1, 101, 55, -9, -3,
+ -1, 115, 70, -3, -1, 85, 84, 99, -1, 39, 114, -11, -5, -3, -1,
+ 100, 7, 112, -1, 98, -1, 69, 53, -5, -1, 6, -1, 83, 68, 23,
+ -17, -5, -1, 113, -1, 54, 38, -5, -3, -1, 37, 82, 21, -1, 81,
+ -1, 52, 67, -3, -1, 22, 97, -1, 96, -1, 5, 80, -19, -11, -7,
+ -3, -1, 36, 66, -1, 51, 4, -1, 20, 65, -3, -1, 64, 35, -1,
+ 50, 3, -3, -1, 19, 49, -1, 48, 34, -7, -3, -1, 18, 33, -1,
+ 2, 32, 17, -1, 1, 16, 0
+};
+
+static short tab11[] =
+{
+-121,-113, -89, -59, -43, -27, -17, -7, -3, -1, 119, 103, -1, 118, 117,
+ -3, -1, 102, 71, -1, 116, -1, 87, 85, -5, -3, -1, 86, 101, 55,
+ -1, 115, 70, -9, -7, -3, -1, 69, 84, -1, 53, 83, 39, -1, 114,
+ -1, 100, 7, -5, -1, 113, -1, 23, 112, -3, -1, 54, 99, -1, 96,
+ -1, 68, 37, -13, -7, -5, -3, -1, 82, 5, 21, 98, -3, -1, 38,
+ 6, 22, -5, -1, 97, -1, 81, 52, -5, -1, 80, -1, 67, 51, -1,
+ 36, 66, -15, -11, -7, -3, -1, 20, 65, -1, 4, 64, -1, 35, 50,
+ -1, 19, 49, -5, -3, -1, 3, 48, 34, 33, -5, -1, 18, -1, 2,
+ 32, 17, -3, -1, 1, 16, 0
+};
+
+static short tab12[] =
+{
+-115, -99, -73, -45, -27, -17, -9, -5, -3, -1, 119, 103, 118, -1, 87,
+ 117, -3, -1, 102, 71, -1, 116, 101, -3, -1, 86, 55, -3, -1, 115,
+ 85, 39, -7, -3, -1, 114, 70, -1, 100, 23, -5, -1, 113, -1, 7,
+ 112, -1, 54, 99, -13, -9, -3, -1, 69, 84, -1, 68, -1, 6, 5,
+ -1, 38, 98, -5, -1, 97, -1, 22, 96, -3, -1, 53, 83, -1, 37,
+ 82, -17, -7, -3, -1, 21, 81, -1, 52, 67, -5, -3, -1, 80, 4,
+ 36, -1, 66, 20, -3, -1, 51, 65, -1, 35, 50, -11, -7, -5, -3,
+ -1, 64, 3, 48, 19, -1, 49, 34, -1, 18, 33, -7, -5, -3, -1,
+ 2, 32, 0, 17, -1, 1, 16
+};
+
+static short tab13[] =
+{
+-509,-503,-475,-405,-333,-265,-205,-153,-115, -83, -53, -35, -21, -13, -9,
+ -7, -5, -3, -1, 254, 252, 253, 237, 255, -1, 239, 223, -3, -1, 238,
+ 207, -1, 222, 191, -9, -3, -1, 251, 206, -1, 220, -1, 175, 233, -1,
+ 236, 221, -9, -5, -3, -1, 250, 205, 190, -1, 235, 159, -3, -1, 249,
+ 234, -1, 189, 219, -17, -9, -3, -1, 143, 248, -1, 204, -1, 174, 158,
+ -5, -1, 142, -1, 127, 126, 247, -5, -1, 218, -1, 173, 188, -3, -1,
+ 203, 246, 111, -15, -7, -3, -1, 232, 95, -1, 157, 217, -3, -1, 245,
+ 231, -1, 172, 187, -9, -3, -1, 79, 244, -3, -1, 202, 230, 243, -1,
+ 63, -1, 141, 216, -21, -9, -3, -1, 47, 242, -3, -1, 110, 156, 15,
+ -5, -3, -1, 201, 94, 171, -3, -1, 125, 215, 78, -11, -5, -3, -1,
+ 200, 214, 62, -1, 185, -1, 155, 170, -1, 31, 241, -23, -13, -5, -1,
+ 240, -1, 186, 229, -3, -1, 228, 140, -1, 109, 227, -5, -1, 226, -1,
+ 46, 14, -1, 30, 225, -15, -7, -3, -1, 224, 93, -1, 213, 124, -3,
+ -1, 199, 77, -1, 139, 184, -7, -3, -1, 212, 154, -1, 169, 108, -1,
+ 198, 61, -37, -21, -9, -5, -3, -1, 211, 123, 45, -1, 210, 29, -5,
+ -1, 183, -1, 92, 197, -3, -1, 153, 122, 195, -7, -5, -3, -1, 167,
+ 151, 75, 209, -3, -1, 13, 208, -1, 138, 168, -11, -7, -3, -1, 76,
+ 196, -1, 107, 182, -1, 60, 44, -3, -1, 194, 91, -3, -1, 181, 137,
+ 28, -43, -23, -11, -5, -1, 193, -1, 152, 12, -1, 192, -1, 180, 106,
+ -5, -3, -1, 166, 121, 59, -1, 179, -1, 136, 90, -11, -5, -1, 43,
+ -1, 165, 105, -1, 164, -1, 120, 135, -5, -1, 148, -1, 119, 118, 178,
+ -11, -3, -1, 27, 177, -3, -1, 11, 176, -1, 150, 74, -7, -3, -1,
+ 58, 163, -1, 89, 149, -1, 42, 162, -47, -23, -9, -3, -1, 26, 161,
+ -3, -1, 10, 104, 160, -5, -3, -1, 134, 73, 147, -3, -1, 57, 88,
+ -1, 133, 103, -9, -3, -1, 41, 146, -3, -1, 87, 117, 56, -5, -1,
+ 131, -1, 102, 71, -3, -1, 116, 86, -1, 101, 115, -11, -3, -1, 25,
+ 145, -3, -1, 9, 144, -1, 72, 132, -7, -5, -1, 114, -1, 70, 100,
+ 40, -1, 130, 24, -41, -27, -11, -5, -3, -1, 55, 39, 23, -1, 113,
+ -1, 85, 7, -7, -3, -1, 112, 54, -1, 99, 69, -3, -1, 84, 38,
+ -1, 98, 53, -5, -1, 129, -1, 8, 128, -3, -1, 22, 97, -1, 6,
+ 96, -13, -9, -5, -3, -1, 83, 68, 37, -1, 82, 5, -1, 21, 81,
+ -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20, -19, -11,
+ -5, -1, 65, -1, 4, 64, -3, -1, 35, 50, 19, -3, -1, 49, 3,
+ -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16,
+ 0
+};
+
+static short tab15[] =
+{
+-495,-445,-355,-263,-183,-115, -77, -43, -27, -13, -7, -3, -1, 255, 239,
+ -1, 254, 223, -1, 238, -1, 253, 207, -7, -3, -1, 252, 222, -1, 237,
+ 191, -1, 251, -1, 206, 236, -7, -3, -1, 221, 175, -1, 250, 190, -3,
+ -1, 235, 205, -1, 220, 159, -15, -7, -3, -1, 249, 234, -1, 189, 219,
+ -3, -1, 143, 248, -1, 204, 158, -7, -3, -1, 233, 127, -1, 247, 173,
+ -3, -1, 218, 188, -1, 111, -1, 174, 15, -19, -11, -3, -1, 203, 246,
+ -3, -1, 142, 232, -1, 95, 157, -3, -1, 245, 126, -1, 231, 172, -9,
+ -3, -1, 202, 187, -3, -1, 217, 141, 79, -3, -1, 244, 63, -1, 243,
+ 216, -33, -17, -9, -3, -1, 230, 47, -1, 242, -1, 110, 240, -3, -1,
+ 31, 241, -1, 156, 201, -7, -3, -1, 94, 171, -1, 186, 229, -3, -1,
+ 125, 215, -1, 78, 228, -15, -7, -3, -1, 140, 200, -1, 62, 109, -3,
+ -1, 214, 227, -1, 155, 185, -7, -3, -1, 46, 170, -1, 226, 30, -5,
+ -1, 225, -1, 14, 224, -1, 93, 213, -45, -25, -13, -7, -3, -1, 124,
+ 199, -1, 77, 139, -1, 212, -1, 184, 154, -7, -3, -1, 169, 108, -1,
+ 198, 61, -1, 211, 210, -9, -5, -3, -1, 45, 13, 29, -1, 123, 183,
+ -5, -1, 209, -1, 92, 208, -1, 197, 138, -17, -7, -3, -1, 168, 76,
+ -1, 196, 107, -5, -1, 182, -1, 153, 12, -1, 60, 195, -9, -3, -1,
+ 122, 167, -1, 166, -1, 192, 11, -1, 194, -1, 44, 91, -55, -29, -15,
+ -7, -3, -1, 181, 28, -1, 137, 152, -3, -1, 193, 75, -1, 180, 106,
+ -5, -3, -1, 59, 121, 179, -3, -1, 151, 136, -1, 43, 90, -11, -5,
+ -1, 178, -1, 165, 27, -1, 177, -1, 176, 105, -7, -3, -1, 150, 74,
+ -1, 164, 120, -3, -1, 135, 58, 163, -17, -7, -3, -1, 89, 149, -1,
+ 42, 162, -3, -1, 26, 161, -3, -1, 10, 160, 104, -7, -3, -1, 134,
+ 73, -1, 148, 57, -5, -1, 147, -1, 119, 9, -1, 88, 133, -53, -29,
+ -13, -7, -3, -1, 41, 103, -1, 118, 146, -1, 145, -1, 25, 144, -7,
+ -3, -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 71, -7,
+ -3, -1, 40, 130, -1, 24, 129, -7, -3, -1, 116, 8, -1, 128, 86,
+ -3, -1, 101, 55, -1, 115, 70, -17, -7, -3, -1, 39, 114, -1, 100,
+ 23, -3, -1, 85, 113, -3, -1, 7, 112, 54, -7, -3, -1, 99, 69,
+ -1, 84, 38, -3, -1, 98, 22, -3, -1, 6, 96, 53, -33, -19, -9,
+ -5, -1, 97, -1, 83, 68, -1, 37, 82, -3, -1, 21, 81, -3, -1,
+ 5, 80, 52, -7, -3, -1, 67, 36, -1, 66, 51, -1, 65, -1, 20,
+ 4, -9, -3, -1, 35, 50, -3, -1, 64, 3, 19, -3, -1, 49, 48,
+ 34, -9, -7, -3, -1, 18, 33, -1, 2, 32, 17, -3, -1, 1, 16,
+ 0
+};
+
+static short tab16[] =
+{
+-509,-503,-461,-323,-103, -37, -27, -15, -7, -3, -1, 239, 254, -1, 223,
+ 253, -3, -1, 207, 252, -1, 191, 251, -5, -1, 175, -1, 250, 159, -3,
+ -1, 249, 248, 143, -7, -3, -1, 127, 247, -1, 111, 246, 255, -9, -5,
+ -3, -1, 95, 245, 79, -1, 244, 243, -53, -1, 240, -1, 63, -29, -19,
+ -13, -7, -5, -1, 206, -1, 236, 221, 222, -1, 233, -1, 234, 217, -1,
+ 238, -1, 237, 235, -3, -1, 190, 205, -3, -1, 220, 219, 174, -11, -5,
+ -1, 204, -1, 173, 218, -3, -1, 126, 172, 202, -5, -3, -1, 201, 125,
+ 94, 189, 242, -93, -5, -3, -1, 47, 15, 31, -1, 241, -49, -25, -13,
+ -5, -1, 158, -1, 188, 203, -3, -1, 142, 232, -1, 157, 231, -7, -3,
+ -1, 187, 141, -1, 216, 110, -1, 230, 156, -13, -7, -3, -1, 171, 186,
+ -1, 229, 215, -1, 78, -1, 228, 140, -3, -1, 200, 62, -1, 109, -1,
+ 214, 155, -19, -11, -5, -3, -1, 185, 170, 225, -1, 212, -1, 184, 169,
+ -5, -1, 123, -1, 183, 208, 227, -7, -3, -1, 14, 224, -1, 93, 213,
+ -3, -1, 124, 199, -1, 77, 139, -75, -45, -27, -13, -7, -3, -1, 154,
+ 108, -1, 198, 61, -3, -1, 92, 197, 13, -7, -3, -1, 138, 168, -1,
+ 153, 76, -3, -1, 182, 122, 60, -11, -5, -3, -1, 91, 137, 28, -1,
+ 192, -1, 152, 121, -1, 226, -1, 46, 30, -15, -7, -3, -1, 211, 45,
+ -1, 210, 209, -5, -1, 59, -1, 151, 136, 29, -7, -3, -1, 196, 107,
+ -1, 195, 167, -1, 44, -1, 194, 181, -23, -13, -7, -3, -1, 193, 12,
+ -1, 75, 180, -3, -1, 106, 166, 179, -5, -3, -1, 90, 165, 43, -1,
+ 178, 27, -13, -5, -1, 177, -1, 11, 176, -3, -1, 105, 150, -1, 74,
+ 164, -5, -3, -1, 120, 135, 163, -3, -1, 58, 89, 42, -97, -57, -33,
+ -19, -11, -5, -3, -1, 149, 104, 161, -3, -1, 134, 119, 148, -5, -3,
+ -1, 73, 87, 103, 162, -5, -1, 26, -1, 10, 160, -3, -1, 57, 147,
+ -1, 88, 133, -9, -3, -1, 41, 146, -3, -1, 118, 9, 25, -5, -1,
+ 145, -1, 144, 72, -3, -1, 132, 117, -1, 56, 131, -21, -11, -5, -3,
+ -1, 102, 40, 130, -3, -1, 71, 116, 24, -3, -1, 129, 128, -3, -1,
+ 8, 86, 55, -9, -5, -1, 115, -1, 101, 70, -1, 39, 114, -5, -3,
+ -1, 100, 85, 7, 23, -23, -13, -5, -1, 113, -1, 112, 54, -3, -1,
+ 99, 69, -1, 84, 38, -3, -1, 98, 22, -1, 97, -1, 6, 96, -9,
+ -5, -1, 83, -1, 53, 68, -1, 37, 82, -1, 81, -1, 21, 5, -33,
+ -23, -13, -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20,
+ -5, -1, 65, -1, 4, 64, -1, 35, 50, -3, -1, 19, 49, -3, -1,
+ 3, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16,
+ 0
+};
+
+static short tab24[] =
+{
+-451,-117, -43, -25, -15, -7, -3, -1, 239, 254, -1, 223, 253, -3, -1,
+ 207, 252, -1, 191, 251, -5, -1, 250, -1, 175, 159, -1, 249, 248, -9,
+ -5, -3, -1, 143, 127, 247, -1, 111, 246, -3, -1, 95, 245, -1, 79,
+ 244, -71, -7, -3, -1, 63, 243, -1, 47, 242, -5, -1, 241, -1, 31,
+ 240, -25, -9, -1, 15, -3, -1, 238, 222, -1, 237, 206, -7, -3, -1,
+ 236, 221, -1, 190, 235, -3, -1, 205, 220, -1, 174, 234, -15, -7, -3,
+ -1, 189, 219, -1, 204, 158, -3, -1, 233, 173, -1, 218, 188, -7, -3,
+ -1, 203, 142, -1, 232, 157, -3, -1, 217, 126, -1, 231, 172, 255,-235,
+-143, -77, -45, -25, -15, -7, -3, -1, 202, 187, -1, 141, 216, -5, -3,
+ -1, 14, 224, 13, 230, -5, -3, -1, 110, 156, 201, -1, 94, 186, -9,
+ -5, -1, 229, -1, 171, 125, -1, 215, 228, -3, -1, 140, 200, -3, -1,
+ 78, 46, 62, -15, -7, -3, -1, 109, 214, -1, 227, 155, -3, -1, 185,
+ 170, -1, 226, 30, -7, -3, -1, 225, 93, -1, 213, 124, -3, -1, 199,
+ 77, -1, 139, 184, -31, -15, -7, -3, -1, 212, 154, -1, 169, 108, -3,
+ -1, 198, 61, -1, 211, 45, -7, -3, -1, 210, 29, -1, 123, 183, -3,
+ -1, 209, 92, -1, 197, 138, -17, -7, -3, -1, 168, 153, -1, 76, 196,
+ -3, -1, 107, 182, -3, -1, 208, 12, 60, -7, -3, -1, 195, 122, -1,
+ 167, 44, -3, -1, 194, 91, -1, 181, 28, -57, -35, -19, -7, -3, -1,
+ 137, 152, -1, 193, 75, -5, -3, -1, 192, 11, 59, -3, -1, 176, 10,
+ 26, -5, -1, 180, -1, 106, 166, -3, -1, 121, 151, -3, -1, 160, 9,
+ 144, -9, -3, -1, 179, 136, -3, -1, 43, 90, 178, -7, -3, -1, 165,
+ 27, -1, 177, 105, -1, 150, 164, -17, -9, -5, -3, -1, 74, 120, 135,
+ -1, 58, 163, -3, -1, 89, 149, -1, 42, 162, -7, -3, -1, 161, 104,
+ -1, 134, 119, -3, -1, 73, 148, -1, 57, 147, -63, -31, -15, -7, -3,
+ -1, 88, 133, -1, 41, 103, -3, -1, 118, 146, -1, 25, 145, -7, -3,
+ -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 40, -17, -7,
+ -3, -1, 130, 24, -1, 71, 116, -5, -1, 129, -1, 8, 128, -1, 86,
+ 101, -7, -5, -1, 23, -1, 7, 112, 115, -3, -1, 55, 39, 114, -15,
+ -7, -3, -1, 70, 100, -1, 85, 113, -3, -1, 54, 99, -1, 69, 84,
+ -7, -3, -1, 38, 98, -1, 22, 97, -5, -3, -1, 6, 96, 53, -1,
+ 83, 68, -51, -37, -23, -15, -9, -3, -1, 37, 82, -1, 21, -1, 5,
+ 80, -1, 81, -1, 52, 67, -3, -1, 36, 66, -1, 51, 20, -9, -5,
+ -1, 65, -1, 4, 64, -1, 35, 50, -1, 19, 49, -7, -5, -3, -1,
+ 3, 48, 34, 18, -1, 33, -1, 2, 32, -3, -1, 17, 1, -1, 16,
+ 0
+};
+
+static short tab_c0[] =
+{
+ -29, -21, -13, -7, -3, -1, 11, 15, -1, 13, 14, -3, -1, 7, 5,
+ 9, -3, -1, 6, 3, -1, 10, 12, -3, -1, 2, 1, -1, 4, 8,
+ 0
+};
+
+static short tab_c1[] =
+{
+ -15, -7, -3, -1, 15, 14, -1, 13, 12, -3, -1, 11, 10, -1, 9,
+ 8, -7, -3, -1, 7, 6, -1, 5, 4, -3, -1, 3, 2, -1, 1,
+ 0
+};
+
+
+
+static struct newhuff ht[] =
+{
+ { /* 0 */ 0 , tab0 } ,
+ { /* 2 */ 0 , tab1 } ,
+ { /* 3 */ 0 , tab2 } ,
+ { /* 3 */ 0 , tab3 } ,
+ { /* 0 */ 0 , tab0 } ,
+ { /* 4 */ 0 , tab5 } ,
+ { /* 4 */ 0 , tab6 } ,
+ { /* 6 */ 0 , tab7 } ,
+ { /* 6 */ 0 , tab8 } ,
+ { /* 6 */ 0 , tab9 } ,
+ { /* 8 */ 0 , tab10 } ,
+ { /* 8 */ 0 , tab11 } ,
+ { /* 8 */ 0 , tab12 } ,
+ { /* 16 */ 0 , tab13 } ,
+ { /* 0 */ 0 , tab0 } ,
+ { /* 16 */ 0 , tab15 } ,
+
+ { /* 16 */ 1 , tab16 } ,
+ { /* 16 */ 2 , tab16 } ,
+ { /* 16 */ 3 , tab16 } ,
+ { /* 16 */ 4 , tab16 } ,
+ { /* 16 */ 6 , tab16 } ,
+ { /* 16 */ 8 , tab16 } ,
+ { /* 16 */ 10, tab16 } ,
+ { /* 16 */ 13, tab16 } ,
+ { /* 16 */ 4 , tab24 } ,
+ { /* 16 */ 5 , tab24 } ,
+ { /* 16 */ 6 , tab24 } ,
+ { /* 16 */ 7 , tab24 } ,
+ { /* 16 */ 8 , tab24 } ,
+ { /* 16 */ 9 , tab24 } ,
+ { /* 16 */ 11, tab24 } ,
+ { /* 16 */ 13, tab24 }
+};
+
+static struct newhuff htc[] =
+{
+ { /* 1 , 1 , */ 0 , tab_c0 } ,
+ { /* 1 , 1 , */ 0 , tab_c1 }
+};
+
+
diff --git a/mpg123_artsplugin/mpg123/l2tables.h b/mpg123_artsplugin/mpg123/l2tables.h
new file mode 100644
index 00000000..643201ef
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/l2tables.h
@@ -0,0 +1,154 @@
+/*
+ * Layer 2 Alloc tables ..
+ * most other tables are calculated on program start (which is (of course)
+ * not ISO-conform) ..
+ * Layer-3 huffman table is in huffman.h
+ */
+
+struct al_table alloc_0[] = {
+ {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
+ {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
+ {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
+ {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
+ {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
+ {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767} };
+
+struct al_table alloc_1[] = {
+ {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
+ {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
+ {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
+ {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
+ {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
+ {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767} };
+
+struct al_table alloc_2[] = {
+ {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
+ {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
+ {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
+ {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} };
+
+struct al_table alloc_3[] = {
+ {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
+ {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
+ {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
+ {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} };
+
+struct al_table alloc_4[] = {
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9} };
+
diff --git a/mpg123_artsplugin/mpg123/layer1.c b/mpg123_artsplugin/mpg123/layer1.c
new file mode 100644
index 00000000..a33335ab
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/layer1.c
@@ -0,0 +1,157 @@
+/*
+ * Mpeg Layer-1 audio decoder
+ * --------------------------
+ * copyright (c) 1995 by Michael Hipp, All rights reserved. See also 'README'
+ * near unoptimzed ...
+ *
+ * may have a few bugs after last optimization ...
+ *
+ */
+
+#include "mpg123.h"
+
+#include "getbits.h"
+
+void I_step_one(unsigned int balloc[], unsigned int scale_index[2][SBLIMIT],struct frame *fr)
+{
+ unsigned int *ba=balloc;
+ unsigned int *sca = (unsigned int *) scale_index;
+
+ if(fr->stereo) {
+ int i;
+ int jsbound = fr->jsbound;
+ for (i=0;i<jsbound;i++) {
+ *ba++ = getbits(&bsi,4);
+ *ba++ = getbits(&bsi,4);
+ }
+ for (i=jsbound;i<SBLIMIT;i++)
+ *ba++ = getbits(&bsi,4);
+
+ ba = balloc;
+
+ for (i=0;i<jsbound;i++) {
+ if ((*ba++))
+ *sca++ = getbits(&bsi,6);
+ if ((*ba++))
+ *sca++ = getbits(&bsi,6);
+ }
+ for (i=jsbound;i<SBLIMIT;i++)
+ if ((*ba++)) {
+ *sca++ = getbits(&bsi,6);
+ *sca++ = getbits(&bsi,6);
+ }
+ }
+ else {
+ int i;
+ for (i=0;i<SBLIMIT;i++)
+ *ba++ = getbits(&bsi,4);
+ ba = balloc;
+ for (i=0;i<SBLIMIT;i++)
+ if ((*ba++))
+ *sca++ = getbits(&bsi,6);
+ }
+}
+
+void I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT],
+ unsigned int scale_index[2][SBLIMIT],struct frame *fr)
+{
+ int i,n;
+ int smpb[2*SBLIMIT]; /* values: 0-65535 */
+ int *sample;
+ register unsigned int *ba;
+ register unsigned int *sca = (unsigned int *) scale_index;
+
+ if(fr->stereo) {
+ int jsbound = fr->jsbound;
+ register real *f0 = fraction[0];
+ register real *f1 = fraction[1];
+ ba = balloc;
+ for (sample=smpb,i=0;i<jsbound;i++) {
+ if ((n = *ba++))
+ *sample++ = getbits(&bsi,n+1);
+ if ((n = *ba++))
+ *sample++ = getbits(&bsi,n+1);
+ }
+ for (i=jsbound;i<SBLIMIT;i++)
+ if ((n = *ba++))
+ *sample++ = getbits(&bsi,n+1);
+
+ ba = balloc;
+ for (sample=smpb,i=0;i<jsbound;i++) {
+ if((n=*ba++))
+ *f0++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
+ else
+ *f0++ = 0.0;
+ if((n=*ba++))
+ *f1++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
+ else
+ *f1++ = 0.0;
+ }
+ for (i=jsbound;i<SBLIMIT;i++) {
+ if ((n=*ba++)) {
+ real samp = ( ((-1)<<n) + (*sample++) + 1);
+ *f0++ = samp * muls[n+1][*sca++];
+ *f1++ = samp * muls[n+1][*sca++];
+ }
+ else
+ *f0++ = *f1++ = 0.0;
+ }
+ for(i=fr->down_sample_sblimit;i<32;i++)
+ fraction[0][i] = fraction[1][i] = 0.0;
+ }
+ else {
+ register real *f0 = fraction[0];
+ ba = balloc;
+ for (sample=smpb,i=0;i<SBLIMIT;i++)
+ if ((n = *ba++))
+ *sample++ = getbits(&bsi,n+1);
+ ba = balloc;
+ for (sample=smpb,i=0;i<SBLIMIT;i++) {
+ if((n=*ba++))
+ *f0++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
+ else
+ *f0++ = 0.0;
+ }
+ for(i=fr->down_sample_sblimit;i<32;i++)
+ fraction[0][i] = 0.0;
+ }
+}
+
+int do_layer1(struct mpstr *mp,struct frame *fr,int outmode,struct audio_info_struct *ai)
+{
+ int clip=0;
+ int i,stereo = fr->stereo;
+ unsigned int balloc[2*SBLIMIT];
+ unsigned int scale_index[2][SBLIMIT];
+ real fraction[2][SBLIMIT];
+ int single = fr->single;
+
+ fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext<<2)+4 : 32;
+
+ if(stereo == 1 || single == 3)
+ single = 0;
+
+ I_step_one(balloc,scale_index,fr);
+
+ for (i=0;i<SCALE_BLOCK;i++)
+ {
+ I_step_two(fraction,balloc,scale_index,fr);
+
+ if(single >= 0)
+ {
+ clip += (fr->synth_mono)( (real *) fraction[single],pcm_sample,&pcm_point);
+ }
+ else {
+ int p1 = pcm_point;
+ clip += (fr->synth)( (real *) fraction[0],0,pcm_sample,&p1);
+ clip += (fr->synth)( (real *) fraction[1],1,pcm_sample,&pcm_point);
+ }
+
+ if(pcm_point >= audiobufsize)
+ audio_flush(outmode,ai);
+ }
+
+ return clip;
+}
+
+
diff --git a/mpg123_artsplugin/mpg123/layer2.c b/mpg123_artsplugin/mpg123/layer2.c
new file mode 100644
index 00000000..54ba1fd0
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/layer2.c
@@ -0,0 +1,318 @@
+/*
+ * Mpeg Layer-2 audio decoder
+ * --------------------------
+ * copyright (c) 1995 by Michael Hipp, All rights reserved. See also 'README'
+ *
+ */
+
+#include "mpg123.h"
+#include "l2tables.h"
+
+#include "getbits.h"
+
+static int grp_3tab[32 * 3] = { 0, }; /* used: 27 */
+static int grp_5tab[128 * 3] = { 0, }; /* used: 125 */
+static int grp_9tab[1024 * 3] = { 0, }; /* used: 729 */
+
+real muls[27][64]; /* also used by layer 1 */
+
+
+void init_layer2(void)
+{
+ static double mulmul[27] = {
+ 0.0 , -2.0/3.0 , 2.0/3.0 ,
+ 2.0/7.0 , 2.0/15.0 , 2.0/31.0, 2.0/63.0 , 2.0/127.0 , 2.0/255.0 ,
+ 2.0/511.0 , 2.0/1023.0 , 2.0/2047.0 , 2.0/4095.0 , 2.0/8191.0 ,
+ 2.0/16383.0 , 2.0/32767.0 , 2.0/65535.0 ,
+ -4.0/5.0 , -2.0/5.0 , 2.0/5.0, 4.0/5.0 ,
+ -8.0/9.0 , -4.0/9.0 , -2.0/9.0 , 2.0/9.0 , 4.0/9.0 , 8.0/9.0 };
+ static int base[3][9] = {
+ { 1 , 0, 2 , } ,
+ { 17, 18, 0 , 19, 20 , } ,
+ { 21, 1, 22, 23, 0, 24, 25, 2, 26 } };
+ int i,j,k,l,len;
+ real *table;
+ static int tablen[3] = { 3 , 5 , 9 };
+ static int *itable,*tables[3] = { grp_3tab , grp_5tab , grp_9tab };
+#ifdef REAL_IS_FIXED
+ const double twotothethird = pow((double)2.0, (double)1/3);
+#endif
+
+ for(i=0;i<3;i++)
+ {
+ itable = tables[i];
+ len = tablen[i];
+ for(j=0;j<len;j++)
+ for(k=0;k<len;k++)
+ for(l=0;l<len;l++)
+ {
+ *itable++ = base[i][l];
+ *itable++ = base[i][k];
+ *itable++ = base[i][j];
+ }
+ }
+
+ for(k=0;k<27;k++)
+ {
+ double m=mulmul[k];
+#ifdef REAL_IS_FIXED
+ double oldtable = m * 2.0 * twotothethird;
+#endif
+
+ table = muls[k];
+#ifdef USE_MMX
+ if(!param.down_sample)
+ for(j=3,i=0;i<63;i++,j--)
+ *table++ = 16384 * m * pow(2.0,(double) j / 3.0);
+ else
+#endif
+ for(j=3,i=0;i<63;i++,j--) {
+#ifdef REAL_IS_FIXED
+ *table = oldtable / twotothethird;
+ oldtable = *table++;
+#else
+ *table++ = m * pow(2.0,(double) j / 3.0);
+#endif
+ }
+ *table++ = 0.0;
+ }
+}
+
+
+void II_step_one(unsigned int *bit_alloc,int *scale,struct frame *fr)
+{
+ int stereo = fr->stereo-1;
+ int sblimit = fr->II_sblimit;
+ int jsbound = fr->jsbound;
+ int sblimit2 = fr->II_sblimit<<stereo;
+ struct al_table *alloc1 = fr->alloc;
+ int i;
+ static unsigned int scfsi_buf[64];
+ unsigned int *scfsi,*bita;
+ int sc,step;
+
+ bita = bit_alloc;
+ if(stereo)
+ {
+ for (i=jsbound;i;i--,alloc1+=(1<<step))
+ {
+ *bita++ = (char) getbits(&bsi,step=alloc1->bits);
+ *bita++ = (char) getbits(&bsi,step);
+ }
+ for (i=sblimit-jsbound;i;i--,alloc1+=(1<<step))
+ {
+ bita[0] = (char) getbits(&bsi,step=alloc1->bits);
+ bita[1] = bita[0];
+ bita+=2;
+ }
+ bita = bit_alloc;
+ scfsi=scfsi_buf;
+ for (i=sblimit2;i;i--)
+ if (*bita++)
+ *scfsi++ = (char) getbits_fast(&bsi,2);
+ }
+ else /* mono */
+ {
+ for (i=sblimit;i;i--,alloc1+=(1<<step))
+ *bita++ = (char) getbits(&bsi,step=alloc1->bits);
+ bita = bit_alloc;
+ scfsi=scfsi_buf;
+ for (i=sblimit;i;i--)
+ if (*bita++)
+ *scfsi++ = (char) getbits_fast(&bsi,2);
+ }
+
+ bita = bit_alloc;
+ scfsi=scfsi_buf;
+ for (i=sblimit2;i;i--)
+ if (*bita++)
+ switch (*scfsi++)
+ {
+ case 0:
+ *scale++ = getbits_fast(&bsi,6);
+ *scale++ = getbits_fast(&bsi,6);
+ *scale++ = getbits_fast(&bsi,6);
+ break;
+ case 1 :
+ *scale++ = sc = getbits_fast(&bsi,6);
+ *scale++ = sc;
+ *scale++ = getbits_fast(&bsi,6);
+ break;
+ case 2:
+ *scale++ = sc = getbits_fast(&bsi,6);
+ *scale++ = sc;
+ *scale++ = sc;
+ break;
+ default: /* case 3 */
+ *scale++ = getbits_fast(&bsi,6);
+ *scale++ = sc = getbits_fast(&bsi,6);
+ *scale++ = sc;
+ break;
+ }
+
+}
+
+void II_step_two(unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int *scale,struct frame *fr,int x1)
+{
+ int i,j,k,ba;
+ int stereo = fr->stereo;
+ int sblimit = fr->II_sblimit;
+ int jsbound = fr->jsbound;
+ struct al_table *alloc2,*alloc1 = fr->alloc;
+ unsigned int *bita=bit_alloc;
+ int d1,step;
+
+ for (i=0;i<jsbound;i++,alloc1+=(1<<step))
+ {
+ step = alloc1->bits;
+ for (j=0;j<stereo;j++)
+ {
+ if ( (ba=*bita++) )
+ {
+ k=(alloc2 = alloc1+ba)->bits;
+ if( (d1=alloc2->d) < 0)
+ {
+ real cm=muls[k][scale[x1]];
+ fraction[j][0][i] = ((real) ((int)getbits(&bsi,k) + d1)) * cm;
+ fraction[j][1][i] = ((real) ((int)getbits(&bsi,k) + d1)) * cm;
+ fraction[j][2][i] = ((real) ((int)getbits(&bsi,k) + d1)) * cm;
+ }
+ else
+ {
+ static int *table[] = { 0,0,0,grp_3tab,0,grp_5tab,0,0,0,grp_9tab };
+ unsigned int idx,*tab,m=scale[x1];
+ idx = (unsigned int) getbits(&bsi,k);
+ tab = (unsigned int *) (table[d1] + idx + idx + idx);
+ fraction[j][0][i] = muls[*tab++][m];
+ fraction[j][1][i] = muls[*tab++][m];
+ fraction[j][2][i] = muls[*tab][m];
+ }
+ scale+=3;
+ }
+ else
+ fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0;
+ }
+ }
+
+ for (i=jsbound;i<sblimit;i++,alloc1+=(1<<step))
+ {
+ step = alloc1->bits;
+ bita++; /* channel 1 and channel 2 bitalloc are the same */
+ if ( (ba=*bita++) )
+ {
+ k=(alloc2 = alloc1+ba)->bits;
+ if( (d1=alloc2->d) < 0)
+ {
+ real cm;
+ cm=muls[k][scale[x1+3]];
+ fraction[1][0][i] = (fraction[0][0][i] = (real) ((int)getbits(&bsi,k) + d1) ) * cm;
+ fraction[1][1][i] = (fraction[0][1][i] = (real) ((int)getbits(&bsi,k) + d1) ) * cm;
+ fraction[1][2][i] = (fraction[0][2][i] = (real) ((int)getbits(&bsi,k) + d1) ) * cm;
+ cm=muls[k][scale[x1]];
+ fraction[0][0][i] *= cm; fraction[0][1][i] *= cm; fraction[0][2][i] *= cm;
+ }
+ else
+ {
+ static int *table[] = { 0,0,0,grp_3tab,0,grp_5tab,0,0,0,grp_9tab };
+ unsigned int idx,*tab,m1,m2;
+ m1 = scale[x1]; m2 = scale[x1+3];
+ idx = (unsigned int) getbits(&bsi,k);
+ tab = (unsigned int *) (table[d1] + idx + idx + idx);
+ fraction[0][0][i] = muls[*tab][m1]; fraction[1][0][i] = muls[*tab++][m2];
+ fraction[0][1][i] = muls[*tab][m1]; fraction[1][1][i] = muls[*tab++][m2];
+ fraction[0][2][i] = muls[*tab][m1]; fraction[1][2][i] = muls[*tab][m2];
+ }
+ scale+=6;
+ }
+ else {
+ fraction[0][0][i] = fraction[0][1][i] = fraction[0][2][i] =
+ fraction[1][0][i] = fraction[1][1][i] = fraction[1][2][i] = 0.0;
+ }
+/*
+ should we use individual scalefac for channel 2 or
+ is the current way the right one , where we just copy channel 1 to
+ channel 2 ??
+ The current 'strange' thing is, that we throw away the scalefac
+ values for the second channel ...!!
+-> changed .. now we use the scalefac values of channel one !!
+*/
+ }
+
+ if(sblimit > (fr->down_sample_sblimit) )
+ sblimit = fr->down_sample_sblimit;
+
+ for(i=sblimit;i<SBLIMIT;i++)
+ for (j=0;j<stereo;j++)
+ fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0;
+
+}
+
+static void II_select_table(struct frame *fr)
+{
+ static int translate[3][2][16] =
+ { { { 0,2,2,2,2,2,2,0,0,0,1,1,1,1,1,0 } ,
+ { 0,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0 } } ,
+ { { 0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0 } ,
+ { 0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0 } } ,
+ { { 0,3,3,3,3,3,3,0,0,0,1,1,1,1,1,0 } ,
+ { 0,3,3,0,0,0,1,1,1,1,1,1,1,1,1,0 } } };
+
+ int table,sblim;
+ static struct al_table *tables[5] =
+ { alloc_0, alloc_1, alloc_2, alloc_3 , alloc_4 };
+ static int sblims[5] = { 27 , 30 , 8, 12 , 30 };
+
+ if(fr->lsf)
+ table = 4;
+ else
+ table = translate[fr->sampling_frequency][2-fr->stereo][fr->bitrate_index];
+ sblim = sblims[table];
+
+ fr->alloc = tables[table];
+ fr->II_sblimit = sblim;
+}
+
+
+int do_layer2(struct mpstr *mp,struct frame *fr,int outmode,struct audio_info_struct *ai)
+{
+ int clip=0;
+ int i,j;
+ int stereo = fr->stereo;
+ real fraction[2][4][SBLIMIT]; /* pick_table clears unused subbands */
+ unsigned int bit_alloc[64];
+ int scale[192];
+ int single = fr->single;
+
+ II_select_table(fr);
+ fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ?
+ (fr->mode_ext<<2)+4 : fr->II_sblimit;
+
+ if(stereo == 1 || single == 3)
+ single = 0;
+
+ II_step_one(bit_alloc, scale, fr);
+
+ for (i=0;i<SCALE_BLOCK;i++)
+ {
+ II_step_two(bit_alloc,fraction,scale,fr,i>>2);
+ for (j=0;j<3;j++)
+ {
+ if(single >= 0)
+ {
+ clip += (fr->synth_mono) (fraction[single][j],pcm_sample,&pcm_point);
+ }
+ else {
+ int p1 = pcm_point;
+ clip += (fr->synth) (fraction[0][j],0,pcm_sample,&p1);
+ clip += (fr->synth) (fraction[1][j],1,pcm_sample,&pcm_point);
+ }
+
+ if(pcm_point >= audiobufsize)
+ audio_flush(outmode,ai);
+ }
+ }
+
+ return clip;
+}
+
+
diff --git a/mpg123_artsplugin/mpg123/layer3.c b/mpg123_artsplugin/mpg123/layer3.c
new file mode 100644
index 00000000..b4f33510
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/layer3.c
@@ -0,0 +1,1880 @@
+/*
+ * Mpeg Layer-3 audio decoder
+ * --------------------------
+ * copyright (c) 1995-1999 by Michael Hipp.
+ * All rights reserved. See also 'README'
+ *
+ * Optimize-TODO: put short bands into the band-field without the stride
+ * of 3 reals
+ * Length-optimze: unify long and short band code where it is possible
+ */
+
+#if 0
+#define L3_DEBUG 1
+#endif
+
+#if 0
+#define CUT_HF
+#endif
+
+#include <stdlib.h>
+#include "mpg123.h"
+#include "huffman.h"
+
+#include "common.h"
+
+#include "getbits.h"
+
+static real ispow[8207];
+static real aa_ca[8],aa_cs[8];
+static real COS1[12][6];
+static real win[4][36];
+static real win1[4][36];
+static real gainpow2[256+118+4];
+
+/* non static for external 3dnow functions */
+real COS9[9];
+static real COS6_1,COS6_2;
+real tfcos36[9];
+
+static real tfcos12[3];
+#define NEW_DCT9
+#ifdef NEW_DCT9
+static real cos9[3],cos18[3];
+#endif
+
+struct bandInfoStruct {
+ int longIdx[23];
+ int longDiff[22];
+ int shortIdx[14];
+ int shortDiff[13];
+};
+
+int longLimit[9][23];
+int shortLimit[9][14];
+
+struct bandInfoStruct bandInfo[9] = {
+
+/* MPEG 1.0 */
+ { {0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576},
+ {4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158},
+ {0,4*3,8*3,12*3,16*3,22*3,30*3,40*3,52*3,66*3, 84*3,106*3,136*3,192*3},
+ {4,4,4,4,6,8,10,12,14,18,22,30,56} } ,
+
+ { {0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576},
+ {4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192},
+ {0,4*3,8*3,12*3,16*3,22*3,28*3,38*3,50*3,64*3, 80*3,100*3,126*3,192*3},
+ {4,4,4,4,6,6,10,12,14,16,20,26,66} } ,
+
+ { {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} ,
+ {4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} ,
+ {0,4*3,8*3,12*3,16*3,22*3,30*3,42*3,58*3,78*3,104*3,138*3,180*3,192*3} ,
+ {4,4,4,4,6,8,12,16,20,26,34,42,12} } ,
+
+/* MPEG 2.0 */
+ { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
+ {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,
+ {0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} ,
+ {4,4,4,6,6,8,10,14,18,26,32,42,18 } } ,
+/*
+ { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576},
+ {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,52,64,70,76,36 } ,
+*/
+/* changed 19th value fropm 330 to 332 */
+ { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,332,394,464,540,576},
+ {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36 } ,
+ {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,136*3,180*3,192*3} ,
+ {4,4,4,6,8,10,12,14,18,24,32,44,12 } } ,
+
+ { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
+ {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 },
+ {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,134*3,174*3,192*3},
+ {4,4,4,6,8,10,12,14,18,24,30,40,18 } } ,
+/* MPEG 2.5 */
+ { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} ,
+ {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54},
+ {0,12,24,36,54,78,108,144,186,240,312,402,522,576},
+ {4,4,4,6,8,10,12,14,18,24,30,40,18} },
+ { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} ,
+ {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54},
+ {0,12,24,36,54,78,108,144,186,240,312,402,522,576},
+ {4,4,4,6,8,10,12,14,18,24,30,40,18} },
+ { {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576},
+ {12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2},
+ {0, 24, 48, 72,108,156,216,288,372,480,486,492,498,576},
+ {8,8,8,12,16,20,24,28,36,2,2,2,26} } ,
+};
+
+static int mapbuf0[9][152];
+static int mapbuf1[9][156];
+static int mapbuf2[9][44];
+static int *map[9][3];
+static int *mapend[9][3];
+
+static unsigned int n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */
+static unsigned int i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */
+
+static real tan1_1[16],tan2_1[16],tan1_2[16],tan2_2[16];
+static real pow1_1[2][16],pow2_1[2][16],pow1_2[2][16],pow2_2[2][16];
+
+/*
+ * init tables for layer-3
+ */
+void init_layer3(int down_sample_sblimit)
+{
+ int i,j,k,l;
+
+#ifdef REAL_IS_FIXED
+ double tmparray[8207];
+ double twotothequarter = pow((double)2.0, (double)0.25);
+ double current = pow((double)2.0, (double)(0.25 * 47));
+#endif
+
+ for(i=-256;i<118+4;i++) {
+#ifdef REAL_IS_FIXED
+ /* Possibly a few too many multiplies - single bit errors will
+ * propagate. It may change the gradient of the (log) power curve
+ * slighty */
+ current = current / twotothequarter;
+ gainpow2[i+256] = DOUBLE_TO_REAL(current);
+#else
+# ifdef USE_MMX
+ if(!param.down_sample)
+ gainpow2[i+256] = 16384.0 * pow((double)2.0,-0.25 * (double) (i+210) );
+ else
+# endif
+ gainpow2[i+256] = DOUBLE_TO_REAL(pow((double)2.0,-0.25 * (double) (i+210) ));
+#endif
+ }
+
+#ifdef REAL_IS_FIXED
+ for(i=0;i<8207;i++)
+ tmparray[i] = 0.0;
+ tmparray[1] = 1.0;
+ for(i=2;i<8207;i++) {
+ if(!tmparray[i]) {
+ tmparray[i] = pow((double)i,(double)(4.0/3.0));
+ for(j = 2; (j <= i) && ((i * j) < 8207); j++) {
+ /* Degradation due to lots of multiplies: A double has
+ * 52 bits of mantissa. A long has 32 bits (on the IPaq).
+ * Hence we can create 20 bits of error without fussing.
+ * Assuming that a 1 bit error multiplies to 2 bits, then 4,
+ * then 8, and noting that 2^13 is 8196 (we go up to 8207),
+ * we may have a problem. Resolve this by limiting to 4
+ * multiplies before recalculating. */
+ for(k = i, l = 0; (k * j) <= 8207 && (l < 4); k *= j, l++) {
+ tmparray[k * j] = tmparray[k] * tmparray[j];
+ }
+ }
+ }
+ ispow[i] = DOUBLE_TO_REAL(tmparray[i]);
+ }
+#else
+ for(i=0;i<8207;i++)
+ ispow[i] = DOUBLE_TO_REAL(pow((double)i,(double)4.0/3.0));
+#endif
+
+ for (i=0;i<8;i++) {
+ static double Ci[8]={-0.6,-0.535,-0.33,-0.185,-0.095,-0.041,-0.0142,-0.0037};
+ double sq=sqrt(1.0+Ci[i]*Ci[i]);
+ aa_cs[i] = DOUBLE_TO_REAL(1.0/sq);
+ aa_ca[i] = DOUBLE_TO_REAL(Ci[i]/sq);
+ }
+
+ for(i=0;i<18;i++) {
+ win[0][i] = win[1][i] =
+ DOUBLE_TO_REAL(0.5 * sin( M_PI / 72.0 * (double) (2*(i+0) +1) ) / cos ( M_PI * (double) (2*(i+0) +19) / 72.0 ));
+ win[0][i+18] = win[3][i+18] =
+ DOUBLE_TO_REAL(0.5 * sin( M_PI / 72.0 * (double) (2*(i+18)+1) ) / cos ( M_PI * (double) (2*(i+18)+19) / 72.0 ));
+ }
+ for(i=0;i<6;i++) {
+ win[1][i+18] = DOUBLE_TO_REAL(0.5 / cos ( M_PI * (double) (2*(i+18)+19) / 72.0 ));
+ win[3][i+12] = DOUBLE_TO_REAL(0.5 / cos ( M_PI * (double) (2*(i+12)+19) / 72.0 ));
+ win[1][i+24] = DOUBLE_TO_REAL(0.5 * sin( M_PI / 24.0 * (double) (2*i+13) ) / cos ( M_PI * (double) (2*(i+24)+19) / 72.0 ));
+ win[1][i+30] = win[3][i] = DOUBLE_TO_REAL(0.0);
+ win[3][i+6 ] = DOUBLE_TO_REAL(0.5 * sin( M_PI / 24.0 * (double) (2*i+1) ) / cos ( M_PI * (double) (2*(i+6 )+19) / 72.0 ));
+ }
+
+ for(i=0;i<9;i++)
+ COS9[i] = DOUBLE_TO_REAL(cos( M_PI / 18.0 * (double) i));
+
+ for(i=0;i<9;i++)
+ tfcos36[i] = DOUBLE_TO_REAL(0.5 / cos ( M_PI * (double) (i*2+1) / 36.0 ));
+ for(i=0;i<3;i++)
+ tfcos12[i] = DOUBLE_TO_REAL(0.5 / cos ( M_PI * (double) (i*2+1) / 12.0 ));
+
+ COS6_1 = DOUBLE_TO_REAL(cos( M_PI / 6.0 * (double) 1));
+ COS6_2 = DOUBLE_TO_REAL(cos( M_PI / 6.0 * (double) 2));
+
+#ifdef NEW_DCT9
+ cos9[0] = DOUBLE_TO_REAL(cos(1.0*M_PI/9.0));
+ cos9[1] = DOUBLE_TO_REAL(cos(5.0*M_PI/9.0));
+ cos9[2] = DOUBLE_TO_REAL(cos(7.0*M_PI/9.0));
+ cos18[0] = DOUBLE_TO_REAL(cos(1.0*M_PI/18.0));
+ cos18[1] = DOUBLE_TO_REAL(cos(11.0*M_PI/18.0));
+ cos18[2] = DOUBLE_TO_REAL(cos(13.0*M_PI/18.0));
+#endif
+
+ for(i=0;i<12;i++) {
+ win[2][i] = DOUBLE_TO_REAL(0.5 * sin( M_PI / 24.0 * (double) (2*i+1) ) / cos ( M_PI * (double) (2*i+7) / 24.0 ));
+ for(j=0;j<6;j++)
+ COS1[i][j] = DOUBLE_TO_REAL(cos( M_PI / 24.0 * (double) ((2*i+7)*(2*j+1)) ));
+ }
+
+ for(j=0;j<4;j++) {
+ static int len[4] = { 36,36,12,36 };
+ for(i=0;i<len[j];i+=2)
+ win1[j][i] = + win[j][i];
+ for(i=1;i<len[j];i+=2)
+ win1[j][i] = - win[j][i];
+ }
+
+ for(i=0;i<16;i++) {
+ double t = tan( (double) i * M_PI / 12.0 );
+ tan1_1[i] = DOUBLE_TO_REAL(t / (1.0+t));
+ tan2_1[i] = DOUBLE_TO_REAL(1.0 / (1.0 + t));
+ tan1_2[i] = DOUBLE_TO_REAL(M_SQRT2 * t / (1.0+t));
+ tan2_2[i] = DOUBLE_TO_REAL(M_SQRT2 / (1.0 + t));
+
+ for(j=0;j<2;j++) {
+ double base = pow(2.0,-0.25*(j+1.0));
+ double p1=1.0,p2=1.0;
+ if(i > 0) {
+ if( i & 1 )
+ p1 = pow(base,(i+1.0)*0.5);
+ else
+ p2 = pow(base,i*0.5);
+ }
+ pow1_1[j][i] = DOUBLE_TO_REAL(p1);
+ pow2_1[j][i] = DOUBLE_TO_REAL(p2);
+ pow1_2[j][i] = DOUBLE_TO_REAL(M_SQRT2 * p1);
+ pow2_2[j][i] = DOUBLE_TO_REAL(M_SQRT2 * p2);
+ }
+ }
+
+ for(j=0;j<9;j++) {
+ struct bandInfoStruct *bi = &bandInfo[j];
+ int *mp;
+ int cb,lwin;
+ int *bdf;
+
+ mp = map[j][0] = mapbuf0[j];
+ bdf = bi->longDiff;
+ for(i=0,cb = 0; cb < 8 ; cb++,i+=*bdf++) {
+ *mp++ = (*bdf) >> 1;
+ *mp++ = i;
+ *mp++ = 3;
+ *mp++ = cb;
+ }
+ bdf = bi->shortDiff+3;
+ for(cb=3;cb<13;cb++) {
+ int l = (*bdf++) >> 1;
+ for(lwin=0;lwin<3;lwin++) {
+ *mp++ = l;
+ *mp++ = i + lwin;
+ *mp++ = lwin;
+ *mp++ = cb;
+ }
+ i += 6*l;
+ }
+ mapend[j][0] = mp;
+
+ mp = map[j][1] = mapbuf1[j];
+ bdf = bi->shortDiff+0;
+ for(i=0,cb=0;cb<13;cb++) {
+ int l = (*bdf++) >> 1;
+ for(lwin=0;lwin<3;lwin++) {
+ *mp++ = l;
+ *mp++ = i + lwin;
+ *mp++ = lwin;
+ *mp++ = cb;
+ }
+ i += 6*l;
+ }
+ mapend[j][1] = mp;
+
+ mp = map[j][2] = mapbuf2[j];
+ bdf = bi->longDiff;
+ for(cb = 0; cb < 22 ; cb++) {
+ *mp++ = (*bdf++) >> 1;
+ *mp++ = cb;
+ }
+ mapend[j][2] = mp;
+
+ }
+
+ for(j=0;j<9;j++) {
+ for(i=0;i<23;i++) {
+ longLimit[j][i] = (bandInfo[j].longIdx[i] - 1 + 8) / 18 + 1;
+ if(longLimit[j][i] > (down_sample_sblimit) )
+ longLimit[j][i] = down_sample_sblimit;
+ }
+ for(i=0;i<14;i++) {
+ shortLimit[j][i] = (bandInfo[j].shortIdx[i] - 1) / 18 + 1;
+ if(shortLimit[j][i] > (down_sample_sblimit) )
+ shortLimit[j][i] = down_sample_sblimit;
+ }
+ }
+
+ for(i=0;i<5;i++) {
+ for(j=0;j<6;j++) {
+ for(k=0;k<6;k++) {
+ int n = k + j * 6 + i * 36;
+ i_slen2[n] = i|(j<<3)|(k<<6)|(3<<12);
+ }
+ }
+ }
+ for(i=0;i<4;i++) {
+ for(j=0;j<4;j++) {
+ for(k=0;k<4;k++) {
+ int n = k + j * 4 + i * 16;
+ i_slen2[n+180] = i|(j<<3)|(k<<6)|(4<<12);
+ }
+ }
+ }
+ for(i=0;i<4;i++) {
+ for(j=0;j<3;j++) {
+ int n = j + i * 3;
+ i_slen2[n+244] = i|(j<<3) | (5<<12);
+ n_slen2[n+500] = i|(j<<3) | (2<<12) | (1<<15);
+ }
+ }
+
+ for(i=0;i<5;i++) {
+ for(j=0;j<5;j++) {
+ for(k=0;k<4;k++) {
+ for(l=0;l<4;l++) {
+ int n = l + k * 4 + j * 16 + i * 80;
+ n_slen2[n] = i|(j<<3)|(k<<6)|(l<<9)|(0<<12);
+ }
+ }
+ }
+ }
+ for(i=0;i<5;i++) {
+ for(j=0;j<5;j++) {
+ for(k=0;k<4;k++) {
+ int n = k + j * 4 + i * 20;
+ n_slen2[n+400] = i|(j<<3)|(k<<6)|(1<<12);
+ }
+ }
+ }
+}
+
+/*
+ * read additional side information (for MPEG 1 and MPEG 2)
+ */
+static int III_get_side_info(struct III_sideinfo *si,int stereo,
+ int ms_stereo,long sfreq,int single,int lsf)
+{
+ int ch, gr;
+ int powdiff = (single == 3) ? 4 : 0;
+
+ static const int tabs[2][5] = { { 2,9,5,3,4 } , { 1,8,1,2,9 } };
+ const int *tab = tabs[lsf];
+
+ si->main_data_begin = getbits(&bsi,tab[1]);
+ if (stereo == 1)
+ si->private_bits = getbits_fast(&bsi,tab[2]);
+ else
+ si->private_bits = getbits_fast(&bsi,tab[3]);
+
+ if(!lsf) {
+ for (ch=0; ch<stereo; ch++) {
+ si->ch[ch].gr[0].scfsi = -1;
+ si->ch[ch].gr[1].scfsi = getbits_fast(&bsi,4);
+ }
+ }
+
+ for (gr=0; gr<tab[0]; gr++) {
+ for (ch=0; ch<stereo; ch++) {
+ register struct gr_info_s *gr_info = &(si->ch[ch].gr[gr]);
+
+ gr_info->part2_3_length = getbits(&bsi,12);
+ gr_info->big_values = getbits(&bsi,9);
+ if(gr_info->big_values > 288) {
+ if(param.verbose)
+ fprintf(stderr,"big_values too large!\n");
+ gr_info->big_values = 288;
+ }
+ gr_info->pow2gain = gainpow2+256 - getbits_fast(&bsi,8) + powdiff;
+ if(ms_stereo)
+ gr_info->pow2gain += 2;
+ gr_info->scalefac_compress = getbits(&bsi,tab[4]);
+
+ if(get1bit(&bsi)) { /* window switch flag */
+ int i;
+#ifdef L3_DEBUG
+if(2*gr_info->big_values > bandInfo[sfreq].shortIdx[12])
+ fprintf(stderr,"L3: BigValues too large, doesn't make sense %d %d\n",2*gr_info->big_values,bandInfo[sfreq].shortIdx[12]);
+#endif
+
+ gr_info->block_type = getbits_fast(&bsi,2);
+ gr_info->mixed_block_flag = get1bit(&bsi);
+ gr_info->table_select[0] = getbits_fast(&bsi,5);
+ gr_info->table_select[1] = getbits_fast(&bsi,5);
+ /*
+ * table_select[2] not needed, because there is no region2,
+ * but to satisfy some verifications tools we set it either.
+ */
+ gr_info->table_select[2] = 0;
+ for(i=0;i<3;i++)
+ gr_info->full_gain[i] = gr_info->pow2gain + (getbits_fast(&bsi,3)<<3);
+
+ if(gr_info->block_type == 0) {
+ if(param.verbose)
+ fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n");
+ return 0;
+ }
+
+ /* region_count/start parameters are implicit in this case. */
+ if(!lsf || gr_info->block_type == 2)
+ gr_info->region1start = 36>>1;
+ else {
+/* check this again for 2.5 and sfreq=8 */
+ if(sfreq == 8)
+ gr_info->region1start = 108>>1;
+ else
+ gr_info->region1start = 54>>1;
+ }
+ gr_info->region2start = 576>>1;
+ }
+ else {
+ int i,r0c,r1c;
+#ifdef L3_DEBUG
+if(2*gr_info->big_values > bandInfo[sfreq].longIdx[21])
+ fprintf(stderr,"L3: BigValues too large, doesn't make sense %d %d\n",2*gr_info->big_values,bandInfo[sfreq].longIdx[21]);
+#endif
+ for (i=0; i<3; i++)
+ gr_info->table_select[i] = getbits_fast(&bsi,5);
+ r0c = getbits_fast(&bsi,4);
+ r1c = getbits_fast(&bsi,3);
+ gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
+ if(r0c + r1c + 2 > 22)
+ gr_info->region2start = 576>>1;
+ else
+ gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
+ gr_info->block_type = 0;
+ gr_info->mixed_block_flag = 0;
+ }
+ if(!lsf)
+ gr_info->preflag = get1bit(&bsi);
+ gr_info->scalefac_scale = get1bit(&bsi);
+ gr_info->count1table_select = get1bit(&bsi);
+ }
+ }
+
+ return !0;
+}
+
+/*
+ * read scalefactors
+ */
+static int III_get_scale_factors_1(int *scf,struct gr_info_s *gr_info)
+{
+ static const unsigned char slen[2][16] = {
+ {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4},
+ {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3}
+ };
+ int numbits;
+ int num0 = slen[0][gr_info->scalefac_compress];
+ int num1 = slen[1][gr_info->scalefac_compress];
+
+ if (gr_info->block_type == 2) {
+ int i=18;
+ numbits = (num0 + num1) * 18;
+
+ if (gr_info->mixed_block_flag) {
+ for (i=8;i;i--)
+ *scf++ = getbits_fast(&bsi,num0);
+ i = 9;
+ numbits -= num0; /* num0 * 17 + num1 * 18 */
+ }
+
+ for (;i;i--)
+ *scf++ = getbits_fast(&bsi,num0);
+ for (i = 18; i; i--)
+ *scf++ = getbits_fast(&bsi,num1);
+ *scf++ = 0; *scf++ = 0; *scf++ = 0; /* short[13][0..2] = 0 */
+ }
+ else {
+ int i;
+ int scfsi = gr_info->scfsi;
+
+ if(scfsi < 0) { /* scfsi < 0 => granule == 0 */
+ for(i=11;i;i--)
+ *scf++ = getbits_fast(&bsi,num0);
+ for(i=10;i;i--)
+ *scf++ = getbits_fast(&bsi,num1);
+ numbits = (num0 + num1) * 10 + num0;
+ *scf++ = 0;
+ }
+ else {
+ numbits = 0;
+ if(!(scfsi & 0x8)) {
+ for (i=0;i<6;i++)
+ *scf++ = getbits_fast(&bsi,num0);
+ numbits += num0 * 6;
+ }
+ else {
+ scf += 6;
+ }
+
+ if(!(scfsi & 0x4)) {
+ for (i=0;i<5;i++)
+ *scf++ = getbits_fast(&bsi,num0);
+ numbits += num0 * 5;
+ }
+ else {
+ scf += 5;
+ }
+
+ if(!(scfsi & 0x2)) {
+ for(i=0;i<5;i++)
+ *scf++ = getbits_fast(&bsi,num1);
+ numbits += num1 * 5;
+ }
+ else {
+ scf += 5;
+ }
+
+ if(!(scfsi & 0x1)) {
+ for (i=0;i<5;i++)
+ *scf++ = getbits_fast(&bsi,num1);
+ numbits += num1 * 5;
+ }
+ else {
+ scf += 5;
+ }
+ *scf++ = 0; /* no l[21] in original sources */
+ }
+ }
+ return numbits;
+}
+
+static int III_get_scale_factors_2(int *scf,struct gr_info_s *gr_info,int i_stereo)
+{
+ unsigned char *pnt;
+ int i,j,n=0,numbits=0;
+ unsigned int slen;
+
+ static unsigned char stab[3][6][4] = {
+ { { 6, 5, 5,5 } , { 6, 5, 7,3 } , { 11,10,0,0} ,
+ { 7, 7, 7,0 } , { 6, 6, 6,3 } , { 8, 8,5,0} } ,
+ { { 9, 9, 9,9 } , { 9, 9,12,6 } , { 18,18,0,0} ,
+ {12,12,12,0 } , {12, 9, 9,6 } , { 15,12,9,0} } ,
+ { { 6, 9, 9,9 } , { 6, 9,12,6 } , { 15,18,0,0} ,
+ { 6,15,12,0 } , { 6,12, 9,6 } , { 6,18,9,0} } };
+
+ if(i_stereo) /* i_stereo AND second channel -> do_layer3() checks this */
+ slen = i_slen2[gr_info->scalefac_compress>>1];
+ else
+ slen = n_slen2[gr_info->scalefac_compress];
+
+ gr_info->preflag = (slen>>15) & 0x1;
+
+ n = 0;
+ if( gr_info->block_type == 2 ) {
+ n++;
+ if(gr_info->mixed_block_flag)
+ n++;
+ }
+
+ pnt = stab[n][(slen>>12)&0x7];
+
+ for(i=0;i<4;i++) {
+ int num = slen & 0x7;
+ slen >>= 3;
+ if(num) {
+ for(j=0;j<(int)(pnt[i]);j++)
+ *scf++ = getbits_fast(&bsi,num);
+ numbits += pnt[i] * num;
+ }
+ else {
+ for(j=0;j<(int)(pnt[i]);j++)
+ *scf++ = 0;
+ }
+ }
+
+ n = (n << 1) + 1;
+ for(i=0;i<n;i++)
+ *scf++ = 0;
+
+ return numbits;
+}
+
+static int pretab1[22] = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0};
+static int pretab2[22] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+/*
+ * Dequantize samples (includes huffman decoding)
+ */
+/* 24 is enough because tab13 has max. a 19 bit huffvector */
+#define BITSHIFT ((sizeof(long)-1)*8)
+#define REFRESH_MASK \
+ while(num < BITSHIFT) { \
+ mask |= ((unsigned long)getbyte(&bsi))<<(BITSHIFT-num); \
+ num += 8; \
+ part2remain -= 8; }
+
+static int III_dequantize_sample(real xr[SBLIMIT][SSLIMIT],int *scf,
+ struct gr_info_s *gr_info,int sfreq,int part2bits)
+{
+ int shift = 1 + gr_info->scalefac_scale;
+ real *xrpnt = (real *) xr;
+ int l[3],l3;
+ int part2remain = gr_info->part2_3_length - part2bits;
+ int *me;
+
+ int num=getbitoffset(&bsi);
+ long mask;
+ /* we must split this, because for num==0 the shift is undefined if you do it in one step */
+ mask = ((unsigned long) getbits(&bsi,num))<<BITSHIFT;
+ mask <<= 8-num;
+ part2remain -= num;
+
+ {
+ int bv = gr_info->big_values;
+ int region1 = gr_info->region1start;
+ int region2 = gr_info->region2start;
+
+ l3 = ((576>>1)-bv)>>1;
+/*
+ * we may lose the 'odd' bit here !!
+ * check this later again
+ */
+ if(bv <= region1) {
+ l[0] = bv; l[1] = l[2] = 0;
+ }
+ else {
+ l[0] = region1;
+ if(bv <= region2) {
+ l[1] = bv - l[0]; l[2] = 0;
+ }
+ else {
+ l[1] = region2 - l[0]; l[2] = bv - region2;
+ }
+ }
+ }
+
+ if(gr_info->block_type == 2) {
+ /*
+ * decoding with short or mixed mode BandIndex table
+ */
+ int i,max[4];
+ int step=0,lwin=3,cb=0;
+ register real v = 0.0;
+ register int *m,mc;
+
+ if(gr_info->mixed_block_flag) {
+ max[3] = -1;
+ max[0] = max[1] = max[2] = 2;
+ m = map[sfreq][0];
+ me = mapend[sfreq][0];
+ }
+ else {
+ max[0] = max[1] = max[2] = max[3] = -1;
+ /* max[3] not really needed in this case */
+ m = map[sfreq][1];
+ me = mapend[sfreq][1];
+ }
+
+ mc = 0;
+ for(i=0;i<2;i++) {
+ int lp = l[i];
+ struct newhuff *h = ht+gr_info->table_select[i];
+ for(;lp;lp--,mc--) {
+ register int x,y;
+ if( (!mc) ) {
+ mc = *m++;
+ xrpnt = ((real *) xr) + (*m++);
+ lwin = *m++;
+ cb = *m++;
+ if(lwin == 3) {
+ v = gr_info->pow2gain[(*scf++) << shift];
+ step = 1;
+ }
+ else {
+ v = gr_info->full_gain[lwin][(*scf++) << shift];
+ step = 3;
+ }
+ }
+ {
+ register short *val = h->table;
+ REFRESH_MASK;
+ while((y=*val++)<0) {
+ if (mask < 0)
+ val -= y;
+ num--;
+ mask <<= 1;
+ }
+ x = y >> 4;
+ y &= 0xf;
+ }
+ if(x == 15 && h->linbits) {
+ max[lwin] = cb;
+ REFRESH_MASK;
+ x += ((unsigned long) mask) >> (BITSHIFT+8-h->linbits);
+ num -= h->linbits+1;
+ mask <<= h->linbits;
+ if(mask < 0)
+ *xrpnt = REAL_MUL(-ispow[x], v);
+ else
+ *xrpnt = REAL_MUL(ispow[x], v);
+ mask <<= 1;
+ }
+ else if(x) {
+ max[lwin] = cb;
+ if(mask < 0)
+ *xrpnt = REAL_MUL(-ispow[x], v);
+ else
+ *xrpnt = REAL_MUL(ispow[x], v);
+ num--;
+ mask <<= 1;
+ }
+ else
+ *xrpnt = DOUBLE_TO_REAL(0.0);
+ xrpnt += step;
+ if(y == 15 && h->linbits) {
+ max[lwin] = cb;
+ REFRESH_MASK;
+ y += ((unsigned long) mask) >> (BITSHIFT+8-h->linbits);
+ num -= h->linbits+1;
+ mask <<= h->linbits;
+ if(mask < 0)
+ *xrpnt = REAL_MUL(-ispow[y], v);
+ else
+ *xrpnt = REAL_MUL(ispow[y], v);
+ mask <<= 1;
+ }
+ else if(y) {
+ max[lwin] = cb;
+ if(mask < 0)
+ *xrpnt = REAL_MUL(-ispow[y], v);
+ else
+ *xrpnt = REAL_MUL(ispow[y], v);
+ num--;
+ mask <<= 1;
+ }
+ else
+ *xrpnt = DOUBLE_TO_REAL(0.0);
+ xrpnt += step;
+ }
+ }
+
+ for(;l3 && (part2remain+num > 0);l3--) {
+ struct newhuff *h = htc+gr_info->count1table_select;
+ register short *val = h->table,a;
+
+ REFRESH_MASK;
+ while((a=*val++)<0) {
+ if (mask < 0)
+ val -= a;
+ num--;
+ mask <<= 1;
+ }
+ if(part2remain+num <= 0) {
+ num -= part2remain+num;
+ break;
+ }
+
+ for(i=0;i<4;i++) {
+ if(!(i & 1)) {
+ if(!mc) {
+ mc = *m++;
+ xrpnt = ((real *) xr) + (*m++);
+ lwin = *m++;
+ cb = *m++;
+ if(lwin == 3) {
+ v = gr_info->pow2gain[(*scf++) << shift];
+ step = 1;
+ }
+ else {
+ v = gr_info->full_gain[lwin][(*scf++) << shift];
+ step = 3;
+ }
+ }
+ mc--;
+ }
+ if( (a & (0x8>>i)) ) {
+ max[lwin] = cb;
+ if(part2remain+num <= 0) {
+ break;
+ }
+ if(mask < 0)
+ *xrpnt = -v;
+ else
+ *xrpnt = v;
+ num--;
+ mask <<= 1;
+ }
+ else
+ *xrpnt = DOUBLE_TO_REAL(0.0);
+ xrpnt += step;
+ }
+ }
+
+ if(lwin < 3) { /* short band? */
+ while(1) {
+ for(;mc > 0;mc--) {
+ *xrpnt = DOUBLE_TO_REAL(0.0); xrpnt += 3; /* short band -> step=3 */
+ *xrpnt = DOUBLE_TO_REAL(0.0); xrpnt += 3;
+ }
+ if(m >= me)
+ break;
+ mc = *m++;
+ xrpnt = ((real *) xr) + *m++;
+ if(*m++ == 0)
+ break; /* optimize: field will be set to zero at the end of the function */
+ m++; /* cb */
+ }
+ }
+
+ gr_info->maxband[0] = max[0]+1;
+ gr_info->maxband[1] = max[1]+1;
+ gr_info->maxband[2] = max[2]+1;
+ gr_info->maxbandl = max[3]+1;
+
+ {
+ int rmax = max[0] > max[1] ? max[0] : max[1];
+ rmax = (rmax > max[2] ? rmax : max[2]) + 1;
+ gr_info->maxb = rmax ? shortLimit[sfreq][rmax] : longLimit[sfreq][max[3]+1];
+ }
+
+ }
+ else {
+ /*
+ * decoding with 'long' BandIndex table (block_type != 2)
+ */
+ int *pretab = gr_info->preflag ? pretab1 : pretab2;
+ int i,max = -1;
+ int cb = 0;
+ int *m = map[sfreq][2];
+ register real v = 0.0;
+ int mc = 0;
+
+ /*
+ * long hash table values
+ */
+ for(i=0;i<3;i++) {
+ int lp = l[i];
+ struct newhuff *h = ht+gr_info->table_select[i];
+
+ for(;lp;lp--,mc--) {
+ int x,y;
+
+ if(!mc) {
+ mc = *m++;
+ cb = *m++;
+#ifdef CUT_HF
+ if(cb == 21) {
+ fprintf(stderr,"c");
+ v = 0.0;
+ }
+ else
+#endif
+ v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift];
+
+ }
+ {
+ register short *val = h->table;
+ REFRESH_MASK;
+ while((y=*val++)<0) {
+ if (mask < 0)
+ val -= y;
+ num--;
+ mask <<= 1;
+ }
+ x = y >> 4;
+ y &= 0xf;
+ }
+
+ if (x == 15 && h->linbits) {
+ max = cb;
+ REFRESH_MASK;
+ x += ((unsigned long) mask) >> (BITSHIFT+8-h->linbits);
+ num -= h->linbits+1;
+ mask <<= h->linbits;
+ if(mask < 0)
+ *xrpnt++ = REAL_MUL(-ispow[x], v);
+ else
+ *xrpnt++ = REAL_MUL(ispow[x], v);
+ mask <<= 1;
+ }
+ else if(x) {
+ max = cb;
+ if(mask < 0)
+ *xrpnt++ = REAL_MUL(-ispow[x], v);
+ else
+ *xrpnt++ = REAL_MUL(ispow[x], v);
+ num--;
+ mask <<= 1;
+ }
+ else
+ *xrpnt++ = DOUBLE_TO_REAL(0.0);
+
+ if (y == 15 && h->linbits) {
+ max = cb;
+ REFRESH_MASK;
+ y += ((unsigned long) mask) >> (BITSHIFT+8-h->linbits);
+ num -= h->linbits+1;
+ mask <<= h->linbits;
+ if(mask < 0)
+ *xrpnt++ = REAL_MUL(-ispow[y], v);
+ else
+ *xrpnt++ = REAL_MUL(ispow[y], v);
+ mask <<= 1;
+ }
+ else if(y) {
+ max = cb;
+ if(mask < 0)
+ *xrpnt++ = REAL_MUL(-ispow[y], v);
+ else
+ *xrpnt++ = REAL_MUL(ispow[y], v);
+ num--;
+ mask <<= 1;
+ }
+ else
+ *xrpnt++ = DOUBLE_TO_REAL(0.0);
+ }
+ }
+
+ /*
+ * short (count1table) values
+ */
+ for(;l3 && (part2remain+num > 0);l3--) {
+ struct newhuff *h = htc+gr_info->count1table_select;
+ register short *val = h->table,a;
+
+ REFRESH_MASK;
+ while((a=*val++)<0) {
+ if (mask < 0)
+ val -= a;
+ num--;
+ mask <<= 1;
+ }
+ if(part2remain+num <= 0) {
+ num -= part2remain+num;
+ break;
+ }
+
+ for(i=0;i<4;i++) {
+ if(!(i & 1)) {
+ if(!mc) {
+ mc = *m++;
+ cb = *m++;
+#ifdef CUT_HF
+ if(cb == 21) {
+ fprintf(stderr,"c");
+ v = 0.0;
+ }
+ else
+#endif
+ v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift];
+ }
+ mc--;
+ }
+ if ( (a & (0x8>>i)) ) {
+ max = cb;
+ if(part2remain+num <= 0) {
+ break;
+ }
+ if(mask < 0)
+ *xrpnt++ = -v;
+ else
+ *xrpnt++ = v;
+ num--;
+ mask <<= 1;
+ }
+ else
+ *xrpnt++ = DOUBLE_TO_REAL(0.0);
+ }
+ }
+
+ gr_info->maxbandl = max+1;
+ gr_info->maxb = longLimit[sfreq][gr_info->maxbandl];
+ }
+
+ part2remain += num;
+ backbits(&bsi,num);
+ num = 0;
+
+ while(xrpnt < &xr[SBLIMIT][0])
+ *xrpnt++ = DOUBLE_TO_REAL(0.0);
+
+ while( part2remain > 16 ) {
+ getbits(&bsi,16); /* Dismiss stuffing Bits */
+ part2remain -= 16;
+ }
+ if(part2remain > 0)
+ getbits(&bsi,part2remain);
+ else if(part2remain < 0) {
+ if(param.verbose)
+ fprintf(stderr,"mpg123: Can't rewind stream by %d bits!\n",-part2remain);
+ return 1; /* -> error */
+ }
+ return 0;
+}
+
+/*
+ * III_stereo: calculate real channel values for Joint-I-Stereo-mode
+ */
+static void III_i_stereo(real xr_buf[2][SBLIMIT][SSLIMIT],int *scalefac,
+ struct gr_info_s *gr_info,int sfreq,int ms_stereo,int lsf)
+{
+ real (*xr)[SBLIMIT*SSLIMIT] = (real (*)[SBLIMIT*SSLIMIT] ) xr_buf;
+ struct bandInfoStruct *bi = &bandInfo[sfreq];
+
+ const real *tab1,*tab2;
+
+ int tab;
+ static const real *tabs[3][2][2] = {
+ { { tan1_1,tan2_1 } , { tan1_2,tan2_2 } },
+ { { pow1_1[0],pow2_1[0] } , { pow1_2[0],pow2_2[0] } } ,
+ { { pow1_1[1],pow2_1[1] } , { pow1_2[1],pow2_2[1] } }
+ };
+
+ tab = lsf + (gr_info->scalefac_compress & lsf);
+ tab1 = tabs[tab][ms_stereo][0];
+ tab2 = tabs[tab][ms_stereo][1];
+#if 0
+ if(lsf) {
+ int p = gr_info->scalefac_compress & 0x1;
+ if(ms_stereo) {
+ tab1 = pow1_2[p]; tab2 = pow2_2[p];
+ }
+ else {
+ tab1 = pow1_1[p]; tab2 = pow2_1[p];
+ }
+ }
+ else {
+ if(ms_stereo) {
+ tab1 = tan1_2; tab2 = tan2_2;
+ }
+ else {
+ tab1 = tan1_1; tab2 = tan2_1;
+ }
+ }
+#endif
+
+ if (gr_info->block_type == 2) {
+ int lwin,do_l = 0;
+ if( gr_info->mixed_block_flag )
+ do_l = 1;
+
+ for (lwin=0;lwin<3;lwin++) { /* process each window */
+ /* get first band with zero values */
+ int is_p,sb,idx,sfb = gr_info->maxband[lwin]; /* sfb is minimal 3 for mixed mode */
+ if(sfb > 3)
+ do_l = 0;
+
+ for(;sfb<12;sfb++) {
+ is_p = scalefac[sfb*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */
+ if(is_p != 7) {
+ real t1,t2;
+ sb = bi->shortDiff[sfb];
+ idx = bi->shortIdx[sfb] + lwin;
+ t1 = tab1[is_p]; t2 = tab2[is_p];
+ for (; sb > 0; sb--,idx+=3) {
+ real v = xr[0][idx];
+ xr[0][idx] = REAL_MUL(v, t1);
+ xr[1][idx] = REAL_MUL(v, t2);
+ }
+ }
+ }
+
+#if 1
+/* in the original: copy 10 to 11 , here: copy 11 to 12
+maybe still wrong??? (copy 12 to 13?) */
+ is_p = scalefac[11*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */
+ sb = bi->shortDiff[12];
+ idx = bi->shortIdx[12] + lwin;
+#else
+ is_p = scalefac[10*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */
+ sb = bi->shortDiff[11];
+ idx = bi->shortIdx[11] + lwin;
+#endif
+ if(is_p != 7) {
+ real t1,t2;
+ t1 = tab1[is_p]; t2 = tab2[is_p];
+ for ( ; sb > 0; sb--,idx+=3 ) {
+ real v = xr[0][idx];
+ xr[0][idx] = REAL_MUL(v, t1);
+ xr[1][idx] = REAL_MUL(v, t2);
+ }
+ }
+ } /* end for(lwin; .. ; . ) */
+
+/* also check l-part, if ALL bands in the three windows are 'empty'
+ * and mode = mixed_mode
+ */
+ if (do_l) {
+ int sfb = gr_info->maxbandl;
+ int idx = bi->longIdx[sfb];
+
+ for ( ; sfb<8; sfb++ ) {
+ int sb = bi->longDiff[sfb];
+ int is_p = scalefac[sfb]; /* scale: 0-15 */
+ if(is_p != 7) {
+ real t1,t2;
+ t1 = tab1[is_p]; t2 = tab2[is_p];
+ for ( ; sb > 0; sb--,idx++) {
+ real v = xr[0][idx];
+ xr[0][idx] = REAL_MUL(v, t1);
+ xr[1][idx] = REAL_MUL(v, t2);
+ }
+ }
+ else
+ idx += sb;
+ }
+ }
+ }
+ else { /* ((gr_info->block_type != 2)) */
+ int sfb = gr_info->maxbandl;
+ int is_p,idx = bi->longIdx[sfb];
+
+/* hmm ... maybe the maxbandl stuff for i-stereo is buggy? */
+ if(sfb <= 21) {
+ for ( ; sfb<21; sfb++) {
+ int sb = bi->longDiff[sfb];
+ is_p = scalefac[sfb]; /* scale: 0-15 */
+ if(is_p != 7) {
+ real t1,t2;
+ t1 = tab1[is_p]; t2 = tab2[is_p];
+ for ( ; sb > 0; sb--,idx++) {
+ real v = xr[0][idx];
+ xr[0][idx] = REAL_MUL(v, t1);
+ xr[1][idx] = REAL_MUL(v, t2);
+ }
+ }
+ else
+ idx += sb;
+ }
+
+ is_p = scalefac[20];
+ if(is_p != 7) { /* copy l-band 20 to l-band 21 */
+ int sb;
+ real t1 = tab1[is_p],t2 = tab2[is_p];
+
+ for ( sb = bi->longDiff[21]; sb > 0; sb--,idx++ ) {
+ real v = xr[0][idx];
+ xr[0][idx] = REAL_MUL(v, t1);
+ xr[1][idx] = REAL_MUL(v, t2);
+ }
+ }
+ } /* end: if(sfb <= 21) */
+ } /* ... */
+}
+
+static void III_antialias(real xr[SBLIMIT][SSLIMIT],struct gr_info_s *gr_info) {
+ int sblim;
+
+ if(gr_info->block_type == 2) {
+ if(!gr_info->mixed_block_flag)
+ return;
+ sblim = 1;
+ }
+ else {
+ sblim = gr_info->maxb-1;
+ }
+
+ /* 31 alias-reduction operations between each pair of sub-bands */
+ /* with 8 butterflies between each pair */
+
+ {
+ int sb;
+ real *xr1=(real *) xr[1];
+
+ for(sb=sblim;sb;sb--,xr1+=10) {
+ int ss;
+ real *cs=aa_cs,*ca=aa_ca;
+ real *xr2 = xr1;
+
+ for(ss=7;ss>=0;ss--)
+ { /* upper and lower butterfly inputs */
+ register real bu = *--xr2,bd = *xr1;
+ *xr2 = REAL_MUL(bu, *cs) - REAL_MUL(bd, *ca);
+ *xr1++ = REAL_MUL(bd, *cs++) + REAL_MUL(bu, *ca++);
+ }
+ }
+ }
+}
+
+/*
+ This is an optimized DCT from Jeff Tsay's maplay 1.2+ package.
+ Saved one multiplication by doing the 'twiddle factor' stuff
+ together with the window mul. (MH)
+
+ This uses Byeong Gi Lee's Fast Cosine Transform algorithm, but the
+ 9 point IDCT needs to be reduced further. Unfortunately, I don't
+ know how to do that, because 9 is not an even number. - Jeff.
+
+ ****************************************************************
+
+ 9 Point Inverse Discrete Cosine Transform
+
+ This piece of code is Copyright 1997 Mikko Tommila and is freely usable
+ by anybody. The algorithm itself is of course in the public domain.
+
+ Again derived heuristically from the 9-point WFTA.
+
+ The algorithm is optimized (?) for speed, not for small rounding errors or
+ good readability.
+
+ 36 additions, 11 multiplications
+
+ Again this is very likely sub-optimal.
+
+ The code is optimized to use a minimum number of temporary variables,
+ so it should compile quite well even on 8-register Intel x86 processors.
+ This makes the code quite obfuscated and very difficult to understand.
+
+ References:
+ [1] S. Winograd: "On Computing the Discrete Fourier Transform",
+ Mathematics of Computation, Volume 32, Number 141, January 1978,
+ Pages 175-199
+*/
+
+/*------------------------------------------------------------------*/
+/* */
+/* Function: Calculation of the inverse MDCT */
+/* */
+/*------------------------------------------------------------------*/
+
+void dct36(real *inbuf,real *o1,real *o2,real *wintab,real *tsbuf)
+{
+#ifdef NEW_DCT9
+ real tmp[18];
+#endif
+
+ {
+ register real *in = inbuf;
+
+ in[17]+=in[16]; in[16]+=in[15]; in[15]+=in[14];
+ in[14]+=in[13]; in[13]+=in[12]; in[12]+=in[11];
+ in[11]+=in[10]; in[10]+=in[9]; in[9] +=in[8];
+ in[8] +=in[7]; in[7] +=in[6]; in[6] +=in[5];
+ in[5] +=in[4]; in[4] +=in[3]; in[3] +=in[2];
+ in[2] +=in[1]; in[1] +=in[0];
+
+ in[17]+=in[15]; in[15]+=in[13]; in[13]+=in[11]; in[11]+=in[9];
+ in[9] +=in[7]; in[7] +=in[5]; in[5] +=in[3]; in[3] +=in[1];
+
+
+#ifdef NEW_DCT9
+#if 1
+ {
+ real t3;
+ {
+ real t0, t1, t2;
+
+ t0 = REAL_MUL(COS6_2, (in[8] + in[16] - in[4]));
+ t1 = REAL_MUL(COS6_2, in[12]);
+
+ t3 = in[0];
+ t2 = t3 - t1 - t1;
+ tmp[1] = tmp[7] = t2 - t0;
+ tmp[4] = t2 + t0 + t0;
+ t3 += t1;
+
+ t2 = REAL_MUL(COS6_1, (in[10] + in[14] - in[2]));
+ tmp[1] -= t2;
+ tmp[7] += t2;
+ }
+ {
+ real t0, t1, t2;
+
+ t0 = REAL_MUL(cos9[0], (in[4] + in[8] ));
+ t1 = REAL_MUL(cos9[1], (in[8] - in[16]));
+ t2 = REAL_MUL(cos9[2], (in[4] + in[16]));
+
+ tmp[2] = tmp[6] = t3 - t0 - t2;
+ tmp[0] = tmp[8] = t3 + t0 + t1;
+ tmp[3] = tmp[5] = t3 - t1 + t2;
+ }
+ }
+ {
+ real t1, t2, t3;
+
+ t1 = REAL_MUL(cos18[0], (in[2] + in[10]));
+ t2 = REAL_MUL(cos18[1], (in[10] - in[14]));
+ t3 = REAL_MUL(COS6_1, in[6]);
+
+ {
+ real t0 = t1 + t2 + t3;
+ tmp[0] += t0;
+ tmp[8] -= t0;
+ }
+
+ t2 -= t3;
+ t1 -= t3;
+
+ t3 = REAL_MUL(cos18[2], (in[2] + in[14]));
+
+ t1 += t3;
+ tmp[3] += t1;
+ tmp[5] -= t1;
+
+ t2 -= t3;
+ tmp[2] += t2;
+ tmp[6] -= t2;
+ }
+
+#else
+ {
+ real t0, t1, t2, t3, t4, t5, t6, t7;
+
+ t1 = REAL_MUL(COS6_2, in[12]);
+ t2 = REAL_MUL(COS6_2, (in[8] + in[16] - in[4]));
+
+ t3 = in[0] + t1;
+ t4 = in[0] - t1 - t1;
+ t5 = t4 - t2;
+ tmp[4] = t4 + t2 + t2;
+
+ t0 = REAL_MUL(cos9[0], (in[4] + in[8]));
+ t1 = REAL_MUL(cos9[1], (in[8] - in[16]));
+
+ t2 = REAL_MUL(cos9[2], (in[4] + in[16]));
+
+ t6 = t3 - t0 - t2;
+ t0 += t3 + t1;
+ t3 += t2 - t1;
+
+ t2 = REAL_MUL(cos18[0], (in[2] + in[10]));
+ t4 = REAL_MUL(cos18[1], (in[10] - in[14]));
+ t7 = REAL_MUL(COS6_1, in[6]);
+
+ t1 = t2 + t4 + t7;
+ tmp[0] = t0 + t1;
+ tmp[8] = t0 - t1;
+ t1 = REAL_MUL(cos18[2], (in[2] + in[14]));
+ t2 += t1 - t7;
+
+ tmp[3] = t3 + t2;
+ t0 = REAL_MUL(COS6_1, (in[10] + in[14] - in[2]));
+ tmp[5] = t3 - t2;
+
+ t4 -= t1 + t7;
+
+ tmp[1] = t5 - t0;
+ tmp[7] = t5 + t0;
+ tmp[2] = t6 + t4;
+ tmp[6] = t6 - t4;
+ }
+#endif
+
+ {
+ real t0, t1, t2, t3, t4, t5, t6, t7;
+
+ t1 = REAL_MUL(COS6_2, in[13]);
+ t2 = REAL_MUL(COS6_2, (in[9] + in[17] - in[5]));
+
+ t3 = in[1] + t1;
+ t4 = in[1] - t1 - t1;
+ t5 = t4 - t2;
+
+ t0 = REAL_MUL(cos9[0], (in[5] + in[9]));
+ t1 = REAL_MUL(cos9[1], (in[9] - in[17]));
+
+ tmp[13] = REAL_MUL((t4 + t2 + t2), tfcos36[17-13]);
+ t2 = REAL_MUL(cos9[2], (in[5] + in[17]));
+
+ t6 = t3 - t0 - t2;
+ t0 += t3 + t1;
+ t3 += t2 - t1;
+
+ t2 = REAL_MUL(cos18[0], (in[3] + in[11]));
+ t4 = REAL_MUL(cos18[1], (in[11] - in[15]));
+ t7 = REAL_MUL(COS6_1, in[7]);
+
+ t1 = t2 + t4 + t7;
+ tmp[17] = REAL_MUL((t0 + t1), tfcos36[17-17]);
+ tmp[9] = REAL_MUL((t0 - t1), tfcos36[17-9]);
+ t1 = REAL_MUL(cos18[2], (in[3] + in[15]));
+ t2 += t1 - t7;
+
+ tmp[14] = REAL_MUL((t3 + t2), tfcos36[17-14]);
+ t0 = REAL_MUL(COS6_1, (in[11] + in[15] - in[3]));
+ tmp[12] = REAL_MUL((t3 - t2), tfcos36[17-12]);
+
+ t4 -= t1 + t7;
+
+ tmp[16] = REAL_MUL((t5 - t0), tfcos36[17-16]);
+ tmp[10] = REAL_MUL((t5 + t0), tfcos36[17-10]);
+ tmp[15] = REAL_MUL((t6 + t4), tfcos36[17-15]);
+ tmp[11] = REAL_MUL((t6 - t4), tfcos36[17-11]);
+ }
+
+#define MACRO(v) { \
+ real tmpval; \
+ tmpval = tmp[(v)] + tmp[17-(v)]; \
+ out2[9+(v)] = REAL_MUL(tmpval, w[27+(v)]); \
+ out2[8-(v)] = REAL_MUL(tmpval, w[26-(v)]); \
+ tmpval = tmp[(v)] - tmp[17-(v)]; \
+ ts[SBLIMIT*(8-(v))] = out1[8-(v)] + REAL_MUL(tmpval, w[8-(v)]); \
+ ts[SBLIMIT*(9+(v))] = out1[9+(v)] + REAL_MUL(tmpval, w[9+(v)]); }
+
+{
+ register real *out2 = o2;
+ register real *w = wintab;
+ register real *out1 = o1;
+ register real *ts = tsbuf;
+
+ MACRO(0);
+ MACRO(1);
+ MACRO(2);
+ MACRO(3);
+ MACRO(4);
+ MACRO(5);
+ MACRO(6);
+ MACRO(7);
+ MACRO(8);
+}
+
+#else
+
+ {
+
+#define MACRO0(v) { \
+ real tmp; \
+ out2[9+(v)] = REAL_MUL((tmp = sum0 + sum1), w[27+(v)]); \
+ out2[8-(v)] = REAL_MUL(tmp, w[26-(v)]); } \
+ sum0 -= sum1; \
+ ts[SBLIMIT*(8-(v))] = out1[8-(v)] + REAL_MUL(sum0, w[8-(v)]); \
+ ts[SBLIMIT*(9+(v))] = out1[9+(v)] + REAL_MUL(sum0, w[9+(v)]);
+#define MACRO1(v) { \
+ real sum0,sum1; \
+ sum0 = tmp1a + tmp2a; \
+ sum1 = REAL_MUL((tmp1b + tmp2b), tfcos36[(v)]); \
+ MACRO0(v); }
+#define MACRO2(v) { \
+ real sum0,sum1; \
+ sum0 = tmp2a - tmp1a; \
+ sum1 = REAL_MUL((tmp2b - tmp1b), tfcos36[(v)]); \
+ MACRO0(v); }
+
+ register const real *c = COS9;
+ register real *out2 = o2;
+ register real *w = wintab;
+ register real *out1 = o1;
+ register real *ts = tsbuf;
+
+ real ta33,ta66,tb33,tb66;
+
+ ta33 = REAL_MUL(in[2*3+0], c[3]);
+ ta66 = REAL_MUL(in[2*6+0], c[6]);
+ tb33 = REAL_MUL(in[2*3+1], c[3]);
+ tb66 = REAL_MUL(in[2*6+1], c[6]);
+
+ {
+ real tmp1a,tmp2a,tmp1b,tmp2b;
+ tmp1a = REAL_MUL(in[2*1+0], c[1]) + ta33 + REAL_MUL(in[2*5+0], c[5]) + REAL_MUL(in[2*7+0], c[7]);
+ tmp1b = REAL_MUL(in[2*1+1], c[1]) + tb33 + REAL_MUL(in[2*5+1], c[5]) + REAL_MUL(in[2*7+1], c[7]);
+ tmp2a = REAL_MUL(in[2*2+0], c[2]) + REAL_MUL(in[2*4+0], c[4]) + ta66 + REAL_MUL(in[2*8+0], c[8]);
+ tmp2b = REAL_MUL(in[2*2+1], c[2]) + REAL_MUL(in[2*4+1], c[4]) + tb66 + REAL_MUL(in[2*8+1], c[8]);
+
+ MACRO1(0);
+ MACRO2(8);
+ }
+
+ {
+ real tmp1a,tmp2a,tmp1b,tmp2b;
+ tmp1a = REAL_MUL(( in[2*1+0] - in[2*5+0] - in[2*7+0] ), c[3]);
+ tmp1b = REAL_MUL(( in[2*1+1] - in[2*5+1] - in[2*7+1] ), c[3]);
+ tmp2a = REAL_MUL(( in[2*2+0] - in[2*4+0] - in[2*8+0] ), c[6]) - in[2*6+0] + in[2*0+0];
+ tmp2b = REAL_MUL(( in[2*2+1] - in[2*4+1] - in[2*8+1] ), c[6]) - in[2*6+1] + in[2*0+1];
+
+ MACRO1(1);
+ MACRO2(7);
+ }
+
+ {
+ real tmp1a,tmp2a,tmp1b,tmp2b;
+ tmp1a = REAL_MUL(in[2*1+0], c[5]) - ta33 - REAL_MUL(in[2*5+0], c[7]) + REAL_MUL(in[2*7+0], c[1]);
+ tmp1b = REAL_MUL(in[2*1+1], c[5]) - tb33 - REAL_MUL(in[2*5+1], c[7]) + REAL_MUL(in[2*7+1], c[1]);
+ tmp2a = - REAL_MUL(in[2*2+0], c[8]) - REAL_MUL(in[2*4+0], c[2]) + ta66 + REAL_MUL(in[2*8+0], c[4]);
+ tmp2b = - REAL_MUL(in[2*2+1], c[8]) - REAL_MUL(in[2*4+1], c[2]) + tb66 + REAL_MUL(in[2*8+1], c[4]);
+
+ MACRO1(2);
+ MACRO2(6);
+ }
+
+ {
+ real tmp1a,tmp2a,tmp1b,tmp2b;
+ tmp1a = REAL_MUL(in[2*1+0], c[7]) - ta33 + REAL_MUL(in[2*5+0], c[1]) - REAL_MUL(in[2*7+0], c[5]);
+ tmp1b = REAL_MUL(in[2*1+1], c[7]) - tb33 + REAL_MUL(in[2*5+1], c[1]) - REAL_MUL(in[2*7+1], c[5]);
+ tmp2a = - REAL_MUL(in[2*2+0], c[4]) + REAL_MUL(in[2*4+0], c[8]) + ta66 - REAL_MUL(in[2*8+0], c[2]);
+ tmp2b = - REAL_MUL(in[2*2+1], c[4]) + REAL_MUL(in[2*4+1], c[8]) + tb66 - REAL_MUL(in[2*8+1], c[2]);
+
+ MACRO1(3);
+ MACRO2(5);
+ }
+
+ {
+ real sum0,sum1;
+ sum0 = in[2*0+0] - in[2*2+0] + in[2*4+0] - in[2*6+0] + in[2*8+0];
+ sum1 = REAL_MUL((in[2*0+1] - in[2*2+1] + in[2*4+1] - in[2*6+1] + in[2*8+1] ), tfcos36[4]);
+ MACRO0(4);
+ }
+ }
+#endif
+
+ }
+}
+
+/*
+ * new DCT12
+ */
+static void dct12(real *in,real *rawout1,real *rawout2,register real *wi,register real *ts)
+{
+#define DCT12_PART1 \
+ in5 = in[5*3]; \
+ in5 += (in4 = in[4*3]); \
+ in4 += (in3 = in[3*3]); \
+ in3 += (in2 = in[2*3]); \
+ in2 += (in1 = in[1*3]); \
+ in1 += (in0 = in[0*3]); \
+ \
+ in5 += in3; in3 += in1; \
+ \
+ in2 = REAL_MUL(in2, COS6_1); \
+ in3 = REAL_MUL(in3, COS6_1); \
+
+#define DCT12_PART2 \
+ in0 += REAL_MUL(in4, COS6_2); \
+ \
+ in4 = in0 + in2; \
+ in0 -= in2; \
+ \
+ in1 += REAL_MUL(in5, COS6_2); \
+ \
+ in5 = REAL_MUL((in1 + in3), tfcos12[0]); \
+ in1 = REAL_MUL((in1 - in3), tfcos12[2]); \
+ \
+ in3 = in4 + in5; \
+ in4 -= in5; \
+ \
+ in2 = in0 + in1; \
+ in0 -= in1;
+
+
+ {
+ real in0,in1,in2,in3,in4,in5;
+ register real *out1 = rawout1;
+ ts[SBLIMIT*0] = out1[0]; ts[SBLIMIT*1] = out1[1]; ts[SBLIMIT*2] = out1[2];
+ ts[SBLIMIT*3] = out1[3]; ts[SBLIMIT*4] = out1[4]; ts[SBLIMIT*5] = out1[5];
+
+ DCT12_PART1
+
+ {
+ real tmp0,tmp1 = (in0 - in4);
+ {
+ real tmp2 = REAL_MUL((in1 - in5), tfcos12[1]);
+ tmp0 = tmp1 + tmp2;
+ tmp1 -= tmp2;
+ }
+ ts[(17-1)*SBLIMIT] = out1[17-1] + REAL_MUL(tmp0, wi[11-1]);
+ ts[(12+1)*SBLIMIT] = out1[12+1] + REAL_MUL(tmp0, wi[6+1]);
+ ts[(6 +1)*SBLIMIT] = out1[6 +1] + REAL_MUL(tmp1, wi[1]);
+ ts[(11-1)*SBLIMIT] = out1[11-1] + REAL_MUL(tmp1, wi[5-1]);
+ }
+
+ DCT12_PART2
+
+ ts[(17-0)*SBLIMIT] = out1[17-0] + REAL_MUL(in2, wi[11-0]);
+ ts[(12+0)*SBLIMIT] = out1[12+0] + REAL_MUL(in2, wi[6+0]);
+ ts[(12+2)*SBLIMIT] = out1[12+2] + REAL_MUL(in3, wi[6+2]);
+ ts[(17-2)*SBLIMIT] = out1[17-2] + REAL_MUL(in3, wi[11-2]);
+
+ ts[(6 +0)*SBLIMIT] = out1[6+0] + REAL_MUL(in0, wi[0]);
+ ts[(11-0)*SBLIMIT] = out1[11-0] + REAL_MUL(in0, wi[5-0]);
+ ts[(6 +2)*SBLIMIT] = out1[6+2] + REAL_MUL(in4, wi[2]);
+ ts[(11-2)*SBLIMIT] = out1[11-2] + REAL_MUL(in4, wi[5-2]);
+ }
+
+ in++;
+
+ {
+ real in0,in1,in2,in3,in4,in5;
+ register real *out2 = rawout2;
+
+ DCT12_PART1
+
+ {
+ real tmp0,tmp1 = (in0 - in4);
+ {
+ real tmp2 = REAL_MUL((in1 - in5), tfcos12[1]);
+ tmp0 = tmp1 + tmp2;
+ tmp1 -= tmp2;
+ }
+ out2[5-1] = REAL_MUL(tmp0, wi[11-1]);
+ out2[0+1] = REAL_MUL(tmp0, wi[6+1]);
+ ts[(12+1)*SBLIMIT] += REAL_MUL(tmp1, wi[1]);
+ ts[(17-1)*SBLIMIT] += REAL_MUL(tmp1, wi[5-1]);
+ }
+
+ DCT12_PART2
+
+ out2[5-0] = REAL_MUL(in2, wi[11-0]);
+ out2[0+0] = REAL_MUL(in2, wi[6+0]);
+ out2[0+2] = REAL_MUL(in3, wi[6+2]);
+ out2[5-2] = REAL_MUL(in3, wi[11-2]);
+
+ ts[(12+0)*SBLIMIT] += REAL_MUL(in0, wi[0]);
+ ts[(17-0)*SBLIMIT] += REAL_MUL(in0, wi[5-0]);
+ ts[(12+2)*SBLIMIT] += REAL_MUL(in4, wi[2]);
+ ts[(17-2)*SBLIMIT] += REAL_MUL(in4, wi[5-2]);
+ }
+
+ in++;
+
+ {
+ real in0,in1,in2,in3,in4,in5;
+ register real *out2 = rawout2;
+ out2[12]=out2[13]=out2[14]=out2[15]=out2[16]=out2[17]=0.0;
+
+ DCT12_PART1
+
+ {
+ real tmp0,tmp1 = (in0 - in4);
+ {
+ real tmp2 = REAL_MUL((in1 - in5), tfcos12[1]);
+ tmp0 = tmp1 + tmp2;
+ tmp1 -= tmp2;
+ }
+ out2[11-1] = REAL_MUL(tmp0, wi[11-1]);
+ out2[6 +1] = REAL_MUL(tmp0, wi[6+1]);
+ out2[0+1] += REAL_MUL(tmp1, wi[1]);
+ out2[5-1] += REAL_MUL(tmp1, wi[5-1]);
+ }
+
+ DCT12_PART2
+
+ out2[11-0] = REAL_MUL(in2, wi[11-0]);
+ out2[6 +0] = REAL_MUL(in2, wi[6+0]);
+ out2[6 +2] = REAL_MUL(in3, wi[6+2]);
+ out2[11-2] = REAL_MUL(in3, wi[11-2]);
+
+ out2[0+0] += REAL_MUL(in0, wi[0]);
+ out2[5-0] += REAL_MUL(in0, wi[5-0]);
+ out2[0+2] += REAL_MUL(in4, wi[2]);
+ out2[5-2] += REAL_MUL(in4, wi[5-2]);
+ }
+}
+
+/*
+ * III_hybrid
+ */
+static void III_hybrid(struct mpstr *mp,real fsIn[SBLIMIT][SSLIMIT],real tsOut[SSLIMIT][SBLIMIT],
+ int ch,struct gr_info_s *gr_info,struct frame *fr)
+{
+/*
+ static real block[2][2][SBLIMIT*SSLIMIT] = { { { 0, } } };
+ static int blc[2]={0,0};
+ */
+
+ real *tspnt = (real *) tsOut;
+ real *rawout1,*rawout2;
+ int bt,sb = 0;
+
+ {
+ int b = mp->hybrid_blc[ch];
+ rawout1=mp->hybrid_block[b][ch];
+ b=-b+1;
+ rawout2=mp->hybrid_block[b][ch];
+ mp->hybrid_blc[ch] = b;
+ }
+
+ if(gr_info->mixed_block_flag) {
+ sb = 2;
+#ifdef USE_3DNOW
+ (fr->dct36)(fsIn[0],rawout1,rawout2,win[0],tspnt);
+ (fr->dct36)(fsIn[1],rawout1+18,rawout2+18,win1[0],tspnt+1);
+#else
+ dct36(fsIn[0],rawout1,rawout2,win[0],tspnt);
+ dct36(fsIn[1],rawout1+18,rawout2+18,win1[0],tspnt+1);
+#endif
+ rawout1 += 36; rawout2 += 36; tspnt += 2;
+ }
+
+ bt = gr_info->block_type;
+ if(bt == 2) {
+ for (; sb<gr_info->maxb; sb+=2,tspnt+=2,rawout1+=36,rawout2+=36) {
+ dct12(fsIn[sb] ,rawout1 ,rawout2 ,win[2] ,tspnt);
+ dct12(fsIn[sb+1],rawout1+18,rawout2+18,win1[2],tspnt+1);
+ }
+ }
+ else {
+ for (; sb<gr_info->maxb; sb+=2,tspnt+=2,rawout1+=36,rawout2+=36) {
+#ifdef USE_3DNOW
+ (fr->dct36)(fsIn[sb],rawout1,rawout2,win[bt],tspnt);
+ (fr->dct36)(fsIn[sb+1],rawout1+18,rawout2+18,win1[bt],tspnt+1);
+#else
+ dct36(fsIn[sb],rawout1,rawout2,win[bt],tspnt);
+ dct36(fsIn[sb+1],rawout1+18,rawout2+18,win1[bt],tspnt+1);
+#endif
+ }
+ }
+
+ for(;sb<SBLIMIT;sb++,tspnt++) {
+ int i;
+ for(i=0;i<SSLIMIT;i++) {
+ tspnt[i*SBLIMIT] = *rawout1++;
+ *rawout2++ = DOUBLE_TO_REAL(0.0);
+ }
+ }
+}
+
+
+
+/*
+ * main layer3 handler
+ */
+int do_layer3(struct mpstr *mp,struct frame *fr,int outmode,struct audio_info_struct *ai)
+{
+ int gr, ch, ss,clip=0;
+ int scalefacs[2][39]; /* max 39 for short[13][3] mode, mixed: 38, long: 22 */
+ struct III_sideinfo sideinfo;
+ int stereo = fr->stereo;
+ int single = fr->single;
+ int ms_stereo,i_stereo;
+ int sfreq = fr->sampling_frequency;
+ int stereo1,granules;
+
+ if(stereo == 1) { /* stream is mono */
+ stereo1 = 1;
+ single = 0;
+ }
+ else if(single >= 0) /* stream is stereo, but force to mono */
+ stereo1 = 1;
+ else
+ stereo1 = 2;
+
+ if(fr->mode == MPG_MD_JOINT_STEREO) {
+ ms_stereo = (fr->mode_ext & 0x2)>>1;
+ i_stereo = fr->mode_ext & 0x1;
+ }
+ else
+ ms_stereo = i_stereo = 0;
+
+ granules = fr->lsf ? 1 : 2;
+ if(!III_get_side_info(&sideinfo,stereo,ms_stereo,sfreq,single,fr->lsf))
+ return -1;
+
+ set_pointer(fr->sideInfoSize,sideinfo.main_data_begin);
+
+ for (gr=0;gr<granules;gr++) {
+ real hybridIn [2][SBLIMIT][SSLIMIT];
+ real hybridOut[2][SSLIMIT][SBLIMIT];
+
+ {
+ struct gr_info_s *gr_info = &(sideinfo.ch[0].gr[gr]);
+ long part2bits;
+ if(fr->lsf)
+ part2bits = III_get_scale_factors_2(scalefacs[0],gr_info,0);
+ else
+ part2bits = III_get_scale_factors_1(scalefacs[0],gr_info);
+
+ if(III_dequantize_sample(hybridIn[0], scalefacs[0],gr_info,sfreq,part2bits))
+ return clip;
+ }
+
+ if(stereo == 2) {
+ struct gr_info_s *gr_info = &(sideinfo.ch[1].gr[gr]);
+ long part2bits;
+ if(fr->lsf)
+ part2bits = III_get_scale_factors_2(scalefacs[1],gr_info,i_stereo);
+ else
+ part2bits = III_get_scale_factors_1(scalefacs[1],gr_info);
+
+ if(III_dequantize_sample(hybridIn[1],scalefacs[1],gr_info,sfreq,part2bits))
+ return clip;
+
+ if(ms_stereo) {
+ int i;
+ int maxb = sideinfo.ch[0].gr[gr].maxb;
+ if(sideinfo.ch[1].gr[gr].maxb > maxb)
+ maxb = sideinfo.ch[1].gr[gr].maxb;
+ for(i=0;i<SSLIMIT*maxb;i++) {
+ real tmp0 = ((real *)hybridIn[0])[i];
+ real tmp1 = ((real *)hybridIn[1])[i];
+ ((real *)hybridIn[0])[i] = tmp0 + tmp1;
+ ((real *)hybridIn[1])[i] = tmp0 - tmp1;
+ }
+ }
+
+ if(i_stereo)
+ III_i_stereo(hybridIn,scalefacs[1],gr_info,sfreq,ms_stereo,fr->lsf);
+
+ if(ms_stereo || i_stereo || (single == 3) ) {
+ if(gr_info->maxb > sideinfo.ch[0].gr[gr].maxb)
+ sideinfo.ch[0].gr[gr].maxb = gr_info->maxb;
+ else
+ gr_info->maxb = sideinfo.ch[0].gr[gr].maxb;
+ }
+
+ switch(single) {
+ case 3:
+ {
+ register int i;
+ register real *in0 = (real *) hybridIn[0],*in1 = (real *) hybridIn[1];
+ for(i=0;i<SSLIMIT*gr_info->maxb;i++,in0++)
+ *in0 = (*in0 + *in1++); /* *0.5 done by pow-scale */
+ }
+ break;
+ case 1:
+ {
+ register int i;
+ register real *in0 = (real *) hybridIn[0],*in1 = (real *) hybridIn[1];
+ for(i=0;i<SSLIMIT*gr_info->maxb;i++)
+ *in0++ = *in1++;
+ }
+ break;
+ }
+ }
+
+ for(ch=0;ch<stereo1;ch++) {
+ struct gr_info_s *gr_info = &(sideinfo.ch[ch].gr[gr]);
+ III_antialias(hybridIn[ch],gr_info);
+ III_hybrid(mp,hybridIn[ch], hybridOut[ch], ch,gr_info,fr);
+ }
+
+#ifdef I486_OPT
+ if (fr->synth != synth_1to1 || single >= 0) {
+#endif
+ for(ss=0;ss<SSLIMIT;ss++) {
+ if(single >= 0) {
+ clip += (fr->synth_mono)(hybridOut[0][ss],pcm_sample,&pcm_point);
+ }
+ else {
+ int p1 = pcm_point;
+ clip += (fr->synth)(hybridOut[0][ss],0,pcm_sample,&p1);
+ clip += (fr->synth)(hybridOut[1][ss],1,pcm_sample,&pcm_point);
+ }
+
+ if(pcm_point >= audiobufsize)
+ audio_flush(outmode,ai);
+ }
+#ifdef I486_OPT
+ } else {
+ /* Only stereo, 16 bits benefit from the 486 optimization. */
+ ss=0;
+ while (ss < SSLIMIT) {
+ int n;
+ n=(audiobufsize - pcm_point) / (2*2*32);
+ if (n > (SSLIMIT-ss)) n=SSLIMIT-ss;
+
+ synth_1to1_486(hybridOut[0][ss],0,pcm_sample+pcm_point,n);
+ synth_1to1_486(hybridOut[1][ss],1,pcm_sample+pcm_point,n);
+ ss+=n;
+ pcm_point+=(2*2*32)*n;
+
+ if(pcm_point >= audiobufsize)
+ audio_flush(outmode,ai);
+ }
+ }
+#endif
+ }
+
+ return clip;
+}
diff --git a/mpg123_artsplugin/mpg123/mpg123.h b/mpg123_artsplugin/mpg123/mpg123.h
new file mode 100644
index 00000000..9c61a4ce
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/mpg123.h
@@ -0,0 +1,465 @@
+/*
+ * mpg123 defines
+ * used source: musicout.h from mpegaudio package
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+#ifndef WIN32
+#include <sys/signal.h>
+#include <unistd.h>
+#endif
+
+#include <math.h>
+
+typedef unsigned char byte;
+
+#ifdef OS2
+#include <float.h>
+#endif
+
+#define MPG123_REMOTE
+#ifdef HPUX
+#define random rand
+#define srandom srand
+#endif
+
+#define FRONTEND_NONE 0
+#define FRONTEND_SAJBER 1
+#define FRONTEND_TK3PLAY 2
+#define FRONTEND_GENERIC 3
+
+#define SKIP_JUNK 1
+
+#ifdef _WIN32 /* Win32 Additions By Tony Million */
+# undef WIN32
+# define WIN32
+
+# define M_PI 3.14159265358979323846
+# define M_SQRT2 1.41421356237309504880
+# define REAL_IS_FLOAT
+# define NEW_DCT9
+
+# define random rand
+# define srandom srand
+
+# define SIGUSR1 0
+# define SIGCONT 0
+# define SIGSTOP 0
+
+# undef MPG123_REMOTE /* Get rid of this stuff for Win32 */
+#endif
+
+#include "xfermem.h"
+
+#ifdef SUNOS
+#define memmove(dst,src,size) bcopy(src,dst,size)
+#endif
+
+#ifdef REAL_IS_FLOAT
+# define real float
+#elif defined(REAL_IS_LONG_DOUBLE)
+# define real long double
+#elif defined(REAL_IS_FIXED)
+# define real long
+
+# define REAL_RADIX 15
+# define REAL_FACTOR (32.0 * 1024.0)
+
+# define REAL_PLUS_32767 ( 32767 << REAL_RADIX )
+# define REAL_MINUS_32768 ( -32768 << REAL_RADIX )
+
+# define DOUBLE_TO_REAL(x) ((int)((x) * REAL_FACTOR))
+# define REAL_TO_SHORT(x) ((x) >> REAL_RADIX)
+# define REAL_MUL(x, y) (((long long)(x) * (long long)(y)) >> REAL_RADIX)
+
+#else
+# define real double
+#endif
+
+#ifndef DOUBLE_TO_REAL
+# define DOUBLE_TO_REAL(x) (x)
+#endif
+#ifndef REAL_TO_SHORT
+# define REAL_TO_SHORT(x) (x)
+#endif
+#ifndef REAL_PLUS_32767
+# define REAL_PLUS_32767 32767.0
+#endif
+#ifndef REAL_MINUS_32768
+# define REAL_MINUS_32768 -32768.0
+#endif
+#ifndef REAL_MUL
+# define REAL_MUL(x, y) ((x) * (y))
+#endif
+
+#ifdef __GNUC__
+#define INLINE inline
+#else
+#define INLINE
+#endif
+
+#include "audio.h"
+
+/* AUDIOBUFSIZE = n*64 with n=1,2,3 ... */
+#define AUDIOBUFSIZE 16384
+
+#define FALSE 0
+#define TRUE 1
+
+#define MAX_NAME_SIZE 81
+#define SBLIMIT 32
+#define SCALE_BLOCK 12
+#define SSLIMIT 18
+
+#define MPG_MD_STEREO 0
+#define MPG_MD_JOINT_STEREO 1
+#define MPG_MD_DUAL_CHANNEL 2
+#define MPG_MD_MONO 3
+
+/* #define MAXFRAMESIZE 1792 */
+#define MAXFRAMESIZE 4096
+#define HDRCMPMASK 0xfffffd00
+
+#define MAXOUTBURST 32768
+
+/* Pre Shift fo 16 to 8 bit converter table */
+#define AUSHIFT (3)
+
+
+struct al_table
+{
+ short bits;
+ short d;
+};
+
+struct frame {
+ struct al_table *alloc;
+ int (*synth)(real *,int,unsigned char *,int *);
+ int (*synth_mono)(real *,unsigned char *,int *);
+#ifdef USE_3DNOW
+ void (*dct36)(real *,real *,real *,real *,real *);
+#endif
+ int stereo;
+ int jsbound;
+ int single;
+ int II_sblimit;
+ int down_sample_sblimit;
+ int lsf;
+ int mpeg25;
+ int down_sample;
+ int header_change;
+ int lay;
+ int error_protection;
+ int bitrate_index;
+ int sampling_frequency;
+ int padding;
+ int extension;
+ int mode;
+ int mode_ext;
+ int copyright;
+ int original;
+ int emphasis;
+ int framesize; /* computed framesize */
+ int padsize; /* */
+
+ int sideInfoSize; /* Layer3 sideInfo Header size */
+
+ /* FIXME: move this to another place */
+ unsigned long firsthead;
+ unsigned long thishead;
+ int freeformatsize;
+};
+
+#define VBR_TOC_SIZE 100
+
+#define VBR_FRAMES_FLAG 0x0001
+#define VBR_BYTES_FLAG 0x0002
+#define VBR_TOC_FLAG 0x0004
+#define VBR_SCALE_FLAG 0x0008
+
+struct vbrHeader {
+ unsigned long flags;
+ unsigned long frames;
+ unsigned long bytes;
+ unsigned long scale;
+ unsigned char toc[100];
+};
+
+struct parameter {
+ int aggressive; /* renice to max. priority */
+ int shuffle; /* shuffle/random play */
+ int remote; /* remote operation */
+ int outmode; /* where to out the decoded sampels */
+ int quiet; /* shut up! */
+ int xterm_title; /* print filename in xterm title */
+ long usebuffer; /* second level buffer size */
+ int tryresync; /* resync stream after error */
+ int verbose; /* verbose level */
+#ifdef TERM_CONTROL
+ int term_ctrl;
+#endif
+ int force_mono;
+ int force_stereo;
+ int force_8bit;
+ long force_rate;
+ double pitch;
+ int down_sample;
+ int checkrange;
+ long doublespeed;
+ long halfspeed;
+ int force_reopen;
+ int stat_3dnow; /* automatic/force/force-off 3DNow! optimized code */
+ int test_3dnow;
+ int realtime;
+ char filename[256];
+ char *esdserver;
+ char *equalfile;
+ int enable_equalizer;
+ long outscale;
+ long startFrame;
+ int print_version;
+};
+
+struct bitstream_info {
+ int bitindex;
+ unsigned char *wordpointer;
+};
+
+struct mpstr {
+ int bsize;
+ int framesize;
+ int fsizeold;
+ struct frame fr;
+ /* int (*do_layer)(struct mpstr *,struct frame *fr,int,struct audio_info_struct *); */
+ unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */
+ real hybrid_block[2][2][SBLIMIT*SSLIMIT];
+ int hybrid_blc[2];
+ unsigned long header;
+ int bsnum;
+ real synth_buffs[2][2][0x110];
+ int synth_bo;
+
+ struct bitstream_info bsi;
+};
+
+extern struct bitstream_info bsi;
+
+struct reader {
+ int (*init)(struct reader *);
+ void (*close)(struct reader *);
+ int (*head_read)(struct reader *,unsigned long *newhead);
+ int (*head_shift)(struct reader *,unsigned long *head);
+ int (*skip_bytes)(struct reader *,int len);
+ int (*read_frame_body)(struct reader *,unsigned char *,int size);
+ int (*back_bytes)(struct reader *,int bytes);
+ int (*back_frame)(struct reader *,struct frame *,int num);
+ long (*tell)(struct reader *);
+ void (*rewind)(struct reader *);
+ long filelen;
+ long filepos;
+ int filept;
+ int flags;
+ unsigned char id3buf[128];
+
+ unsigned char *backbuf;
+ int mark;
+ int bufpos,bufstart,bufend;
+ int bufsize;
+};
+#define READER_FD_OPENED 0x1
+#define READER_ID3TAG 0x2
+
+extern struct reader *rd,readers[];
+
+extern int halfspeed;
+extern int buffer_fd[2];
+extern txfermem *buffermem;
+extern char *prgName, *prgVersion;
+
+#ifndef NOXFERMEM
+extern void buffer_loop(struct audio_info_struct *ai,sigset_t *oldsigset);
+#endif
+
+extern void readers_pushback_header(struct reader *rds,unsigned long aLong);
+extern void readers_mark_pos(struct reader *rds);
+extern void readers_goto_mark(struct reader *rds);
+
+
+/* ------ Declarations from "httpget.c" ------ */
+
+extern char *proxyurl;
+extern unsigned long proxyip;
+extern int http_open (const char *url);
+extern char *httpauth;
+
+/* ------ Declarations from "common.c" ------ */
+
+int sync_stream(struct reader *rds,struct frame *fr,int flags,int *skipped);
+
+extern void audio_flush(int, struct audio_info_struct *);
+extern void (*catchsignal(int signum, void(*handler)()))();
+
+extern void print_header(struct frame *);
+extern void print_header_compact(struct frame *);
+extern void print_id3_tag(unsigned char *buf);
+
+extern int split_dir_file(const char *path, char **dname, char **fname);
+
+extern unsigned int get1bit(struct bitstream_info *);
+extern unsigned int getbits(struct bitstream_info *,int);
+extern unsigned int getbits_fast(struct bitstream_info *,int);
+extern void backbits(struct bitstream_info *,int);
+extern int getbitoffset(struct bitstream_info *);
+extern int getbyte(struct bitstream_info *);
+
+extern void set_pointer(int,long);
+
+extern unsigned char *pcm_sample;
+extern int pcm_point;
+extern int audiobufsize;
+
+extern int OutputDescriptor;
+
+struct gr_info_s {
+ int scfsi;
+ unsigned part2_3_length;
+ unsigned big_values;
+ unsigned scalefac_compress;
+ unsigned block_type;
+ unsigned mixed_block_flag;
+ unsigned table_select[3];
+ unsigned subblock_gain[3];
+ unsigned maxband[3];
+ unsigned maxbandl;
+ unsigned maxb;
+ unsigned region1start;
+ unsigned region2start;
+ unsigned preflag;
+ unsigned scalefac_scale;
+ unsigned count1table_select;
+ real *full_gain[3];
+ real *pow2gain;
+};
+
+struct III_sideinfo
+{
+ unsigned main_data_begin;
+ unsigned private_bits;
+ struct {
+ struct gr_info_s gr[2];
+ } ch[2];
+};
+
+extern struct reader *open_stream(const char *,int fd);
+extern void read_frame_init (struct frame *fr);
+extern int read_frame(struct reader *rd,struct frame *fr);
+extern int play_frame(struct mpstr *mp,int init,struct frame *fr);
+extern int do_layer3(struct mpstr *mp,struct frame *fr,int,struct audio_info_struct *);
+extern int do_layer2(struct mpstr *mp,struct frame *fr,int,struct audio_info_struct *);
+extern int do_layer1(struct mpstr *mp,struct frame *fr,int,struct audio_info_struct *);
+extern void do_equalizer(real *bandPtr,int channel);
+
+#ifdef PENTIUM_OPT
+extern int synth_1to1_pent (real *,int,unsigned char *);
+#endif
+extern int synth_1to1 (real *,int,unsigned char *,int *);
+extern int synth_1to1_8bit (real *,int,unsigned char *,int *);
+extern int synth_1to1_mono (real *,unsigned char *,int *);
+extern int synth_1to1_mono2stereo (real *,unsigned char *,int *);
+extern int synth_1to1_8bit_mono (real *,unsigned char *,int *);
+extern int synth_1to1_8bit_mono2stereo (real *,unsigned char *,int *);
+
+extern int synth_2to1 (real *,int,unsigned char *,int *);
+extern int synth_2to1_8bit (real *,int,unsigned char *,int *);
+extern int synth_2to1_mono (real *,unsigned char *,int *);
+extern int synth_2to1_mono2stereo (real *,unsigned char *,int *);
+extern int synth_2to1_8bit_mono (real *,unsigned char *,int *);
+extern int synth_2to1_8bit_mono2stereo (real *,unsigned char *,int *);
+
+extern int synth_4to1 (real *,int,unsigned char *,int *);
+extern int synth_4to1_8bit (real *,int,unsigned char *,int *);
+extern int synth_4to1_mono (real *,unsigned char *,int *);
+extern int synth_4to1_mono2stereo (real *,unsigned char *,int *);
+extern int synth_4to1_8bit_mono (real *,unsigned char *,int *);
+extern int synth_4to1_8bit_mono2stereo (real *,unsigned char *,int *);
+
+extern int synth_ntom (real *,int,unsigned char *,int *);
+extern int synth_ntom_8bit (real *,int,unsigned char *,int *);
+extern int synth_ntom_mono (real *,unsigned char *,int *);
+extern int synth_ntom_mono2stereo (real *,unsigned char *,int *);
+extern int synth_ntom_8bit_mono (real *,unsigned char *,int *);
+extern int synth_ntom_8bit_mono2stereo (real *,unsigned char *,int *);
+
+extern void rewindNbits(int bits);
+extern int hsstell(void);
+extern void huffman_decoder(int ,int *);
+extern void huffman_count1(int,int *);
+extern void print_stat(struct reader *rd,struct frame *fr,int no,long buffsize,struct audio_info_struct *ai);
+extern int get_songlen(struct reader *rd,struct frame *fr,int no);
+
+extern void init_layer3(int);
+extern void init_layer2(void);
+extern void make_decode_tables(long scale);
+extern void make_conv16to8_table(int);
+extern void dct64(real *,real *,real *);
+
+#ifdef USE_MMX
+extern void dct64_MMX(short *a,short *b,real *c);
+extern int synth_1to1_MMX(real *, int, short *, short *, int *);
+#endif
+
+extern void synth_ntom_set_step(long,long);
+
+extern void control_generic(struct mpstr *,struct frame *fr);
+extern void control_sajber(struct mpstr *,struct frame *fr);
+extern void control_tk3play(struct mpstr *,struct frame *fr);
+
+extern int cdr_open(struct audio_info_struct *ai, char *ame);
+extern int au_open(struct audio_info_struct *ai, char *name);
+extern int wav_open(struct audio_info_struct *ai, char *wavfilename);
+extern int wav_write(unsigned char *buf,int len);
+extern int cdr_close(void);
+extern int au_close(void);
+extern int wav_close(void);
+
+extern int au_open(struct audio_info_struct *ai, char *aufilename);
+extern int au_close(void);
+
+extern int cdr_open(struct audio_info_struct *ai, char *cdrfilename);
+extern int cdr_close(void);
+
+extern int getVBRHeader(struct vbrHeader *head,unsigned char *buf,
+ struct frame *fr);
+
+
+extern unsigned char *conv16to8;
+extern long freqs[9];
+extern real muls[27][64];
+extern real decwin[512+32];
+#ifndef USE_MMX
+extern real *pnts[5];
+#endif
+
+extern real equalizer[2][32];
+extern real equalizer_sum[2][32];
+extern int equalizer_cnt;
+
+extern struct audio_name audio_val2name[];
+
+extern struct parameter param;
+
+/* 486 optimizations */
+#define FIR_BUFFER_SIZE 128
+extern void dct64_486(int *a,int *b,real *c);
+extern int synth_1to1_486(real *bandPtr,int channel,unsigned char *out,int nb_blocks);
+
+/* 3DNow! optimizations */
+#ifdef USE_3DNOW
+extern int getcpuflags(void);
+extern void dct36(real *,real *,real *,real *,real *);
+extern void dct36_3dnow(real *,real *,real *,real *,real *);
+extern int synth_1to1_3dnow(real *,int,unsigned char *,int *);
+#endif
diff --git a/mpg123_artsplugin/mpg123/readers.c b/mpg123_artsplugin/mpg123/readers.c
new file mode 100644
index 00000000..de5f53db
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/readers.c
@@ -0,0 +1,618 @@
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "mpg123.h"
+#include "buffer.h"
+#include "common.h"
+
+#ifdef READ_MMAP
+#include <sys/mman.h>
+#ifndef MAP_FAILED
+#define MAP_FAILED ( (void *) -1 )
+#endif
+#endif
+
+static int get_fileinfo(struct reader *,char *buf);
+static void readers_add_data(struct reader *rds,unsigned char *buf,int len);
+
+/* can hold 4096-1 = 4095 bytes! */
+#define BACKBUF_SIZE (8192)
+
+/*******************************************************************
+ * stream based operation
+ */
+static int bufdiff(struct reader *rds,int start, int end)
+{
+ return (end >= start) ? end - start : rds->bufsize + end - start;
+}
+
+static int fullread(struct reader *rds,int fd,unsigned char *buf,int count)
+{
+ int ret,cnt=0;
+
+ while(cnt < count) {
+ int toread = count-cnt;
+ int num = bufdiff(rds,rds->bufpos,rds->bufend);
+
+ /* if we have some data in the backbuffer .. use it first */
+ if(num > 0) {
+ int part1,part2;
+
+ if(toread > num)
+ toread = num;
+
+ part1 = rds->bufsize - rds->bufpos;
+ if(part1 > toread)
+ part1 = toread;
+ part2 = toread - part1;
+ memcpy(buf+cnt,&rds->backbuf[rds->bufpos],part1);
+ if(part2 > 0)
+ memcpy(buf+cnt+part1,&rds->backbuf[0],part2);
+ rds->bufpos += toread;
+ if(rds->bufpos >= rds->bufsize)
+ rds->bufpos -= rds->bufsize;
+ ret = toread;
+
+ if(!rds->mark)
+ rds->bufstart = rds->bufpos;
+ }
+ else {
+ ret = read(fd,buf+cnt,toread);
+
+ if(ret < 0)
+ return ret;
+ if(ret == 0)
+ break;
+
+ if(rds->mark) {
+ readers_add_data(rds,buf+cnt,ret);
+ rds->bufpos = rds->bufend;
+ }
+
+ }
+ cnt += ret;
+ }
+
+
+if(0)
+{
+ int i;
+ fprintf(stderr,"Fullread2 %d\n",cnt);
+ for(i=0;i<cnt;i++) {
+ fprintf(stderr,"%02x ",buf[i]);
+ if(i % 16 == 15)
+ fprintf(stderr,"\n");
+ }
+}
+
+
+ return cnt;
+}
+
+static void readers_add_data(struct reader *rds,unsigned char *buf,int len)
+{
+ int diff,part1,part2,store = len;
+
+ if(store >= rds->bufsize)
+ store = rds->bufsize - 1;
+
+ /* check whether the new bytes would overwrite the buffer front */
+ diff = bufdiff(rds,rds->bufstart,rds->bufend);
+ if(diff+store >= rds->bufsize) {
+ fprintf(stderr,"Warning: backbuffer overfull %d %d\n",diff+store,rds->bufsize);
+ /* +1 because end should never be the same as start if the is data in the buffer */
+ rds->bufstart += diff + store + 1 - rds->bufsize;
+ if(rds->bufstart >= rds->bufsize)
+ rds->bufstart -= rds->bufsize;
+ }
+
+ part1 = rds->bufsize - rds->bufend;
+ if(part1 > store)
+ part1 = store;
+ part2 = store - part1;
+
+ memcpy(rds->backbuf+rds->bufend,&buf[len-part1+part2],part1);
+ if(part2 > 0)
+ memcpy(rds->backbuf,&buf[len-part2],part2);
+
+ rds->bufend += store;
+ if(rds->bufend >= rds->bufsize)
+ rds->bufend -= rds->bufsize;
+
+
+}
+
+void readers_pushback_header(struct reader *rds,unsigned long aLong)
+{
+ unsigned char buf[4];
+
+ if(rds->mark || (rds->bufpos != rds->bufend) ) {
+ rds->bufpos -= 4;
+ if(rds->bufpos < 0)
+ rds->bufpos += rds->bufsize;
+ }
+ else {
+ buf[0] = (aLong>>24) & 0xff;
+ buf[1] = (aLong>>16) & 0xff;
+ buf[2] = (aLong>>8) & 0xff;
+ buf[3] = (aLong>>0) & 0xff;
+ }
+
+ readers_add_data(rds,buf,4);
+}
+
+void readers_mark_pos(struct reader *rds) {
+ /* fprintf(stderr,"M%d ",rds->bufpos); */
+ rds->bufstart = rds->bufpos;
+ rds->mark = 1;
+}
+
+void readers_goto_mark(struct reader *rds) {
+ /* fprintf(stderr,"G%d ",rds->bufstart); */
+ rds->mark = 0;
+ rds->bufpos = rds->bufstart;
+}
+
+
+static int default_init(struct reader *rds)
+{
+ char buf[128];
+
+ rds->mark = 0;
+ rds->bufend = 0;
+ rds->bufstart = 0;
+ rds->bufpos = 0;
+ rds->bufsize = BACKBUF_SIZE;
+
+ rds->backbuf = (unsigned char *) malloc(rds->bufsize);
+
+ rds->filepos = 0;
+ rds->filelen = get_fileinfo(rds,buf);
+
+ if(rds->filelen > 0) {
+ if(!strncmp(buf,"TAG",3)) {
+ rds->flags |= READER_ID3TAG;
+ memcpy(rds->id3buf,buf,128);
+ }
+ }
+ return 0;
+}
+
+void stream_close(struct reader *rds)
+{
+ if (rds->flags & READER_FD_OPENED)
+ close(rds->filept);
+}
+
+/****************************************
+ * HACK,HACK,HACK: step back <num> frames
+ * can only work if the 'stream' isn't a real stream but a file
+ */
+static int stream_back_bytes(struct reader *rds,int bytes)
+{
+ if(lseek(rds->filept,-bytes,SEEK_CUR) < 0)
+ return -1;
+ if(param.usebuffer)
+ buffer_resync();
+ return 0;
+}
+
+static int stream_back_frame(struct reader *rds,struct frame *fr,int num)
+{
+ long bytes;
+ int skipped;
+
+ if(!fr->firsthead)
+ return 0;
+
+ bytes = (fr->framesize+8)*(num+2);
+
+ /* Skipping back/forth requires a bit more work in buffered mode.
+ * See mapped_back_frame().
+ */
+#ifndef NOXFERMEM
+ if(param.usebuffer)
+ bytes += (long)(xfermem_get_usedspace(buffermem) /
+ (buffermem->buf[0] * buffermem->buf[1]
+ * (buffermem->buf[2] & AUDIO_FORMAT_MASK ?
+ 16.0 : 8.0 ))
+ * (tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index] << 10));
+#endif
+ /*
+ bytes += (long)(compute_buffer_offset(fr)*compute_bpf(fr));
+ */
+ if(lseek(rds->filept,-bytes,SEEK_CUR) < 0)
+ return -1;
+
+ sync_stream(rds,fr,0xffff,&skipped);
+
+ read_frame(rds,fr);
+ read_frame(rds,fr);
+
+ if(fr->lay == 3) {
+ set_pointer(fr->sideInfoSize,512);
+ }
+
+ if(param.usebuffer)
+ buffer_resync();
+
+ return 0;
+}
+
+static int stream_head_read(struct reader *rds,unsigned long *newhead)
+{
+ unsigned char hbuf[4];
+
+ if(fullread(rds,rds->filept,hbuf,4) != 4)
+ return FALSE;
+
+ *newhead = ((unsigned long) hbuf[0] << 24) |
+ ((unsigned long) hbuf[1] << 16) |
+ ((unsigned long) hbuf[2] << 8) |
+ (unsigned long) hbuf[3];
+
+ return TRUE;
+}
+
+static int stream_head_shift(struct reader *rds,unsigned long *head)
+{
+ unsigned char hbuf;
+
+ if(fullread(rds,rds->filept,&hbuf,1) != 1)
+ return 0;
+ *head <<= 8;
+ *head |= hbuf;
+ *head &= 0xffffffff;
+ return 1;
+}
+
+static int stream_skip_bytes(struct reader *rds,int len)
+{
+ if (!param.usebuffer)
+ return lseek(rds->filept,len,SEEK_CUR);
+
+ else {
+ int ret = lseek(rds->filept,len,SEEK_CUR);
+ buffer_resync();
+ return ret;
+ }
+}
+
+static int stream_read_frame_body(struct reader *rds,unsigned char *buf,
+ int size)
+{
+ long l;
+
+ if( (l=fullread(rds,rds->filept,buf,size)) != size)
+ {
+ if(l <= 0)
+ return 0;
+ memset(buf+l,0,size-l);
+ }
+
+ return 1;
+}
+
+static long stream_tell(struct reader *rds)
+{
+ return lseek(rds->filept,0,SEEK_CUR);
+}
+
+static void stream_rewind(struct reader *rds)
+{
+ lseek(rds->filept,0,SEEK_SET);
+ if(param.usebuffer)
+ buffer_resync();
+}
+
+/*
+ * returns length of a file (if filept points to a file)
+ * reads the last 128 bytes information into buffer
+ */
+static int get_fileinfo(struct reader *rds,char *buf)
+{
+ int len;
+
+ if((len=lseek(rds->filept,0,SEEK_END)) < 0) {
+ return -1;
+ }
+ if(lseek(rds->filept,-128,SEEK_END) < 0)
+ return -1;
+ if(fullread(rds,rds->filept,(unsigned char *)buf,128) != 128) {
+ return -1;
+ }
+ if(!strncmp(buf,"TAG",3)) {
+ len -= 128;
+ }
+ if(lseek(rds->filept,0,SEEK_SET) < 0)
+ return -1;
+ if(len <= 0)
+ return -1;
+ return len;
+}
+
+
+#ifdef READ_MMAP
+/*********************************************************+
+ * memory mapped operation
+ *
+ */
+static unsigned char *mapbuf;
+static unsigned char *mappnt;
+static unsigned char *mapend;
+
+static int mapped_init(struct reader *rds)
+{
+ long len;
+ char buf[128];
+
+ len = get_fileinfo(rds,buf);
+ if(len < 0)
+ return -1;
+
+ if(!strncmp(buf,"TAG",3)) {
+ rds->flags |= READER_ID3TAG;
+ memcpy(rds->id3buf,buf,128);
+ }
+
+ mappnt = mapbuf = (unsigned char *)
+ mmap(NULL, len, PROT_READ, MAP_SHARED , rds->filept, 0);
+ if(!mapbuf || mapbuf == MAP_FAILED)
+ return -1;
+
+ mapend = mapbuf + len;
+
+ if(param.verbose > 1)
+ fprintf(stderr,"Using memory mapped IO for this stream.\n");
+
+ rds->filelen = len;
+ return 0;
+}
+
+static void mapped_rewind(struct reader *rds)
+{
+ mappnt = mapbuf;
+ if (param.usebuffer)
+ buffer_resync();
+}
+
+static void mapped_close(struct reader *rds)
+{
+ munmap((void *)mapbuf,mapend-mapbuf);
+ if (rds->flags & READER_FD_OPENED)
+ close(rds->filept);
+}
+
+static int mapped_head_read(struct reader *rds,unsigned long *newhead)
+{
+ unsigned long nh;
+
+ if(mappnt + 4 > mapend)
+ return FALSE;
+
+ nh = (*mappnt++) << 24;
+ nh |= (*mappnt++) << 16;
+ nh |= (*mappnt++) << 8;
+ nh |= (*mappnt++) ;
+
+ *newhead = nh;
+ return TRUE;
+}
+
+static int mapped_head_shift(struct reader *rds,unsigned long *head)
+{
+ if(mappnt + 1 > mapend)
+ return FALSE;
+ *head <<= 8;
+ *head |= *mappnt++;
+ *head &= 0xffffffff;
+ return TRUE;
+}
+
+static int mapped_skip_bytes(struct reader *rds,int len)
+{
+ if(mappnt + len > mapend)
+ return FALSE;
+ mappnt += len;
+ if (param.usebuffer)
+ buffer_resync();
+ return TRUE;
+}
+
+static int mapped_read_frame_body(struct reader *rds,unsigned char *buf,
+ int size)
+{
+ if(size <= 0) {
+ fprintf(stderr,"Ouch. Read_frame called with size <= 0\n");
+ return FALSE;
+ }
+ if(mappnt + size > mapend)
+ return FALSE;
+ memcpy(buf,mappnt,size);
+ mappnt += size;
+
+ return TRUE;
+}
+
+static int mapped_back_bytes(struct reader *rds,int bytes)
+{
+ if( (mappnt - bytes) < mapbuf || (mappnt - bytes + 4) > mapend)
+ return -1;
+ mappnt -= bytes;
+ if(param.usebuffer)
+ buffer_resync();
+ return 0;
+}
+
+static int mapped_back_frame(struct reader *rds,struct frame *fr,int num)
+{
+ long bytes;
+ unsigned long newhead;
+
+
+ if(!firsthead)
+ return 0;
+
+ bytes = (fr->framesize+8)*(num+2);
+
+ /* Buffered mode is a bit trickier. From the size of the buffered
+ * output audio stream we have to make a guess at the number of frames
+ * this corresponds to.
+ */
+#ifndef NOXFERMEM
+ if(param.usebuffer)
+ bytes += (long)(xfermem_get_usedspace(buffermem) /
+ (buffermem->buf[0] * buffermem->buf[1]
+ * (buffermem->buf[2] & AUDIO_FORMAT_MASK ?
+ 16.0 : 8.0 ))
+ * (tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index] << 10));
+#endif
+ /*
+ bytes += (long)(compute_buffer_offset(fr)*compute_bpf(fr));
+ */
+
+ if( (mappnt - bytes) < mapbuf || (mappnt - bytes + 4) > mapend)
+ return -1;
+ mappnt -= bytes;
+
+ newhead = (mappnt[0]<<24) + (mappnt[1]<<16) + (mappnt[2]<<8) + mappnt[3];
+ mappnt += 4;
+
+ while( (newhead & HDRCMPMASK) != (firsthead & HDRCMPMASK) ) {
+ if(mappnt + 1 > mapend)
+ return -1;
+ newhead <<= 8;
+ newhead |= *mappnt++;
+ newhead &= 0xffffffff;
+ }
+ mappnt -= 4;
+
+ read_frame(fr);
+ read_frame(fr);
+
+ if(fr->lay == 3)
+ set_pointer(fr->sideInfoSize,512);
+
+ if(param.usebuffer)
+ buffer_resync();
+
+ return 0;
+}
+
+static long mapped_tell(struct reader *rds)
+{
+ return mappnt - mapbuf;
+}
+
+#endif
+
+/*****************************************************************
+ * read frame helper
+ */
+
+struct reader *rd;
+struct reader readers[] = {
+#ifdef READ_SYSTEM
+ { system_init,
+ NULL, /* filled in by system_init() */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL } ,
+#endif
+#ifdef READ_MMAP
+ { mapped_init,
+ mapped_close,
+ mapped_head_read,
+ mapped_head_shift,
+ mapped_skip_bytes,
+ mapped_read_frame_body,
+ mapped_back_bytes,
+ mapped_back_frame,
+ mapped_tell,
+ mapped_rewind } ,
+#endif
+ { default_init,
+ stream_close,
+ stream_head_read,
+ stream_head_shift,
+ stream_skip_bytes,
+ stream_read_frame_body,
+ stream_back_bytes,
+ stream_back_frame,
+ stream_tell,
+ stream_rewind } ,
+ { NULL, }
+};
+
+
+/* open the device to read the bit stream from it */
+
+struct reader *open_stream(const char *bs_filenam,int fd)
+{
+ int i;
+ int filept_opened = 1;
+ int filept;
+
+ if (!bs_filenam) {
+ if(fd < 0) {
+ filept = 0;
+ filept_opened = 0;
+ }
+ else
+ filept = fd;
+ }
+ else if (!strncasecmp(bs_filenam, "http://", 7))
+ filept = http_open(bs_filenam);
+ else if (!strncasecmp(bs_filenam, "ftp://", 6))
+ filept = http_open(bs_filenam);
+
+#ifndef O_BINARY
+#define O_BINARY (0)
+#endif
+ else if ( (filept = open(bs_filenam, O_RDONLY|O_BINARY)) < 0) {
+ perror (bs_filenam);
+ return NULL;
+ }
+
+ rd = NULL;
+ for(i=0;;i++) {
+ readers[i].filelen = -1;
+ readers[i].filept = filept;
+ readers[i].flags = 0;
+ if(filept_opened)
+ readers[i].flags |= READER_FD_OPENED;
+ if(!readers[i].init) {
+ fprintf(stderr,"Fatal error!\n");
+ exit(1);
+ }
+ if(readers[i].init(readers+i) >= 0) {
+ rd = &readers[i];
+ break;
+ }
+ }
+
+ if(rd && rd->flags & READER_ID3TAG) {
+ print_id3_tag(rd->id3buf);
+ }
+
+ return rd;
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mpg123_artsplugin/mpg123/tabinit.c b/mpg123_artsplugin/mpg123/tabinit.c
new file mode 100644
index 00000000..4622114e
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/tabinit.c
@@ -0,0 +1,139 @@
+
+#include <stdlib.h>
+
+#include "mpg123.h"
+
+static unsigned char *conv16to8_buf = NULL;
+unsigned char *conv16to8;
+
+#ifndef USE_MMX
+real decwin[512+32];
+static real cos64[16],cos32[8],cos16[4],cos8[2],cos4[1];
+
+real *pnts[] = { cos64,cos32,cos16,cos8,cos4 };
+
+
+static long intwinbase[] = {
+ 0, -1, -1, -1, -1, -1, -1, -2, -2, -2,
+ -2, -3, -3, -4, -4, -5, -5, -6, -7, -7,
+ -8, -9, -10, -11, -13, -14, -16, -17, -19, -21,
+ -24, -26, -29, -31, -35, -38, -41, -45, -49, -53,
+ -58, -63, -68, -73, -79, -85, -91, -97, -104, -111,
+ -117, -125, -132, -139, -147, -154, -161, -169, -176, -183,
+ -190, -196, -202, -208, -213, -218, -222, -225, -227, -228,
+ -228, -227, -224, -221, -215, -208, -200, -189, -177, -163,
+ -146, -127, -106, -83, -57, -29, 2, 36, 72, 111,
+ 153, 197, 244, 294, 347, 401, 459, 519, 581, 645,
+ 711, 779, 848, 919, 991, 1064, 1137, 1210, 1283, 1356,
+ 1428, 1498, 1567, 1634, 1698, 1759, 1817, 1870, 1919, 1962,
+ 2001, 2032, 2057, 2075, 2085, 2087, 2080, 2063, 2037, 2000,
+ 1952, 1893, 1822, 1739, 1644, 1535, 1414, 1280, 1131, 970,
+ 794, 605, 402, 185, -45, -288, -545, -814, -1095, -1388,
+ -1692, -2006, -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788,
+ -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, -7910, -8209,
+ -8491, -8755, -8998, -9219, -9416, -9585, -9727, -9838, -9916, -9959,
+ -9966, -9935, -9863, -9750, -9592, -9389, -9139, -8840, -8492, -8092,
+ -7640, -7134, -6574, -5959, -5288, -4561, -3776, -2935, -2037, -1082,
+ -70, 998, 2122, 3300, 4533, 5818, 7154, 8540, 9975, 11455,
+ 12980, 14548, 16155, 17799, 19478, 21189, 22929, 24694, 26482, 28289,
+ 30112, 31947, 33791, 35640, 37489, 39336, 41176, 43006, 44821, 46617,
+ 48390, 50137, 51853, 53534, 55178, 56778, 58333, 59838, 61289, 62684,
+ 64019, 65290, 66494, 67629, 68692, 69679, 70590, 71420, 72169, 72835,
+ 73415, 73908, 74313, 74630, 74856, 74992, 75038 };
+
+void make_decode_tables(long scaleval)
+{
+ int i,j,k,kr,divv;
+ real *costab;
+ int idx;
+
+
+ for(i=0;i<5;i++)
+ {
+ kr=0x10>>i; divv=0x40>>i;
+ costab = pnts[i];
+ for(k=0;k<kr;k++)
+ costab[k] = DOUBLE_TO_REAL(1.0 / (2.0 * cos(M_PI * ((double) k * 2.0 + 1.0) / (double) divv)));
+ }
+
+ idx = 0;
+ scaleval = -scaleval;
+ for(i=0,j=0;i<256;i++,j++,idx+=32)
+ {
+ if(idx < 512+16)
+ decwin[idx+16] = decwin[idx] = DOUBLE_TO_REAL((double) intwinbase[j] / 65536.0 * (double) scaleval);
+
+ if(i % 32 == 31)
+ idx -= 1023;
+ if(i % 64 == 63)
+ scaleval = - scaleval;
+ }
+
+ for( /* i=256 */ ;i<512;i++,j--,idx+=32)
+ {
+ if(idx < 512+16)
+ decwin[idx+16] = decwin[idx] = DOUBLE_TO_REAL((double) intwinbase[j] / 65536.0 * (double) scaleval);
+
+ if(i % 32 == 31)
+ idx -= 1023;
+ if(i % 64 == 63)
+ scaleval = - scaleval;
+ }
+
+}
+#endif
+
+void make_conv16to8_table(int mode)
+{
+ int i;
+
+ /*
+ * ????: 8.0 is right but on SB cards '2.0' is a better value ???
+ */
+ const double mul = 8.0;
+
+ if(!conv16to8_buf) {
+ conv16to8_buf = (unsigned char *) malloc(8192);
+ if(!conv16to8_buf) {
+ fprintf(stderr,"Can't allocate 16 to 8 converter table!\n");
+ exit(1);
+ }
+ conv16to8 = conv16to8_buf + 4096;
+ }
+
+ if(mode == AUDIO_FORMAT_ULAW_8) {
+ double m=127.0 / log(256.0);
+ int c1;
+
+ for(i=-4096;i<4096;i++) {
+/* dunno whether this is a valid transformation rule ?!?!? */
+ if(i < 0)
+ c1 = 127 - (int) (log( 1.0 - 255.0 * (double) i*mul / 32768.0 ) * m);
+ else
+ c1 = 255 - (int) (log( 1.0 + 255.0 * (double) i*mul / 32768.0 ) * m);
+ if(c1 < 0 || c1 > 255)
+ fprintf(stderr,"Converror %d %d\n",i,c1);
+ if(c1 == 0)
+ c1 = 2;
+ conv16to8[i] = (unsigned char) c1;
+ }
+ }
+ else if(mode == AUDIO_FORMAT_SIGNED_8) {
+ for(i=-4096;i<4096;i++) {
+ conv16to8[i] = i>>5;
+ }
+ }
+ else if(mode == AUDIO_FORMAT_UNSIGNED_8) {
+ for(i=-4096;i<4096;i++) {
+ conv16to8[i] = (i>>5)+128;
+ }
+ }
+ else {
+ for(i=-4096;i<4096;i++) {
+ conv16to8[i] = 0;
+ }
+ }
+}
+
+
+
diff --git a/mpg123_artsplugin/mpg123/tabinit_MMX.s b/mpg123_artsplugin/mpg123/tabinit_MMX.s
new file mode 100644
index 00000000..06a54e5f
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/tabinit_MMX.s
@@ -0,0 +1,160 @@
+.bss
+ .align 32
+ .comm decwin,2176,32
+ .align 32
+ .comm decwins,2176,32
+
+.data
+ .align 32
+intwinbase:
+ .value 0, -1, -1, -1, -1, -1, -1, -2
+ .value -2, -2, -2, -3, -3, -4, -4, -5
+ .value -5, -6, -7, -7, -8, -9, -10, -11
+ .value -13, -14, -16, -17, -19, -21, -24, -26
+ .value -29, -31, -35, -38, -41, -45, -49, -53
+ .value -58, -63, -68, -73, -79, -85, -91, -97
+ .value -104, -111, -117, -125, -132, -139, -147, -154
+ .value -161, -169, -176, -183, -190, -196, -202, -208
+ .value -213, -218, -222, -225, -227, -228, -228, -227
+ .value -224, -221, -215, -208, -200, -189, -177, -163
+ .value -146, -127, -106, -83, -57, -29, 2, 36
+ .value 72, 111, 153, 197, 244, 294, 347, 401
+ .value 459, 519, 581, 645, 711, 779, 848, 919
+ .value 991, 1064, 1137, 1210, 1283, 1356, 1428, 1498
+ .value 1567, 1634, 1698, 1759, 1817, 1870, 1919, 1962
+ .value 2001, 2032, 2057, 2075, 2085, 2087, 2080, 2063
+ .value 2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535
+ .value 1414, 1280, 1131, 970, 794, 605, 402, 185
+ .value -45, -288, -545, -814, -1095, -1388, -1692, -2006
+ .value -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788
+ .value -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597
+ .value -7910, -8209, -8491, -8755, -8998, -9219, -9416, -9585
+ .value -9727, -9838, -9916, -9959, -9966, -9935, -9863, -9750
+ .value -9592, -9389, -9139, -8840, -8492, -8092, -7640, -7134
+ .value -6574, -5959, -5288, -4561, -3776, -2935, -2037, -1082
+ .value -70, 998, 2122, 3300, 4533, 5818, 7154, 8540
+ .value 9975, 11455, 12980, 14548, 16155, 17799, 19478, 21189
+ .value 22929, 24694, 26482, 28289, 30112, 31947,-26209,-24360
+ .value -22511,-20664,-18824,-16994,-15179,-13383,-11610, -9863
+ .value -8147, -6466, -4822, -3222, -1667, -162, 1289, 2684
+ .value 4019, 5290, 6494, 7629, 8692, 9679, 10590, 11420
+ .value 12169, 12835, 13415, 13908, 14313, 14630, 14856, 14992
+ .value 15038
+
+intwindiv:
+ .long 0x47800000 # 65536.0
+.text
+ .align 32
+.globl make_decode_tables
+
+make_decode_tables:
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+
+ xorl %ecx,%ecx
+ xorl %ebx,%ebx
+ movl $32,%esi
+ movl $intwinbase,%edi
+ negl 16(%esp) # scaleval
+ pushl $2 # intwinbase step
+.L00:
+ cmpl $528,%ecx
+ jnc .L02
+ movswl (%edi),%eax
+ cmpl $intwinbase+444,%edi
+ jc .L01
+ addl $60000,%eax
+.L01:
+ pushl %eax
+ fildl (%esp)
+ fdivs intwindiv
+ fimull 24(%esp)
+ popl %eax
+ fsts decwin(,%ecx,4)
+ fstps decwin+64(,%ecx,4)
+.L02:
+ leal -1(%esi),%edx
+ and %ebx,%edx
+ cmp $31,%edx
+ jnz .L03
+ addl $-1023,%ecx
+ test %esi,%ebx
+ jz .L03
+ negl 20(%esp)
+.L03:
+ addl %esi,%ecx
+ addl (%esp),%edi
+ incl %ebx
+ cmpl $intwinbase,%edi
+ jz .L04
+ cmp $256,%ebx
+ jnz .L00
+ negl (%esp)
+ jmp .L00
+.L04:
+ popl %eax
+
+ xorl %ecx,%ecx
+ xorl %ebx,%ebx
+ pushl $2
+.L05:
+ cmpl $528,%ecx
+ jnc .L11
+ movswl (%edi),%eax
+ cmpl $intwinbase+444,%edi
+ jc .L06
+ addl $60000,%eax
+.L06:
+ cltd
+ imull 20(%esp)
+ shrdl $17,%edx,%eax
+ cmpl $32767,%eax
+ movl $1055,%edx
+ jle .L07
+ movl $32767,%eax
+ jmp .L08
+.L07:
+ cmpl $-32767,%eax
+ jge .L08
+ movl $-32767,%eax
+.L08:
+ cmpl $512,%ecx
+ jnc .L09
+ subl %ecx,%edx
+ movw %ax,decwins(,%edx,2)
+ movw %ax,decwins-32(,%edx,2)
+.L09:
+ testl $1,%ecx
+ jnz .L10
+ negl %eax
+.L10:
+ movw %ax,decwins(,%ecx,2)
+ movw %ax,decwins+32(,%ecx,2)
+.L11:
+ leal -1(%esi),%edx
+ and %ebx,%edx
+ cmp $31,%edx
+ jnz .L12
+ addl $-1023,%ecx
+ test %esi,%ebx
+ jz .L12
+ negl 20(%esp)
+.L12:
+ addl %esi,%ecx
+ addl (%esp),%edi
+ incl %ebx
+ cmpl $intwinbase,%edi
+ jz .L13
+ cmp $256,%ebx
+ jnz .L05
+ negl (%esp)
+ jmp .L05
+.L13:
+ popl %eax
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
diff --git a/mpg123_artsplugin/mpg123/vbrhead.c b/mpg123_artsplugin/mpg123/vbrhead.c
new file mode 100644
index 00000000..f77ab279
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/vbrhead.c
@@ -0,0 +1,79 @@
+/*
+ * This checks for the VBR Header defined by Xing(tm)
+ */
+
+#include "mpg123.h"
+
+static unsigned long get32bits(unsigned char *buf) {
+ unsigned long ret = 0;
+
+ ret = (((unsigned long) buf[0]) << 24) |
+ (((unsigned long) buf[1]) << 16) |
+ (((unsigned long) buf[2]) << 8) |
+ ((unsigned long) buf[3]) ;
+
+ return ret;
+}
+
+int getVBRHeader(struct vbrHeader *head,unsigned char *buf, struct frame *fr)
+{
+ int ssize;
+
+ if(fr->lay != 3)
+ return 0;
+
+ if(fr->lsf)
+ ssize = (fr->stereo == 1) ? 9 : 17;
+ else
+ ssize = (fr->stereo == 1) ? 17 : 32;
+
+
+ buf += ssize;
+
+ if(( buf[0] != 'X' ) || ( buf[1] != 'i' ) ||
+ ( buf[2] != 'n' ) || ( buf[3] != 'g' ) )
+ return 0;
+ buf+=4;
+
+ head->flags = get32bits(buf);
+ buf+=4;
+
+ if(head->flags & VBR_FRAMES_FLAG) {
+ head->frames = get32bits(buf);
+ buf += 4;
+ }
+
+ if(head->flags & VBR_BYTES_FLAG) {
+ head->bytes = get32bits(buf);
+ buf += 4;
+ }
+
+ if(head->flags & VBR_TOC_FLAG) {
+ memcpy(head->toc,buf,100);
+ buf += 100;
+ }
+
+ if(head->flags & VBR_SCALE_FLAG) {
+ head->scale = get32bits(buf);
+ buf += 4;
+ }
+
+ fprintf(stderr,"Found XING %04lx\n",head->flags);
+
+ return 1;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mpg123_artsplugin/mpg123/xfermem.c b/mpg123_artsplugin/mpg123/xfermem.c
new file mode 100644
index 00000000..8e43dab4
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/xfermem.c
@@ -0,0 +1,275 @@
+/*
+ * xfermem.c
+ *
+ * Oliver Fromme <oliver.fromme@heim3.tu-clausthal.de>
+ * Sun Apr 6 02:26:26 MET DST 1997
+ *
+ * See xfermem.h for documentation/description.
+ */
+
+#ifndef NOXFERMEM
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+
+#ifdef AIX
+#include <sys/select.h>
+#endif
+
+#include "mpg123.h"
+
+#ifndef USE_MMAP
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif
+
+extern int errno;
+
+#if defined (USE_MMAP) && defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
+#define MAP_ANON MAP_ANONYMOUS
+#endif
+
+void xfermem_init (txfermem **xf, int bufsize, int msize, int skipbuf)
+{
+ int regsize = bufsize + msize + skipbuf + sizeof(txfermem);
+ extern int preload;
+
+#ifdef USE_MMAP
+# ifdef MAP_ANON
+ if ((*xf = (txfermem *) mmap(0, regsize, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_SHARED, -1, 0)) == (txfermem *) -1) {
+ perror ("mmap()");
+ exit (1);
+ }
+# else
+ int devzero;
+ if ((devzero = open("/dev/zero", O_RDWR, 0)) == -1) {
+ perror ("open(/dev/zero)");
+ exit (1);
+ }
+ if ((*xf = (txfermem *) mmap(0, regsize, PROT_READ | PROT_WRITE,
+ MAP_SHARED, devzero, 0)) == (txfermem *) -1) {
+ perror ("mmap()");
+ exit (1);
+ }
+ close (devzero);
+# endif
+#else
+ struct shmid_ds shmemds;
+ int shmemid;
+ if ((shmemid = shmget(IPC_PRIVATE, regsize, IPC_CREAT | 0600)) == -1) {
+ perror ("shmget()");
+ exit (1);
+ }
+ if ((*xf = (txfermem *) shmat(shmemid, 0, 0)) == (txfermem *) -1) {
+ perror ("shmat()");
+ shmctl (shmemid, IPC_RMID, &shmemds);
+ exit (1);
+ }
+ if (shmctl(shmemid, IPC_RMID, &shmemds) == -1) {
+ perror ("shmctl()");
+ xfermem_done (*xf);
+ exit (1);
+ }
+#endif
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, (*xf)->fd) < 0) {
+ perror ("socketpair()");
+ xfermem_done (*xf);
+ exit (1);
+ }
+ (*xf)->freeindex = (*xf)->readindex = 0;
+ (*xf)->wakeme[0] = (*xf)->wakeme[1] = FALSE;
+ (*xf)->data = ((byte *) *xf) + sizeof(txfermem) + msize;
+ (*xf)->metadata = ((byte *) *xf) + sizeof(txfermem);
+ (*xf)->size = bufsize;
+ (*xf)->metasize = msize + skipbuf;
+ preload = bufsize>>3;
+}
+
+void xfermem_done (txfermem *xf)
+{
+ if(!xf)
+ return;
+#ifdef USE_MMAP
+ munmap ((caddr_t) xf, xf->size + xf->metasize + sizeof(txfermem));
+#else
+ if (shmdt((void *) xf) == -1) {
+ perror ("shmdt()");
+ exit (1);
+ }
+#endif
+}
+
+void xfermem_init_writer (txfermem *xf)
+{
+ if(xf)
+ close (xf->fd[XF_READER]);
+}
+
+void xfermem_init_reader (txfermem *xf)
+{
+ if(xf)
+ close (xf->fd[XF_WRITER]);
+}
+
+int xfermem_get_freespace (txfermem *xf)
+{
+ int freeindex, readindex;
+
+ if(!xf)
+ return 0;
+
+ if ((freeindex = xf->freeindex) < 0
+ || (readindex = xf->readindex) < 0)
+ return (0);
+ if (readindex > freeindex)
+ return ((readindex - freeindex) - 1);
+ else
+ return ((xf->size - (freeindex - readindex)) - 1);
+}
+
+int xfermem_get_usedspace (txfermem *xf)
+{
+ int freeindex, readindex;
+
+ if(!xf)
+ return 0;
+
+ if ((freeindex = xf->freeindex) < 0
+ || (readindex = xf->readindex) < 0)
+ return (0);
+ if (freeindex >= readindex)
+ return (freeindex - readindex);
+ else
+ return (xf->size - (readindex - freeindex));
+}
+
+int xfermem_getcmd (int fd, int block)
+{
+ fd_set selfds;
+ byte cmd;
+
+ for (;;) {
+ struct timeval selto = {0, 0};
+
+ FD_ZERO (&selfds);
+ FD_SET (fd, &selfds);
+ /* #ifdef HPUX */ /* seems to trigger performance problems? strange */
+#if 0
+ switch (select(FD_SETSIZE, (int *) &selfds, NULL, NULL, block ? NULL : &selto)) {
+#else
+ switch (select(FD_SETSIZE, &selfds, NULL, NULL, block ? NULL : &selto)) {
+#endif
+ case 0:
+ if (!block)
+ return (0);
+ continue;
+ case -1:
+ if (errno == EINTR)
+ continue;
+ return (-2);
+ case 1:
+ if (FD_ISSET(fd, &selfds))
+ switch (read(fd, &cmd, 1)) {
+ case 0: /* EOF */
+ return (-1);
+ case -1:
+ if (errno == EINTR)
+ continue;
+ return (-3);
+ case 1:
+ return (cmd);
+ default: /* ?!? */
+ return (-4);
+ }
+ else /* ?!? */
+ return (-5);
+ default: /* ?!? */
+ return (-6);
+ }
+ }
+}
+
+int xfermem_putcmd (int fd, byte cmd)
+{
+ for (;;) {
+ switch (write(fd, &cmd, 1)) {
+ case 1:
+ return (1);
+ case -1:
+ if (errno != EINTR)
+ return (-1);
+ }
+ }
+}
+
+int xfermem_block (int readwrite, txfermem *xf)
+{
+ int myfd = xf->fd[readwrite];
+ int result;
+
+ xf->wakeme[readwrite] = TRUE;
+ if (xf->wakeme[1 - readwrite])
+ xfermem_putcmd (myfd, XF_CMD_WAKEUP);
+ result = xfermem_getcmd(myfd, TRUE);
+ xf->wakeme[readwrite] = FALSE;
+ return ((result <= 0) ? -1 : result);
+}
+
+#elif defined(WIN32)
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include "mpg123.h"
+
+extern int errno;
+
+void xfermem_init (txfermem **xf, int bufsize, int msize, int skipbuf)
+{
+}
+void xfermem_done (txfermem *xf)
+{
+}
+void xfermem_init_writer (txfermem *xf)
+{
+}
+void xfermem_init_reader (txfermem *xf)
+{
+}
+int xfermem_get_freespace (txfermem *xf)
+{
+ return 0;
+}
+int xfermem_get_usedspace (txfermem *xf)
+{
+ return 0;
+}
+int xfermem_getcmd (int fd, int block)
+{
+ return 0;
+}
+int xfermem_putcmd (int fd, byte cmd)
+{
+ return 0;
+}
+int xfermem_block (int readwrite, txfermem *xf)
+{
+ return 0;
+}
+#endif
+
+/* eof */
+
diff --git a/mpg123_artsplugin/mpg123/xfermem.h b/mpg123_artsplugin/mpg123/xfermem.h
new file mode 100644
index 00000000..ae7e5afd
--- /dev/null
+++ b/mpg123_artsplugin/mpg123/xfermem.h
@@ -0,0 +1,60 @@
+/*
+ * xfermem.h
+ *
+ * Oliver Fromme <oliver.fromme@heim3.tu-clausthal.de>
+ * Sat Mar 29 04:41:34 MET 1997
+ *
+ * This is a stand-alone module which implements a unidirectional,
+ * fast pipe using mmap(). Its primary use is to transfer large
+ * amounts of data from a parent process to its child process,
+ * with a buffer in between which decouples blocking conditions
+ * on both sides. Control information is transferred between the
+ * processes through a socketpair. See xftest.c for an example on
+ * how to use this module.
+ */
+
+#ifndef TRUE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+typedef struct {
+ int freeindex; /* [W] next free index */
+ int readindex; /* [R] next index to read */
+ int fd[2];
+ int wakeme[2];
+ byte *data;
+ byte *metadata;
+ int size;
+ int metasize;
+ int buf[3];
+} txfermem;
+/*
+ * [W] -- May be written to by the writing process only!
+ * [R] -- May be written to by the reading process only!
+ * All other entries are initialized once.
+ */
+
+void xfermem_init (txfermem **xf, int bufsize, int msize,int skipbuf);
+void xfermem_init_writer (txfermem *xf);
+void xfermem_init_reader (txfermem *xf);
+
+int xfermem_write (txfermem *xf, byte *data, int count);
+int xfermem_read (txfermem *xf, byte *data, int count);
+
+int xfermem_get_freespace (txfermem *xf);
+int xfermem_get_usedspace (txfermem *xf);
+#define XF_CMD_WAKEUP_INFO 0x04
+#define XF_CMD_WAKEUP 0x02
+#define XF_CMD_TERMINATE 0x03
+#define XF_WRITER 0
+#define XF_READER 1
+int xfermem_getcmd (int fd, int block);
+int xfermem_putcmd (int fd, byte cmd);
+int xfermem_block (int fd, txfermem *xf);
+
+void xfermem_done (txfermem *xf);
+#define xfermem_done_writer xfermem_init_reader
+#define xfermem_done_reader xfermem_init_writer
+
+/* EOF */
diff --git a/mpg123_artsplugin/mpg123PlayObject.mcopclass b/mpg123_artsplugin/mpg123PlayObject.mcopclass
new file mode 100644
index 00000000..24f3f8cf
--- /dev/null
+++ b/mpg123_artsplugin/mpg123PlayObject.mcopclass
@@ -0,0 +1,6 @@
+Interface=Arts::mpg123PlayObject,Arts::PlayObject,Arts::SynthModule,Arts::Object
+Library=libmpg123arts.la
+Author=Kevin Puetz <puetzk@iastate.edu>
+Extension=mp3,mp1,mp2
+Language=C++
+MimeType=audio/x-mp3,audio/x-mp1,audio/x-mp2
diff --git a/mpg123_artsplugin/mpg123PlayObject_impl.cpp b/mpg123_artsplugin/mpg123PlayObject_impl.cpp
new file mode 100644
index 00000000..29ab5dcf
--- /dev/null
+++ b/mpg123_artsplugin/mpg123PlayObject_impl.cpp
@@ -0,0 +1,675 @@
+/*
+ * $Id$
+ * Copyright (C) 2001 Kevin Puetz
+ *
+ *
+ * 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-1307, USA.
+ *
+ */
+
+#include <config.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/stat.h>
+#include <sys/shm.h>
+#include <sys/wait.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <math.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/////////////////////////////////////////////////////////////
+// aRts interface
+
+#include <stdsynthmodule.h>
+#include "mpg123arts.h"
+#include <convert.h>
+#include <debug.h>
+
+
+#include "mpg123PlayObject_impl.h"
+
+using namespace Arts;
+
+int mpg123PlayObject_impl::decoder_init = 0;
+
+// This is to minimize the hackery in mpg123
+int audio_get_formats(struct audio_info_struct *)
+{
+ return AUDIO_FORMAT_SIGNED_16;
+}
+
+// This is purely convenience
+void mpg123PlayObject_impl::set_synth_functions(struct frame *fr)
+{
+ typedef int (*func)(real *,int,unsigned char *,int *);
+ typedef int (*func_mono)(real *,unsigned char *,int *);
+ typedef void (*func_dct36)(real *,real *,real *,real *,real *);
+
+ int ds = fr->down_sample;
+ int p8=0;
+ // it's as big as pcmdata (internal to mpg123 - where this size comes from I dunno
+ // but it'll be big enough, since all data comes as memcpy's from there.
+
+ static func funcs[][4] = {
+ { synth_1to1,
+ synth_2to1,
+ synth_4to1,
+ synth_ntom } ,
+ { synth_1to1_8bit,
+ synth_2to1_8bit,
+ synth_4to1_8bit,
+ synth_ntom_8bit }
+#ifdef USE_3DNOW
+ ,{synth_1to1_3dnow,
+ synth_2to1,
+ synth_4to1,
+ synth_ntom }
+#endif
+ };
+
+ static func_mono funcs_mono[2][2][4] = {
+ { { synth_1to1_mono2stereo ,
+ synth_2to1_mono2stereo ,
+ synth_4to1_mono2stereo ,
+ synth_ntom_mono2stereo } ,
+ { synth_1to1_8bit_mono2stereo ,
+ synth_2to1_8bit_mono2stereo ,
+ synth_4to1_8bit_mono2stereo ,
+ synth_ntom_8bit_mono2stereo } } ,
+ { { synth_1to1_mono ,
+ synth_2to1_mono ,
+ synth_4to1_mono ,
+ synth_ntom_mono } ,
+ { synth_1to1_8bit_mono ,
+ synth_2to1_8bit_mono ,
+ synth_4to1_8bit_mono ,
+ synth_ntom_8bit_mono } }
+ };
+
+#ifdef USE_3DNOW
+ static func_dct36 funcs_dct36[2] = {dct36 , dct36_3dnow};
+#endif
+
+ if (0) // ((ai.format & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_8)
+ p8 = 1;
+ fr->synth = funcs[p8][ds];
+ fr->synth_mono = funcs_mono[param.force_stereo?0:1][p8][ds];
+
+#ifdef USE_3DNOW
+ arts_debug("set_synth_functions: 3dnow?");
+ /* check cpuflags bit 31 (3DNow!) and 23 (MMX) */
+ if((param.stat_3dnow < 2) &&
+ ((param.stat_3dnow == 1) ||
+ (getcpuflags() & 0x80800000) == 0x80800000))
+ {
+ fr->synth = funcs[2][ds]; /* 3DNow! optimized synth_1to1() */
+ fr->dct36 = funcs_dct36[1]; /* 3DNow! optimized dct36() */
+ } else {
+ fr->dct36 = funcs_dct36[0];
+ }
+#endif
+
+ if (p8)
+ {
+ make_conv16to8_table(-1); // FIX
+ }
+}
+
+void mpg123PlayObject_impl::initialise_decoder()
+{
+ arts_debug("initializing decoder");
+ set_synth_functions(&mp->fr);
+ make_decode_tables(param.outscale);
+ init_layer2(); // inits also shared tables with layer1
+ init_layer3(mp->fr.down_sample); // No down sample support (yet?)
+}
+
+int mpg123PlayObject_impl::play_frame(int init)
+{
+ struct frame *fr = &mp->fr;
+ int clip;
+ long newrate;
+ long old_rate,old_format,old_channels;
+
+ if(fr->header_change || init) {
+
+ if(fr->header_change > 1 || init) {
+ old_rate = ai.rate;
+ old_format = ai.format;
+ old_channels = ai.channels;
+
+ newrate = (long)param.pitch * (freqs[fr->sampling_frequency]>>(param.down_sample));
+ if(param.verbose && param.pitch != 1.0)
+ fprintf(stderr,"Pitching to %f => %ld Hz\n",param.pitch,newrate);
+
+ fr->down_sample = param.down_sample;
+
+ ai.format = AUDIO_FORMAT_SIGNED_16;
+ ai.rate = 44100;
+ ai.channels = 2;
+
+ /* check, whether the fitter setted our proposed rate */
+ if(ai.rate != newrate) {
+ arts_debug("resampling from %d to %d",newrate, ai.rate);
+ if(ai.rate == (newrate>>1) )
+ fr->down_sample++;
+ else if(ai.rate == (newrate>>2) )
+ fr->down_sample+=2;
+ else {
+ fr->down_sample = 3;
+ fprintf(stderr,"Warning, flexible rate not heavily tested!\n");
+ }
+ if(fr->down_sample > 3)
+ fr->down_sample = 3;
+ }
+
+ if(fr->down_sample > 3)
+ fr->down_sample = 3;
+
+ switch(fr->down_sample) {
+ case 0:
+ case 1:
+ case 2:
+ fr->down_sample_sblimit = SBLIMIT>>(fr->down_sample);
+ break;
+ case 3:
+ {
+ long n = (long)param.pitch * freqs[fr->sampling_frequency];
+ long m = ai.rate;
+
+ synth_ntom_set_step(n,m);
+
+ if(n>m) {
+ fr->down_sample_sblimit = SBLIMIT * m;
+ fr->down_sample_sblimit /= n;
+ }
+ else {
+ fr->down_sample_sblimit = SBLIMIT;
+ }
+ }
+ break;
+ }
+
+ set_synth_functions(fr);
+ //init_output(); XXX: eh?
+ if(ai.rate != old_rate || ai.channels != old_channels ||
+ ai.format != old_format || param.force_reopen) {
+ if(param.force_mono < 0) {
+ if(ai.channels == 1)
+ fr->single = 3;
+ else
+ fr->single = -1;
+ }
+ }
+ else
+ fr->single = param.force_mono;
+
+ param.force_stereo &= ~0x2;
+ if(fr->single >= 0 && ai.channels == 2) {
+ param.force_stereo |= 0x2;
+ }
+
+ set_synth_functions(fr);
+ init_layer3(fr->down_sample_sblimit);
+ // reset_audio(); XXX: wha?
+ if(param.verbose) {
+ if(fr->down_sample == 3) {
+ long n = (long)param.pitch * freqs[fr->sampling_frequency];
+ long m = ai.rate;
+ if(n > m) {
+ fprintf(stderr,"Audio: %2.4f:1 conversion,",(float)n/(float)m);
+ }
+ else {
+ fprintf(stderr,"Audio: 1:%2.4f conversion,",(float)m/(float)n);
+ }
+ }
+ else {
+ fprintf(stderr,"Audio: %ld:1 conversion,",(long)pow(2.0,fr->down_sample));
+ }
+ fprintf(stderr," rate: %ld, encoding: %s, channels: %d\n",ai.rate,audio_encoding_name(ai.format),ai.channels);
+ }
+ }
+ }
+
+ if (fr->error_protection) {
+ /* skip crc, we are byte aligned here */
+ getbyte(&bsi);
+ getbyte(&bsi);
+ }
+
+ /* do the decoding */
+ switch(fr->lay) {
+ case 1:
+ if( (clip=do_layer1(mp,fr,param.outmode,&ai)) < 0 )
+ return 0;
+ break;
+ case 2:
+ if( (clip=do_layer2(mp,fr,param.outmode,&ai)) < 0 )
+ return 0;
+ break;
+ case 3:
+ if( (clip=do_layer3(mp,fr,param.outmode,&ai)) < 0 )
+ return 0;
+ break;
+ default:
+ clip = 0;
+ }
+
+ if(clip > 0 && param.checkrange)
+ fprintf(stderr,"%d samples clipped\n", clip);
+
+ return pcm_point / 4;
+}
+
+mpg123PlayObject_impl::mpg123PlayObject_impl()
+{
+ pcm_buf = new unsigned char[16384*2+1024*2];
+ mp = (struct mpstr *)malloc(sizeof(struct mpstr));
+ memset(mp, 0, sizeof(struct mpstr));
+ //memset(&mp->fr, 0, sizeof(struct frame)); XXX: why would I need to do this?
+
+ prgName = strdup("arts/mpg123");
+ prgVersion = strdup("$Revision$");
+ pcm_point = 0;
+ pcm_sample=pcm_buf; // just point this to our internal buffer
+ memset(&param, 0, sizeof(struct parameter));
+ param.halfspeed = 0;
+ param.outmode = DECODE_BUFFER+999;
+ param.usebuffer = 0;
+ param.down_sample = 0;
+ param.force_stereo = 1; // XXX was 0
+ param.force_mono = -1;
+ param.pitch = 1.0;
+ param.checkrange = 0;
+ param.outscale = 32768;
+ param.tryresync = 2;
+
+ equalfile = NULL;
+ struct shmid_ds bleh;
+ shm_id = shmget(IPC_PRIVATE, sizeof(*shm_buf), 0600);
+ shm_buf = (struct buf_t *)shmat(shm_id, 0, 0);
+ // mark it to be destroyed after the last detach
+ shmctl(shm_id, IPC_RMID, &bleh);
+ // sem0 has base, sem1 remaining space,sem2 seekTo
+ buflen_sem = semget(IPC_PRIVATE, 3, 0600);
+ child_pid = 0;
+}
+
+mpg123PlayObject_impl::~mpg123PlayObject_impl()
+{
+ artsdebug("Destroying PlayObject");
+ halt();
+ union semun semdat;
+ arts_debug("removing IPC resources");
+ semctl(buflen_sem,0,IPC_RMID,semdat);
+ // WABA: Don't remove the cast, it is needed on some platforms.
+ shmdt((char *)shm_buf);
+ delete pcm_buf;
+}
+
+bool mpg123PlayObject_impl::loadMedia(const string &filename)
+{
+// string filename = "http://131.174.33.2:9024/";
+ arts_debug("mpg123: loadMedia %s", filename.c_str());
+ halt(); // stop playing any previous stream
+ arts_debug("previous playback killed");
+ struct sembuf semoper;
+ union semun semdat;
+
+ semoper.sem_flg = 0; // normal blocking semaphores
+
+ semdat.val = 0;
+ if(semctl(buflen_sem,0,SETVAL,semdat)) // no data in the queue
+ arts_debug("couldn't clear queue");
+ semdat.val = 0;
+ if(semctl(buflen_sem,2,SETVAL,semdat)) // seekTo is -1 (ie, no seek)
+ arts_debug("couldn't clear seekTo");
+ semdat.val = BACKBUFSIZ;
+ if(semctl(buflen_sem,1,SETVAL,semdat)) // setup the starting free space
+ arts_debug("couldn't mark buffer empty");
+
+ buf_pos = 0;
+
+ //throw off a process to handle the decoding
+ if((child_pid = fork())) {
+ return true; // all further setup happens in the child
+ }
+ arts_debug("child process");
+ initialise_decoder();
+
+ snprintf(param.filename, 250, filename.c_str());
+ memset(&ai, 0, sizeof(struct audio_info_struct));
+ mp->fr.sampling_frequency = 0;
+ mp->fr.down_sample = 0;
+ mp->fr.single = -1;
+ mp->fr.down_sample_sblimit = SBLIMIT>>(mp->fr.down_sample);
+ sample_freq = freqs[mp->fr.sampling_frequency]>>(param.down_sample);
+
+ // audio_info_struct_init
+ ai.rate = 44100;
+ ai.gain = -1;
+ ai.output = AUDIO_OUT_LINE_OUT;
+ ai.device = 0;
+ ai.channels = 2;
+ ai.format = AUDIO_FORMAT_SIGNED_16;
+ audio_capabilities(&ai);
+
+ set_synth_functions(&mp->fr);
+
+ if (rd)
+ rd->close(rd);
+ if (!open_stream(filename.c_str(), -1)) {
+ printf("erorr opening stream\n");
+ return 0;
+ }
+
+ mpeg_name[0] = 0;
+ snprintf(mpeg_name, 1000, filename.c_str());
+ if (strstr(filename.c_str(), "http://") != NULL) {
+ sprintf(mpeg_name, "ShoutCast from %s\n", filename.c_str());
+ streaming = 1;
+ }
+
+ read_frame_init(&mp->fr);
+
+ XHEADDATA xingHeader;
+
+ shm_buf->pos = 0;
+
+ read_frame(rd,&mp->fr); // read in a frame for the xing code to play with
+ bool gotXing = false;
+ if(!streaming) {
+ gotXing = mpg123_stream_check_for_xing_header(&mp->fr,&xingHeader);
+ if(gotXing)
+ shm_buf->len = xingHeader.frames;
+ else // assume no VBR for non-Xing
+ shm_buf->len = static_cast<unsigned long>(rd->filelen / compute_bpf(&mp->fr));
+ } else {
+ shm_buf->len = 1;
+ }
+ // can't calculate tpf until we reach a non-header frame
+
+ int skipped = 0;
+ if (sync_stream(rd, &mp->fr, 0xffff, &skipped) <= 0) {
+ fprintf(stderr,"Can't find frame start");
+ rd->close(rd);
+ return 0;
+ }
+
+
+/*
+ if (!mpeg_get_frame_info(filename.c_str())) {
+ printf("mpeg_get_frame_info(%s) failed\n", filename.c_str());
+ return 0;
+ }
+*/
+ arts_debug("mpg123: loadMedia %s got %s", filename.c_str(), mpeg_name);
+
+ short *decode_buf = reinterpret_cast<short *>(pcm_sample);
+ bool init=true;
+ do {
+ // get more data
+
+ int seekTo = semctl(buflen_sem, 2, GETVAL, semdat);
+ if (seekTo) { // we need to seek, to sync back up
+ unsigned long offset;
+ arts_debug("seeking to %d\n", seekTo);
+ if(gotXing && (xingHeader.flags & TOC_FLAG) && xingHeader.toc) // do we have a table of contents?
+ offset = mpg123_seek_point(xingHeader.toc,rd->filelen,100 * (seekTo -1) / double(shm_buf->len)); // relative position in file
+ else
+ offset = static_cast<unsigned long>(rd->filelen * ((seekTo-1) / double(shm_buf->len))); // the crude ole' fashioned way
+ rd->rewind(rd);
+ lseek(rd->filept, offset, SEEK_SET);
+
+ // now we need to sync back up :-)
+ read_frame(rd,&mp->fr);
+ read_frame(rd,&mp->fr);
+ // if (sync_stream(rd, &mp->fr, 0xffff, &skipped) <= 0) {
+ // arts_debug("Can't find frame start");
+ // rd->close(rd);
+ // break;
+ // }
+ shm_buf->pos = seekTo; // assume we got the frame we were after? I don't have a better idea...
+ semdat.val = 0;
+ semctl(buflen_sem, 2, SETVAL, semdat); // we've done it
+ }
+
+ if (!read_frame(rd,&mp->fr)) {
+ // mpg123 says we're done, or we errored (in which case we're done)
+ arts_debug("out of frames, exiting");
+ break;
+ }
+
+ if(init) // need to figure this one out with a real audio frame...
+ {
+ arts_debug("samplerate: %d (%d)",mp->fr.sampling_frequency,freqs[mp->fr.sampling_frequency]>>(param.down_sample));
+ shm_buf->tpf = compute_tpf(&mp->fr);
+ }
+ int thisPass = play_frame(init);
+ if(init) // need to figure this one out with a real audio frame...
+ arts_debug("samplerate: %d",mp->fr.sampling_frequency);
+ init=false; // no longer init :-)
+
+ semoper.sem_num = 1;
+ semoper.sem_op = -thisPass;
+ semop(buflen_sem, &semoper, 1);
+
+ // block until there's enough space to stick in this frame
+ int roomFor = semctl(buflen_sem, 1, GETVAL, semdat);
+ if (roomFor > BACKBUFSIZ) {
+ arts_debug("exit requested (%d slots available), bye!",roomFor);
+ // this can never go above BACKBUFSIZ in normal operation,
+ // the consumer wants us to exit
+ break;
+ }
+
+ //arts_debug("decoded %d frames (%d avail)",thisPass,roomFor);
+
+ for(int i=0 ; i <thisPass ;
+ ++i, buf_pos = ((buf_pos + 1) % BACKBUFSIZ)) {
+ shm_buf->left[buf_pos] = conv_16le_float(decode_buf[2*i]);
+ shm_buf->right[buf_pos] = conv_16le_float(decode_buf[2*i+1]);
+ }
+ shm_buf->pos++; // ran another frame through the mill
+ pcm_point=0;
+ //arts_debug("enqueued them");
+ semoper.sem_num = 0;
+ semoper.sem_op = thisPass;
+ semop(buflen_sem,&semoper,1); // mark the additional data now available
+
+ //arts_debug("calculated %d more samples",shm_buf->backbuflen );
+ } while(1);
+
+ //signal completion
+ semdat.val = 0;
+ // no more data available
+ semctl(buflen_sem, 0, SETVAL, semdat);
+ // and no room either (ie, none coming)
+ semctl(buflen_sem, 1, SETVAL, semdat);
+
+ arts_debug("decoder process exiting");
+ exit(0);
+ return true;
+}
+
+string mpg123PlayObject_impl::description()
+{
+ return "mpg123 artsplug - w00t!";
+}
+
+//XXX
+poTime mpg123PlayObject_impl::currentTime()
+{
+ return poTime(shm_buf->pos * shm_buf->tpf, 0, 0, "none");
+}
+
+//XXX
+poTime mpg123PlayObject_impl::overallTime()
+{
+ return poTime(shm_buf->len * shm_buf->tpf, 0, 0, "none");
+}
+
+poCapabilities mpg123PlayObject_impl::capabilities()
+{
+ return static_cast<poCapabilities>(capPause | capSeek);
+}
+
+//YYY
+string mpg123PlayObject_impl::mediaName()
+{
+ return param.filename;
+}
+
+poState mpg123PlayObject_impl::state()
+{
+ return mState;
+}
+
+void mpg123PlayObject_impl::play()
+{
+ arts_debug("mpg123: play");
+ mState = posPlaying;
+}
+
+void mpg123PlayObject_impl::halt()
+{
+ mState = posIdle;
+ union semun semdat;
+
+ if (child_pid) {
+ arts_debug("killing decoder process");
+ semdat.val = 2*BACKBUFSIZ;
+ semctl(buflen_sem, 1, SETVAL, semdat);
+ waitpid(child_pid, NULL, 0);
+ child_pid = 0;
+ }
+ // tell the producer to exit (would also result in us halting, if we weren't already)
+
+ // mainly this is to ensure that the decoder wakes up to notice
+}
+
+//XXX disabled for now
+void mpg123PlayObject_impl::seek(const class poTime &t)
+{
+ union semun foo;
+
+ // this index is one-based so 0 can represent no seek
+ foo.val = static_cast<int>(t.seconds / shm_buf->tpf + 1);
+ arts_debug("requesting seek to %d", foo.val);
+ semctl(buflen_sem, 2, SETVAL, foo); // we've done it
+}
+
+/* Pause implemented on the streaming-side - decoding will simply block on it's own */
+void mpg123PlayObject_impl::pause()
+{
+ mState = posPaused;
+}
+
+/*
+ * SynthModule interface
+ * - where is stop? initialize?
+ */
+
+void mpg123PlayObject_impl::streamInit()
+{
+ arts_debug("streamInit");
+}
+
+void mpg123PlayObject_impl::streamStart()
+{
+ arts_debug("streamStart");
+}
+
+void mpg123PlayObject_impl::calculateBlock(unsigned long samples)
+{
+ int samplesAvailable = 0;
+
+ //arts_debug("calculateBlock");
+
+ if (mState==posPlaying) {
+ //arts_debug("calculateBlock, %d(%d) of %d samples in buffer",
+ //shm_buf->buflen - bufpos, shm_buf->backbuflen,samples);
+
+ struct sembuf bleh;
+
+ bleh.sem_num = 0;
+ bleh.sem_flg = IPC_NOWAIT;
+
+ //arts_debug("%d samples wanted", samplesAvailable);
+ bleh.sem_op = -samples; // does the buffer have sufficient samples?
+ if (semop(buflen_sem, &bleh, 1) == -1) {
+ if (errno == EAGAIN) {
+ union semun semdat;
+ arts_debug("buffer underrun");
+// samplesAvailable = semctl(buflen_sem,0,GETVAL,semdat);
+// if (semctl(buflen_sem, 1, GETVAL, semdat) == 0) {
+// samplesAvailable = semctl(buflen_sem,0,GETVAL,semdat);
+ if ((semctl(buflen_sem, 1, GETVAL, semdat) == 0) && (semctl(buflen_sem,0,GETVAL,semdat) == 0))
+ {
+ arts_debug("decoder requested exit");
+ // no samples AND no room is the decoder's way of signalling completion
+ halt();
+ // samplesAvailable = 0;
+ }
+ samplesAvailable = 0; //
+ } else {
+ arts_debug("something awful happened to our semaphores...");
+ // something awful has happened
+ halt();
+ samplesAvailable = 0;
+ }
+ } else {
+ samplesAvailable = samples; // number of samples we pushed from buffers
+ // used to calculate the number we should zero out for an underrun
+ }
+ bleh.sem_flg = 0; // back to normal now
+
+ if(samplesAvailable) {
+ //arts_debug("%d samples available",samplesAvailable);
+ for (int i = 0; i < samplesAvailable;
+ ++i, buf_pos = ((buf_pos + 1) % BACKBUFSIZ)) {
+
+ left[i] = shm_buf->left[buf_pos];
+ right[i] = shm_buf->right[buf_pos];
+ }
+
+ bleh.sem_num = 1;
+ bleh.sem_op = samplesAvailable;
+ // 0 here CAN block, which is why this is in an if(samplesAvailable)
+ semop(buflen_sem, &bleh, 1); // mark the now-free space
+ }
+ }
+ // zero out any samples we didn't have enough to complete - no buzz of death!
+ while(static_cast<unsigned long>(samplesAvailable) < samples) {
+ left[samplesAvailable] = 0.0;
+ right[samplesAvailable] = 0.0;
+ samplesAvailable++;
+ }
+}
+
+void mpg123PlayObject_impl::streamEnd()
+{
+ arts_debug("streamEnd");
+}
+
+REGISTER_IMPLEMENTATION(mpg123PlayObject_impl);
+
diff --git a/mpg123_artsplugin/mpg123PlayObject_impl.h b/mpg123_artsplugin/mpg123PlayObject_impl.h
new file mode 100644
index 00000000..e8be2619
--- /dev/null
+++ b/mpg123_artsplugin/mpg123PlayObject_impl.h
@@ -0,0 +1,111 @@
+#ifndef MPG123PLAYER_IMPL_H
+#define MPG123PLAYER_IMPL_H "$Id$"
+
+using namespace std;
+
+#if (defined(__GNU_LIBRARY__) && defined(_SEM_SEMUN_UNDEFINED)) || defined(__osf__) || defined(__sun__)
+/* union semun is defined by including <sys/sem.h> */
+/* according to X/OPEN we have to define it ourselves */
+union semun {
+ int val; /* value for SETVAL */
+ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
+ unsigned short int *array; /* array for GETALL, SETALL */
+ struct seminfo *__buf; /* buffer for IPC_INFO */
+};
+#endif
+
+#define RESYNC_FRAMES 3
+
+extern "C" {
+ #include "mpg123/mpg123.h"
+ #include "dxhead.h"
+
+ // These are provided to make mpg123 happy
+ int audio_get_formats(struct audio_info_struct *ai);
+ char *equalfile;
+ struct parameter param;
+ char *prgName;
+ char *prgVersion;
+ struct audio_info_struct ai;
+
+ // We abuse these internal mpg123 objects
+ extern double compute_bpf(struct frame *fr);
+ extern double compute_tpf(struct frame *fr);
+ extern void set_pointer(int, long);
+ extern void audio_capabilities(struct audio_info_struct *);
+ extern unsigned char *pcm_sample;
+ extern int pcm_point;
+ extern int audiobufsize;
+}
+
+#define BACKBUFSIZ 8132
+
+struct id3tag {
+ char tag[3];
+ char title[30];
+ char artist[30];
+ char album[30];
+ char year[4];
+ char comment[30];
+ unsigned char genre;
+};
+
+namespace Arts {
+
+class mpg123PlayObject_impl
+ : public mpg123PlayObject_skel, public StdSynthModule
+{
+ public:
+ mpg123PlayObject_impl();
+ ~mpg123PlayObject_impl();
+ bool loadMedia(const string &filename);
+ string description();
+ poTime currentTime();
+ poTime overallTime();
+ poCapabilities capabilities();
+ string mediaName();
+ poState state();
+ void play();
+ void halt();
+ void seek(const class poTime &t);
+ void pause();
+ void streamInit();
+ void streamStart();
+ void calculateBlock(unsigned long samples);
+ void streamEnd();
+
+ protected:
+ // These are to enable seeking
+ static void stream_jump_to_frame(struct frame *fr, int frame);
+ static int calc_numframes(struct frame *);
+
+ // This is to enable playing, what else?
+ static void set_synth_functions(struct frame *fr);
+ void initialise_decoder();
+ int play_frame(int init);
+
+ inline float conv_16le_float(short x)
+ { return static_cast<float>(x) / 32768.0; }
+
+ int streaming, /*padded, cnt, junk_size, */ sample_freq /*frame_size*/;
+ char mpeg_name[FILENAME_MAX+1];
+ struct mpstr *mp;
+ static int decoder_init;
+
+ int buf_pos; // loops around the circular buffer
+ poState mState;
+ struct buf_t{
+ float left[BACKBUFSIZ];
+ float right[BACKBUFSIZ];
+ unsigned long len; // total frames
+ unsigned long pos; // last decoded frame
+ double tpf; // time per frame, seconds
+ } *shm_buf;
+ int shm_id, child_pid;
+ int buflen_sem;
+ unsigned char *pcm_buf;
+};
+
+};
+
+#endif
diff --git a/mpg123_artsplugin/mpg123arts.idl b/mpg123_artsplugin/mpg123arts.idl
new file mode 100644
index 00000000..f7ff2bc7
--- /dev/null
+++ b/mpg123_artsplugin/mpg123arts.idl
@@ -0,0 +1,12 @@
+#include <kmedia2.idl>
+#include <soundserver.idl>
+
+module Arts
+{
+
+interface mpg123PlayObject : PlayObject, SynthModule
+{
+ out audio stream left,right;
+};
+
+};