diff options
Diffstat (limited to 'mpg123_artsplugin')
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(¶m, 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; +}; + +}; |