Built SDL2_image and _mixer static

This commit is contained in:
2022-09-30 15:49:16 -04:00
parent e2605bf6c1
commit 1dec4347e0
4473 changed files with 1964551 additions and 9 deletions

View File

@ -0,0 +1,141 @@
# Module for non-recursive mpg123 build system.
include src/compat/Makemodule.am
include src/libmpg123/Makemodule.am
include src/libout123/Makemodule.am
bin_PROGRAMS += \
src/mpg123 \
src/out123 \
src/mpg123-id3dump \
src/mpg123-strip
src_mpg123_LDADD = \
src/compat/libcompat.la \
src/libmpg123/libmpg123.la \
src/libout123/libout123.la \
$(LIBM)
src_mpg123_LDFLAGS = @EXEC_LT_LDFLAGS@
src_out123_LDADD = \
src/compat/libcompat.la \
src/libout123/libout123.la
src_out123_LDFLAGS = @EXEC_LT_LDFLAGS@
EXTRA_DIST += \
src/intsym.h \
src/mpg123-with-modules \
src/out123-with-modules
CLEANFILES += src/*.a
src_mpg123_id3dump_LDADD = \
src/compat/libcompat.la \
src/libmpg123/libmpg123.la
src_mpg123_strip_LDADD = \
src/compat/libcompat.la \
src/libmpg123/libmpg123.la
EXTRA_PROGRAMS += \
src/tests/seek_whence \
src/tests/noise \
src/tests/text \
src/tests/plain_id3
src_mpg123_SOURCES = \
src/audio.c \
src/audio.h \
src/common.c \
src/common.h \
src/sysutil.c \
src/sysutil.h \
src/control_generic.c \
src/equalizer.c \
src/getlopt.c \
src/getlopt.h \
src/httpget.c \
src/httpget.h \
src/resolver.c \
src/resolver.h \
src/genre.h \
src/genre.c \
src/mpg123.c \
src/mpg123app.h \
src/metaprint.c \
src/metaprint.h \
src/local.h \
src/local.c \
src/playlist.c \
src/playlist.h \
src/streamdump.h \
src/streamdump.c \
src/term.c \
src/term.h \
src/win32_support.h
# Does that finally work to build/link the correct object file?
src_mpg123_SOURCES +=
# Replace common.h by sysutil.h!
src_out123_SOURCES = \
src/sysutil.c \
src/sysutil.h \
src/waves.c \
src/waves.h \
src/common.h \
src/getlopt.c \
src/getlopt.h \
src/out123.c \
src/mpg123app.h \
src/win32_support.h
src_mpg123_id3dump_SOURCES = \
src/mpg123-id3dump.c \
src/getlopt.c \
src/getlopt.h
src_mpg123_strip_SOURCES = \
src/mpg123-strip.c \
src/getlopt.c \
src/getlopt.h
if WIN32_CODES
src_mpg123_SOURCES += \
src/win32_support.c \
src/win32_net.c
src_out123_SOURCES+= \
src/win32_support.c
src_mpg123_id3dump_SOURCES += \
src/win32_support.c
endif
src_tests_seek_whence_SOURCES = \
src/tests/seek_whence.c
src_tests_seek_whence_LDADD = \
src/compat/libcompat.la \
src/libmpg123/libmpg123.la
src_tests_noise_SOURCES = \
src/tests/noise.c \
src/libmpg123/dither.h \
src/libmpg123/dither_impl.h
src_tests_noise_LDADD = \
src/compat/libcompat.la
src_tests_text_SOURCES = \
src/tests/text.c \
src/tests/testtext.h
src_tests_text_LDADD = \
src/compat/libcompat.la \
src/libmpg123/libmpg123.la
src_tests_plain_id3_SOURCES = \
src/tests/plain_id3.c
src_tests_plain_id3_LDADD = \
src/compat/libcompat.la \
src/libmpg123/libmpg123.la

View File

@ -0,0 +1,241 @@
/*
audio: audio output interface
copyright ?-2016 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
#include <errno.h>
#include "mpg123app.h"
#include "audio.h"
#include "out123.h"
#include "common.h"
#include "sysutil.h"
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#include "debug.h"
mpg123_string* audio_enclist(void)
{
int i;
mpg123_string *list;
size_t enc_count = 0;
const int *enc_codes = NULL;
/* Only the encodings supported by libmpg123 build
Those returned by out123_enc_list() are a superset. */
mpg123_encodings(&enc_codes, &enc_count);
if((list = malloc(sizeof(*list))))
mpg123_init_string(list);
/* Further calls to mpg123 string lib are hardened against NULL. */
for(i=0;i<enc_count;++i)
{
if(i>0)
mpg123_add_string(list, " ");
mpg123_add_string(list, out123_enc_name(enc_codes[i]));
}
return list;
}
static void capline(mpg123_handle *mh, long rate)
{
int enci;
const int *encs;
size_t num_encs;
mpg123_encodings(&encs, &num_encs);
fprintf(stderr," %5ld |", pitch_rate(rate));
for(enci=0; enci<num_encs; ++enci)
{
switch(mpg123_format_support(mh, rate, encs[enci]))
{
case MPG123_MONO: fprintf(stderr, " M |"); break;
case MPG123_STEREO: fprintf(stderr, " S |"); break;
case MPG123_MONO|MPG123_STEREO: fprintf(stderr, " M/S |"); break;
default: fprintf(stderr, " |");
}
}
fprintf(stderr, "\n");
}
void print_capabilities(out123_handle *ao, mpg123_handle *mh)
{
int r,e;
const long *rates;
size_t num_rates;
const int *encs;
size_t num_encs;
char *name;
char *dev;
out123_driver_info(ao, &name, &dev);
mpg123_rates(&rates, &num_rates);
mpg123_encodings(&encs, &num_encs);
fprintf(stderr,"\nAudio driver: %s\nAudio device: %s\nAudio capabilities:\n(matrix of [S]tereo or [M]ono support for sample format and rate in Hz)\n |", name, dev);
for(e=0;e<num_encs;e++)
{
const char *encname = out123_enc_name(encs[e]);
fprintf(stderr," %5s |", encname ? encname : "???");
}
fprintf(stderr,"\n ------|");
for(e=0;e<num_encs;e++) fprintf(stderr,"-------|");
fprintf(stderr, "\n");
for(r=0; r<num_rates; ++r) capline(mh, rates[r]);
if(param.force_rate) capline(mh, param.force_rate);
fprintf(stderr,"\n");
}
/* Quick-shot paired table setup with remembering search in it.
this is for storing pairs of output sampling rate and decoding
sampling rate. */
struct ratepair { long a; long b; };
long brate(struct ratepair *table, long arate, int count, int *last)
{
int i = 0;
int j;
for(j=0; j<2; ++j)
{
i = i ? 0 : *last;
for(; i<count; ++i) if(table[i].a == arate)
{
*last = i;
return table[i].b;
}
}
return 0;
}
/* This uses the currently opened audio device, queries its caps.
In case of buffered playback, this works _once_ by querying the buffer for the caps before entering the main loop. */
void audio_capabilities(out123_handle *ao, mpg123_handle *mh)
{
int force_fmt = 0;
size_t ri;
/* Pitching introduces a difference between decoder rate and playback rate. */
long decode_rate;
const long *rates;
long *outrates;
struct ratepair *unpitch;
struct mpg123_fmt *outfmts = NULL;
int fmtcount;
size_t num_rates, rlimit;
debug("audio_capabilities");
mpg123_rates(&rates, &num_rates);
mpg123_format_none(mh); /* Start with nothing. */
if(param.force_encoding != NULL)
{
if(!param.quiet)
fprintf(stderr, "Note: forcing output encoding %s\n", param.force_encoding);
force_fmt = out123_enc_byname(param.force_encoding);
if(!force_fmt)
{
error1("Failed to find an encoding to match requested \"%s\"!\n"
, param.force_encoding);
return; /* No capabilities at all... */
}
else if(param.verbose > 2)
fprintf(stderr, "Note: forcing encoding code 0x%x (%s)\n"
, force_fmt, out123_enc_name(force_fmt));
}
/* Lots of preparation of rate lists. */
rlimit = param.force_rate > 0 ? num_rates+1 : num_rates;
outrates = malloc(sizeof(*rates)*rlimit);
unpitch = malloc(sizeof(*unpitch)*rlimit);
if(!outrates || !unpitch)
{
if(!param.quiet)
error("DOOM");
return;
}
for(ri = 0; ri<rlimit; ri++)
{
decode_rate = ri < num_rates ? rates[ri] : param.force_rate;
outrates[ri] = pitch_rate(decode_rate);
unpitch[ri].a = outrates[ri];
unpitch[ri].b = decode_rate;
}
/* Actually query formats possible with given rates. */
fmtcount = out123_formats(ao, outrates, rlimit, 1, 2, &outfmts);
free(outrates);
if(fmtcount > 0)
{
int fi;
int unpitch_i = 0;
if(param.verbose > 1 && outfmts[0].encoding > 0)
{
const char *encname = out123_enc_name(outfmts[0].encoding);
fprintf(stderr, "Note: default format %li Hz, %i channels, %s\n"
, outfmts[0].rate, outfmts[0].channels
, encname ? encname : "???" );
}
for(fi=1; fi<fmtcount; ++fi)
{
int fmts = outfmts[fi].encoding;
if(param.verbose > 2)
fprintf( stderr
, "Note: output support for %li Hz, %i channels: 0x%x\n"
, outfmts[fi].rate, outfmts[fi].channels, outfmts[fi].encoding );
if(force_fmt)
{ /* Filter for forced encoding. */
if((fmts & force_fmt) == force_fmt)
fmts = force_fmt;
else /* Nothing else! */
fmts = 0;
}
mpg123_format( mh
, brate(unpitch, outfmts[fi].rate, rlimit, &unpitch_i)
, outfmts[fi].channels, fmts );
}
}
free(outfmts);
free(unpitch);
if(param.verbose > 1) print_capabilities(ao, mh);
}
int set_pitch(mpg123_handle *fr, out123_handle *ao, double new_pitch)
{
double old_pitch = param.pitch;
long rate;
int channels, format;
int smode = 0;
/* Be safe, check support. */
if(mpg123_getformat(fr, &rate, &channels, &format) != MPG123_OK)
{
/* We might just not have a track handy. */
error("There is no current audio format, cannot apply pitch. This might get fixed in future.");
return 0;
}
param.pitch = new_pitch;
if(param.pitch < -0.99) param.pitch = -0.99;
if(channels == 1) smode = MPG123_MONO;
if(channels == 2) smode = MPG123_STEREO;
out123_stop(ao);
/* Remember: This takes param.pitch into account. */
audio_capabilities(ao, fr);
if(!(mpg123_format_support(fr, rate, format) & smode))
{
/* Note: When using --pitch command line parameter, you can go higher
because a lower decoder sample rate is automagically chosen.
Here, we'd need to switch decoder rate during track... good? */
error("Reached a hardware limit there with pitch!");
param.pitch = old_pitch;
audio_capabilities(ao, fr);
}
return out123_start(ao, pitch_rate(rate), channels, format);
}

View File

@ -0,0 +1,38 @@
/*
audio: audio output interface
This is what is left after separating out libout123.
copyright ?-2015 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
/*
* Audio 'LIB' defines
*/
#ifndef _MPG123_AUDIO_H_
#define _MPG123_AUDIO_H_
#include "compat.h"
#include "mpg123.h"
#include "out123.h"
#define pitch_rate(rate) (param.pitch == 0 ? (rate) : (long) ((param.pitch+1.0)*(rate)))
mpg123_string* audio_enclist(void);
void audio_capabilities(out123_handle *ao, mpg123_handle *mh);
void print_capabilities(out123_handle *ao, mpg123_handle *mh);
/*
Twiddle audio output rate to yield speedup/down (pitch) effect.
The actually achieved pitch value is stored in param.pitch.
Returns 1 if pitch setting succeeded, 0 otherwise.
*/
int set_pitch(mpg123_handle *fr, out123_handle *ao, double new_pitch);
#endif

View File

@ -0,0 +1,432 @@
/*
common: misc stuff... audio flush, status display...
copyright ?-2015 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
/* Need snprintf. */
#define _DEFAULT_SOURCE
#define _BSD_SOURCE
#include "mpg123app.h"
#include "out123.h"
#include <sys/stat.h>
#include "common.h"
#ifdef __EMX__
/* Special ways for OS/2 EMX */
#include <stdlib.h>
#else
/* POSIX stuff */
#ifdef HAVE_TERMIOS
#include <termios.h>
#include <sys/ioctl.h>
#endif
#endif
#include "debug.h"
int stopped = 0;
int paused = 0;
/* Also serves as a way to detect if we have an interactive terminal. */
int term_width(int fd)
{
#ifdef __EMX__
/* OS/2 */
int s[2];
_scrsize (s);
if (s[0] >= 0)
return s[0];
#else
#ifdef HAVE_TERMIOS
/* POSIX */
struct winsize geometry;
geometry.ws_col = 0;
if(ioctl(fd, TIOCGWINSZ, &geometry) >= 0)
return (int)geometry.ws_col;
#endif
#endif
return -1;
}
const char* rva_name[3] = { "off", "mix", "album" };
static const char* rva_statname[3] = { "---", "mix", "alb" };
static const char *modes[5] = {"Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel", "Invalid" };
static const char *smodes[5] = { "stereo", "j-s", "dual", "mono", "o.O" };
static const char *layers[4] = { "Unknown" , "I", "II", "III" };
static const char *versions[4] = {"1.0", "2.0", "2.5", "x.x" };
static const int samples_per_frame[4][4] =
{
{ -1,384,1152,1152 }, /* MPEG 1 */
{ -1,384,1152,576 }, /* MPEG 2 */
{ -1,384,1152,576 }, /* MPEG 2.5 */
{ -1,-1,-1,-1 }, /* Unknown */
};
/* concurring to print_rheader... here for control_generic */
const char* remote_header_help = "S <mpeg-version> <layer> <sampling freq> <mode(stereo/mono/...)> <mode_ext> <framesize> <stereo> <copyright> <error_protected> <emphasis> <bitrate> <extension> <vbr(0/1=yes/no)>";
void print_remote_header(mpg123_handle *mh)
{
struct mpg123_frameinfo i;
mpg123_info(mh, &i);
if(i.mode >= 4 || i.mode < 0) i.mode = 4;
if(i.version >= 3 || i.version < 0) i.version = 3;
generic_sendmsg("S %s %d %ld %s %d %d %d %d %d %d %d %d %d",
versions[i.version],
i.layer,
i.rate,
modes[i.mode],
i.mode_ext,
i.framesize,
i.mode == MPG123_M_MONO ? 1 : 2,
i.flags & MPG123_COPYRIGHT ? 1 : 0,
i.flags & MPG123_CRC ? 1 : 0,
i.emphasis,
i.bitrate,
i.flags & MPG123_PRIVATE ? 1 : 0,
i.vbr);
}
void print_header(mpg123_handle *mh)
{
struct mpg123_frameinfo i;
mpg123_info(mh, &i);
if(i.mode > 4 || i.mode < 0) i.mode = 4;
if(i.version > 3 || i.version < 0) i.version = 3;
if(i.layer > 3 || i.layer < 0) i.layer = 0;
fprintf(stderr,"MPEG %s, Layer: %s, Freq: %ld, mode: %s, modext: %d, BPF : %d\n",
versions[i.version],
layers[i.layer], i.rate,
modes[i.mode],i.mode_ext,i.framesize);
fprintf(stderr,"Channels: %d, copyright: %s, original: %s, CRC: %s, emphasis: %d.\n",
i.mode == MPG123_M_MONO ? 1 : 2,i.flags & MPG123_COPYRIGHT ? "Yes" : "No",
i.flags & MPG123_ORIGINAL ? "Yes" : "No", i.flags & MPG123_CRC ? "Yes" : "No",
i.emphasis);
fprintf(stderr,"Bitrate: ");
switch(i.vbr)
{
case MPG123_CBR:
if(i.bitrate) fprintf(stderr, "%d kbit/s", i.bitrate);
else fprintf(stderr, "%d kbit/s (free format)", (int)((double)(i.framesize+4)*8*i.rate*0.001/samples_per_frame[i.version][i.layer]+0.5));
break;
case MPG123_VBR: fprintf(stderr, "VBR"); break;
case MPG123_ABR: fprintf(stderr, "%d kbit/s ABR", i.abr_rate); break;
default: fprintf(stderr, "???");
}
fprintf(stderr, " Extension value: %d\n", i.flags & MPG123_PRIVATE ? 1 : 0);
}
void print_header_compact(mpg123_handle *mh)
{
struct mpg123_frameinfo i;
mpg123_info(mh, &i);
if(i.mode > 4 || i.mode < 0) i.mode = 4;
if(i.version > 3 || i.version < 0) i.version = 3;
if(i.layer > 3 || i.layer < 0) i.layer = 0;
fprintf(stderr,"MPEG %s L %s ", versions[i.version], layers[i.layer]);
switch(i.vbr)
{
case MPG123_CBR:
if(i.bitrate) fprintf(stderr, "cbr%d", i.bitrate);
else fprintf(stderr, "cbr%d", (int)((double)i.framesize*8*i.rate*0.001/samples_per_frame[i.version][i.layer]+0.5));
break;
case MPG123_VBR: fprintf(stderr, "vbr"); break;
case MPG123_ABR: fprintf(stderr, "abr%d", i.abr_rate); break;
default: fprintf(stderr, "???");
}
fprintf(stderr," %ld %s\n", i.rate, smodes[i.mode]);
}
unsigned int roundui(double val)
{
double base = floor(val);
return (unsigned int) ((val-base) < 0.5 ? base : base + 1 );
}
/* Split into mm:ss.xx or hh:mm:ss, depending on value. */
static void settle_time(double tim, unsigned long *times, char *sep)
{
if(tim >= 3600.)
{
*sep = ':';
times[0] = (unsigned long) tim/3600;
tim -= times[0]*3600;
times[1] = (unsigned long) tim/60;
tim -= times[1]*60;
times[2] = (unsigned long) tim;
}
else
{
*sep = '.';
times[0] = (unsigned long) tim/60;
times[1] = (unsigned long) tim%60;
times[2] = (unsigned long) (tim*100)%100;
}
}
/* Print output buffer fill. */
void print_buf(const char* prefix, out123_handle *ao)
{
long rate;
int framesize;
double tim;
unsigned long times[3];
char timesep;
size_t buffsize;
buffsize = out123_buffered(ao);
if(out123_getformat(ao, &rate, NULL, NULL, &framesize))
return;
tim = (double)(buffsize/framesize)/rate;
settle_time(tim, times, &timesep);
fprintf( stderr, "\r%s[%02lu:%02lu%c%02lu]"
, prefix, times[0], times[1], timesep, times[2] );
}
/* Note about position info with buffering:
Negative positions mean that the previous track is still playing from the
buffer. It's a countdown. The frame counter always relates to the last
decoded frame, what entered the buffer right now. */
void print_stat(mpg123_handle *fr, long offset, out123_handle *ao, int draw_bar)
{
size_t buffered;
off_t decoded;
off_t elapsed;
off_t remain;
off_t length;
off_t frame;
off_t frames;
off_t rframes;
int spf;
double basevol, realvol;
char *icy;
long rate;
int framesize;
struct mpg123_frameinfo mi;
char linebuf[256];
char *line = NULL;
#ifndef WIN32
#ifndef GENERIC
/* Only generate new stat line when stderr is ready... don't overfill... */
{
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
#endif
if(out123_getformat(ao, &rate, NULL, NULL, &framesize))
return;
buffered = out123_buffered(ao)/framesize;
decoded = mpg123_tell(fr);
length = mpg123_length(fr);
frame = mpg123_tellframe(fr);
frames = mpg123_framelength(fr);
spf = mpg123_spf(fr);
if(decoded < 0 || length < 0 || frame < 0 || frames <= 0 || spf <= 0)
return;
/* Apply offset. */
frame += offset;
if(frame < 0)
frame = 0;
/* Some sensible logic around offsets and time.
Buffering makes the relationships between the numbers non-trivial. */
rframes = frames-frame;
elapsed = decoded + offset*spf - buffered; /* May be negative, a countdown. */
remain = elapsed > 0 ? length - elapsed : length;
if( MPG123_OK == mpg123_info(fr, &mi)
&& MPG123_OK == mpg123_getvolume(fr, &basevol, &realvol, NULL) )
{
char framefmt[10];
char framestr[2][32];
int linelen;
int maxlen;
int len;
int ti;
/* Deal with overly long times. */
double tim[3];
unsigned long times[3][3];
char timesep[3];
char sign[3] = {' ', ' ', ' '};
/* 255 is enough for the data I prepare, if there is no terminal width to
fill */
maxlen = term_width(STDERR_FILENO);
linelen = maxlen > 0 ? maxlen : (sizeof(linebuf)-1);
line = linelen >= sizeof(linebuf)
? malloc(linelen+1) /* Only malloc if it is a really long line. */
: linebuf; /* Small buffer on stack is enough. */
tim[0] = (double)elapsed/rate;
tim[1] = (double)remain/rate;
tim[2] = (double)buffered/rate;
for(ti=0; ti<3; ++ti)
{
if(tim[ti] < 0.){ sign[ti] = '-'; tim[ti] = -tim[ti]; }
settle_time(tim[ti], times[ti], &timesep[ti]);
}
/* Taking pains to properly size the frame number fields. */
len = snprintf( framefmt, sizeof(framefmt)
, "%%0%d"OFF_P, (int)log10(frames)+1 );
if(len < 0 || len >= sizeof(framefmt))
memcpy(framefmt, "%05"OFF_P, sizeof("%05"OFF_P));
snprintf( framestr[0], sizeof(framestr[0])-1, framefmt, (off_p)frame);
framestr[0][sizeof(framestr[0])-1] = 0;
snprintf( framestr[1], sizeof(framestr[1])-1, framefmt, (off_p)rframes);
framestr[1][sizeof(framestr[1])-1] = 0;
/* Now start with the state line. */
memset(line, 0, linelen+1); /* Always one zero more. */
/* Start with position info. */
len = snprintf( line, linelen
, "%c %s+%s %c%02lu:%02lu%c%02lu+%02lu:%02lu%c%02lu"
, stopped ? '_' : (paused ? '=' : '>')
, framestr[0], framestr[1]
, sign[0]
, times[0][0], times[0][1], timesep[0], times[0][2]
, times[1][0], times[1][1], timesep[1], times[1][2]
);
/* Just cut it. */
if(len >= linelen)
len=linelen;
if(len >= 0 && param.usebuffer && len < linelen )
{ /* Buffer info. */
int len_add = snprintf( line+len, linelen-len
, " [%02lu:%02lu%c%02lu]"
, times[2][0], times[2][1], timesep[2], times[2][2] );
if(len_add > 0)
len += len_add;
}
if(len >= 0 && len < linelen)
{ /* Volume info. */
int len_add = snprintf( line+len, linelen-len
, " %s %03u=%03u"
, rva_statname[param.rva], roundui(basevol*100), roundui(realvol*100)
);
if(len_add > 0)
len += len_add;
}
if(len >= 0 && len < linelen)
{ /* Bitrate. */
int len_add = snprintf( line+len, linelen-len
, " %3d kb/s", mi.bitrate );
if(len_add > 0)
len += len_add;
}
if(len >= 0 && len < linelen)
{ /* Size of frame in bytes. */
int len_add = snprintf( line+len, linelen-len
, " %4d B", mi.framesize );
if(len_add > 0)
len += len_add;
}
if(len >= 0 && len < linelen)
{ /* Size of frame in bytes. */
int len_add = 0;
long res = 0;
if(mpg123_getstate(fr, MPG123_ACCURATE, &res, NULL) == MPG123_OK)
len_add = snprintf( line+len, linelen-len
, " %s", res ? "acc" : "fuz" );
if(len_add > 0)
len += len_add;
}
if(len >= 0 && len < linelen)
{ /* Size of frame in bytes. */
int len_add = 0;
long res = mpg123_clip(fr);
if(res >= 0)
len_add = snprintf( line+len, linelen-len
, " %4ld clip", res );
if(len_add > 0)
len += len_add;
}
if(len >= 0 && len < linelen)
{ /* Size of frame in bytes. */
int len_add = 0;
len_add = snprintf( line+len, linelen-len
, " p%+.3f", param.pitch );
if(len_add > 0)
len += len_add;
}
if(len >= 0)
{
if(maxlen > 0 && len > maxlen)
{
/* Emergency cut to avoid terminal scrolling. */
int i;
/* Blank a word that would have been cut off. */
for(i=maxlen; i>=0; --i)
{
char old = line[i];
line[i] = ' ';
if(old == ' ')
break;
}
line[maxlen] = 0;
len = maxlen;
}
/* Ensure that it is filled with spaces if we got some line length.
Shouldn't we always fill to maxlen? */
if(maxlen > 0)
memset(line+len, ' ', linelen-len);
#ifdef HAVE_TERMIOS
/* Use inverse color to draw a progress bar. */
if(maxlen > 0 && draw_bar)
{
char old;
int barlen = 0;
if(length > 0 && elapsed > 0)
{
if(elapsed < length)
barlen = (int)((double)elapsed/length * maxlen);
else
barlen = maxlen;
}
old = line[barlen];
fprintf(stderr, "\x1b[7m");
line[barlen] = 0;
fprintf(stderr, "\r%s", line);
line[barlen] = old;
fprintf(stderr, "\x1b[0m");
fprintf(stderr, "%s", line+barlen);
}
else
#endif
fprintf(stderr, "\r%s", line);
}
}
/* Check for changed tags here too? */
if( mpg123_meta_check(fr) & MPG123_NEW_ICY && MPG123_OK == mpg123_icy(fr, &icy) )
{
if(line) /* Clear the inverse video. */
fprintf(stderr, "\r%s", line);
fprintf(stderr, "\nICY-META: %s\n", icy);
}
if(line && line != linebuf)
free(line);
}
void clear_stat()
{
int len = term_width(STDERR_FILENO);
if(len > 0)
{
char fmt[20];
int flen;
if( (flen=snprintf(fmt, sizeof(fmt), "\r%%%ds\r", len)) > 0
&& flen < sizeof(fmt) )
fprintf(stderr, fmt, " ");
}
}

View File

@ -0,0 +1,35 @@
/*
common: anything can happen here... frame reading, output, messages
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
#ifndef _MPG123_COMMON_H_
#define _MPG123_COMMON_H_
#include "mpg123app.h"
#include "out123.h"
extern int stopped;
extern int paused;
/* Return width of terminal associated with given descriptor,
-1 when there is none. */
int term_width(int fd);
void print_header(mpg123_handle *);
void print_header_compact(mpg123_handle *);
void print_stat(mpg123_handle *fr, long offset, out123_handle *ao, int draw_bar);
void print_buf(const char* prefix, out123_handle *ao);
void clear_stat();
/* for control_generic */
extern const char* remote_header_help;
void print_remote_header(mpg123_handle *mh);
void generic_sendmsg (const char *fmt, ...);
extern const char* rva_name[3];
#endif

View File

@ -0,0 +1,14 @@
noinst_LTLIBRARIES += src/compat/libcompat.la
noinst_LTLIBRARIES += src/compat/libcompat_str.la
src_compat_libcompat_la_SOURCES = \
src/compat/compat_str.c \
src/compat/compat.c \
src/compat/compat.h
# A smaller one for the output modules. Do not want to grow them
# unnecessarily with unused code.
src_compat_libcompat_str_la_SOURCES = \
src/compat/compat_str.c \
src/compat/compat.h

View File

@ -0,0 +1,665 @@
/*
compat: Some compatibility functions (basic memory & string stuff in separate file)
The mpg123 code is determined to keep it's legacy. A legacy of old, old UNIX.
So anything possibly somewhat advanced should be considered to be put here, with proper #ifdef;-)
copyright 2007-2016 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis, Windows Unicode stuff by JonY.
*/
#include "config.h"
/* This source file does need _POSIX_SOURCE to get some sigaction. */
#define _POSIX_SOURCE
#include "compat.h"
#ifdef _MSC_VER
#include <io.h>
#if(defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP))
#define WINDOWS_UWP
#endif
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#endif
/* Win32 is only supported with unicode now. These headers also cover
module stuff. The WANT_WIN32_UNICODE macro is synonymous with
"want windows-specific API, and only the unicode variants of which". */
#ifdef WANT_WIN32_UNICODE
#include <wchar.h>
#include <windows.h>
#include <winnls.h>
#include <shlwapi.h>
#endif
#ifdef USE_MODULES
# ifdef HAVE_DLFCN_H
# include <dlfcn.h>
# endif
#endif
#include "debug.h"
#ifndef WINDOWS_UWP
char *compat_getenv(const char* name)
{
char *ret = NULL;
#ifdef WANT_WIN32_UNICODE
wchar_t *env;
wchar_t *wname = NULL;
if(win32_utf8_wide(name, &wname, NULL) > 0)
{
env = _wgetenv(wname);
free(wname);
if(env)
win32_wide_utf8(env, &ret, NULL);
}
#else
ret = getenv(name);
if(ret)
ret = compat_strdup(ret);
#endif
return ret;
}
#ifdef WANT_WIN32_UNICODE
/* Convert unix UTF-8 (or ASCII) paths to Windows wide character paths. */
static wchar_t* u2wpath(const char *upath)
{
wchar_t* wpath, *p;
if(!upath || win32_utf8_wide(upath, &wpath, NULL) < 1)
return NULL;
for(p=wpath; *p; ++p)
if(*p == L'/')
*p = L'\\';
return wpath;
}
/* Convert Windows wide character paths to unix UTF-8. */
static char* w2upath(const wchar_t *wpath)
{
char* upath, *p;
if(!wpath || win32_wide_utf8(wpath, &upath, NULL) < 1)
return NULL;
for(p=upath; *p; ++p)
if(*p == '\\')
*p = '/';
return upath;
}
/* An absolute path that is too long and not already marked with
\\?\ can be marked as a long one and still work. */
static int wpath_need_elongation(wchar_t *wpath)
{
if( wpath && !PathIsRelativeW(wpath)
&& wcslen(wpath) > MAX_PATH-1
&& wcsncmp(L"\\\\?\\", wpath, 4) )
return 1;
else
return 0;
}
/* Take any wide windows path and turn it into a path that is allowed
to be longer than MAX_PATH, if it is not already. */
static wchar_t* wlongpath(wchar_t *wpath)
{
size_t len, plen;
const wchar_t *prefix = L"";
wchar_t *wlpath = NULL;
if(!wpath)
return NULL;
/* Absolute paths that do not start with \\?\ get that prepended
to allow them being long. */
if(!PathIsRelativeW(wpath) && wcsncmp(L"\\\\?\\", wpath, 4))
{
if(wcslen(wpath) >= 2 && PathIsUNCW(wpath))
{
/* \\server\path -> \\?\UNC\server\path */
prefix = L"\\\\?\\UNC";
++wpath; /* Skip the first \. */
}
else /* c:\some/path -> \\?\c:\some\path */
prefix = L"\\\\?\\";
}
plen = wcslen(prefix);
len = plen + wcslen(wpath);
wlpath = malloc(len+1*sizeof(wchar_t));
if(wlpath)
{
/* Brute force memory copying, swprintf is too dandy. */
memcpy(wlpath, prefix, sizeof(wchar_t)*plen);
memcpy(wlpath+plen, wpath, sizeof(wchar_t)*(len-plen));
wlpath[len] = 0;
}
return wlpath;
}
/* Convert unix path to wide windows path, optionally marking
it as long path if necessary. */
static wchar_t* u2wlongpath(const char *upath)
{
wchar_t *wpath = NULL;
wchar_t *wlpath = NULL;
wpath = u2wpath(upath);
if(wpath_need_elongation(wpath))
{
wlpath = wlongpath(wpath);
free(wpath);
wpath = wlpath;
}
return wpath;
}
#endif
#else
static wchar_t* u2wlongpath(const char *upath)
{
wchar_t* wpath, *p;
if (!upath || win32_utf8_wide(upath, &wpath, NULL) < 1)
return NULL;
for (p = wpath; *p; ++p)
if (*p == L'/')
*p = L'\\';
return wpath;
}
#endif
/* Always add a default permission mask in case of flags|O_CREAT. */
int compat_open(const char *filename, int flags)
{
int ret;
#if defined (WANT_WIN32_UNICODE)
wchar_t *frag = NULL;
frag = u2wlongpath(filename);
/* Fallback to plain open when ucs-2 conversion fails */
if(!frag)
goto open_fallback;
/*Try _wopen */
ret = _wopen(frag, flags|_O_BINARY, _S_IREAD | _S_IWRITE);
if(ret != -1 )
goto open_ok; /* msdn says -1 means failure */
open_fallback:
#endif
#if (defined(WIN32) && !defined (__CYGWIN__))
/* MSDN says POSIX function is deprecated beginning in Visual C++ 2005 */
/* Try plain old _open(), if it fails, do nothing */
ret = _open(filename, flags|_O_BINARY, _S_IREAD | _S_IWRITE);
#else
ret = open(filename, flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
#endif
#if defined (WANT_WIN32_UNICODE)
open_ok:
free(frag);
#endif
return ret;
}
/* Moved over from wav.c, logic with fallbacks added from the
example of compat_open(). */
FILE* compat_fopen(const char *filename, const char *mode)
{
FILE* stream = NULL;
#ifdef WANT_WIN32_UNICODE
int cnt = 0;
wchar_t *wname = NULL;
wchar_t *wmode = NULL;
wname = u2wlongpath(filename);
if(!wname)
goto fopen_fallback;
cnt = win32_utf8_wide(mode, &wmode, NULL);
if( (wmode == NULL) || (cnt == 0))
goto fopen_fallback;
stream = _wfopen(wname, wmode);
if(stream) goto fopen_ok;
fopen_fallback:
#endif
stream = fopen(filename, mode);
#ifdef WANT_WIN32_UNICODE
fopen_ok:
free(wmode);
free(wname);
#endif
return stream;
}
FILE* compat_fdopen(int fd, const char *mode)
{
return fdopen(fd, mode);
}
int compat_close(int infd)
{
#if (defined(WIN32) && !defined (__CYGWIN__)) /* MSDN says POSIX function is deprecated beginning in Visual C++ 2005 */
return _close(infd);
#else
return close(infd);
#endif
}
int compat_fclose(FILE *stream)
{
return fclose(stream);
}
/* Windows Unicode stuff */
#ifdef WANT_WIN32_UNICODE
int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen)
{
size_t len;
char *buf;
int ret = 0;
len = WideCharToMultiByte(CP_UTF8, 0, wptr, -1, NULL, 0, NULL, NULL); /* Get utf-8 string length */
buf = calloc(len + 1, sizeof (char)); /* Can we assume sizeof char always = 1? */
if(!buf) len = 0;
else {
if (len != 0) ret = WideCharToMultiByte(CP_UTF8, 0, wptr, -1, buf, len, NULL, NULL); /*Do actual conversion*/
buf[len] = '0'; /* Must terminate */
}
*mbptr = buf; /* Set string pointer to allocated buffer */
if(buflen != NULL) *buflen = (len) * sizeof (char); /* Give length of allocated memory if needed. */
return ret;
}
int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen)
{
size_t len;
wchar_t *buf;
int ret = 0;
len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, mbptr, -1, NULL, 0); /* Get converted size */
buf = calloc(len + 1, sizeof (wchar_t)); /* Allocate memory accordingly */
if(!buf) len = 0;
else {
if (len != 0) ret = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, mbptr, -1, buf, len); /* Do conversion */
buf[len] = L'0'; /* Must terminate */
}
*wptr = buf; /* Set string pointer to allocated buffer */
if (buflen != NULL) *buflen = len * sizeof (wchar_t); /* Give length of allocated memory if needed. */
return ret; /* Number of characters written */
}
#endif
#ifndef WINDOWS_UWP
/*
The Windows file and path stuff is an extract of jon_y's win32 loader
prototype from the loader_rework branch. It's been divided in to
reusable functons by ThOr in the hope to work out some generic-looking
loader code for both POSIX and Windows. The routines might be
helpful for consistent path work in other parts of mpg123, too.
This all is about getting some working code on a wide range of
systems while staying somewhat sane. If it does ridiculously inefficient
things with extraneous copies and grabbing of functions that made
it late to some official APIs, that's still fine with us.
*/
char* compat_catpath(const char *prefix, const char* path)
{
char *ret = NULL;
#ifdef WANT_WIN32_UNICODE
wchar_t *wprefix = NULL; /* Wide windows versions of */
wchar_t *wpath = NULL; /* input arguments. */
wchar_t *locwret = NULL; /* Tmp return value from LocalAlloc */
/*
This variation of combinepath can work with long and UNC paths, but
is not officially exposed in any DLLs, It also allocates all its buffers
internally via LocalAlloc, avoiding buffer overflow problems.
ThOr: I presume this hack is for supporting pre-8 Windows, as
from Windows 8 on, this is documented in the API.
*/
HRESULT (__stdcall *mypac)( const wchar_t *in, const wchar_t* more
, unsigned long flags, wchar_t **out ) = NULL;
HMODULE pathcch = NULL;
if(!prefix && !path)
goto catpath_end;
wprefix = u2wpath(prefix);
wpath = u2wpath(path);
if((prefix && !wprefix) || (path && !wpath))
goto catpath_end;
/* Again: I presume this whole fun is to get at PathAllocCombine
even when pathcch.h is not available (like in MinGW32). */
if( (pathcch = GetModuleHandleA("kernelbase")) )
mypac = (void *)GetProcAddress(pathcch, "PathAllocCombine");
if(mypac) /* PATHCCH_ALLOW_LONG_PATH = 1 per API docs */
{
debug("Actually calling PathAllocCombine!");
mypac(wprefix, wpath, 1, &locwret);
}
else
{
/* Playing safe, if we'd care much about performance, this would be on
the stack. */
locwret = LocalAlloc(LPTR, sizeof(wchar_t)*MAX_PATH);
if(locwret)
PathCombineW(locwret, wprefix, wpath);
}
ret = w2upath(locwret);
catpath_end:
LocalFree(locwret);
free(wprefix);
free(wpath);
#else
size_t len, prelen, patlen;
if(path && path[0] == '/')
prefix = NULL; /* Absolute path stays as it is. */
prelen = prefix ? strlen(prefix) : 0;
patlen = path ? strlen(path) : 0;
/* Concatenate the two, put a / in between if both present. */
len = ((prefix && path) ? 1 : 0) + prelen + patlen;
ret = malloc(len+1);
if(ret)
{
size_t off=0;
memcpy(ret, prefix, prelen);
if(prefix && path)
ret[prelen+(off++)] = '/';
memcpy(ret+prelen+off, path, patlen);
ret[len] = 0;
}
#endif
return ret;
}
int compat_isdir(const char *path)
{
int ret = 0;
#ifdef WANT_WIN32_UNICODE
wchar_t *wpath;
wpath = u2wlongpath(path);
if(wpath)
{
DWORD attr = GetFileAttributesW(wpath);
if(attr != INVALID_FILE_ATTRIBUTES && attr & FILE_ATTRIBUTE_DIRECTORY)
ret=1;
free(wpath);
}
#else
struct stat sb;
if(path && !stat(path, &sb))
{
if(S_ISDIR(sb.st_mode))
ret=1;
}
#endif
return ret;
}
struct compat_dir
{
char *path;
#ifdef WANT_WIN32_UNICODE
int gotone; /* Got a result stored from FindFirstFileW. */
WIN32_FIND_DATAW d;
HANDLE ffn;
#else
DIR* dir;
#endif
};
struct compat_dir* compat_diropen(char *path)
{
struct compat_dir *cd;
if(!path)
return NULL;
cd = malloc(sizeof(*cd));
if(!cd)
return NULL;
#ifdef WANT_WIN32_UNICODE
cd->gotone = 0;
{
char *pattern;
wchar_t *wpattern;
pattern = compat_catpath(path, "*");
wpattern = u2wlongpath(pattern);
if(wpattern)
{
cd->ffn = FindFirstFileW(wpattern, &(cd->d));
if(cd->ffn == INVALID_HANDLE_VALUE)
{
/* FindClose() only needed after successful first find, right? */
free(cd);
cd = NULL;
}
else
cd->gotone = 1;
}
free(wpattern);
free(pattern);
}
#else
cd->dir = opendir(path);
if(!cd->dir)
{
free(cd);
cd = NULL;
}
#endif
if(cd)
{
cd->path = compat_strdup(path);
if(!cd->path)
{
compat_dirclose(cd);
cd = NULL;
}
}
return cd;
}
void compat_dirclose(struct compat_dir *cd)
{
if(cd)
{
free(cd->path);
#ifdef WANT_WIN32_UNICODE
FindClose(cd->ffn);
#else
closedir(cd->dir);
#endif
free(cd);
}
}
char* compat_nextfile(struct compat_dir *cd)
{
if(!cd)
return NULL;
#ifdef WANT_WIN32_UNICODE
while(cd->gotone || FindNextFileW(cd->ffn, &(cd->d)))
{
cd->gotone = 0;
if(!(cd->d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
char *ret;
win32_wide_utf8(cd->d.cFileName, &ret, NULL);
return ret;
}
}
#else
{
struct dirent *dp;
while((dp = readdir(cd->dir)))
{
struct stat fst;
char *fullpath = compat_catpath(cd->path, dp->d_name);
if(fullpath && !stat(fullpath, &fst) && S_ISREG(fst.st_mode))
{
free(fullpath);
return compat_strdup(dp->d_name);
}
free(fullpath);
}
}
#endif
return NULL;
}
char* compat_nextdir(struct compat_dir *cd)
{
if(!cd)
return NULL;
#ifdef WANT_WIN32_UNICODE
while(cd->gotone || FindNextFileW(cd->ffn, &(cd->d)))
{
cd->gotone = 0;
if(cd->d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
char *ret;
win32_wide_utf8(cd->d.cFileName, &ret, NULL);
return ret;
}
}
#else
{
struct dirent *dp;
while((dp = readdir(cd->dir)))
{
struct stat fst;
char *fullpath = compat_catpath(cd->path, dp->d_name);
if(fullpath && !stat(fullpath, &fst) && S_ISDIR(fst.st_mode))
{
free(fullpath);
return compat_strdup(dp->d_name);
}
free(fullpath);
}
}
#endif
return NULL;
}
#endif
#ifdef USE_MODULES
/*
This is what I expected the platform-specific dance for dynamic module
support to be. Little did I know about the peculiarities of (long)
paths and directory/file search on Windows.
*/
void *compat_dlopen(const char *path)
{
void *handle = NULL;
#ifdef WANT_WIN32_UNICODE
wchar_t *wpath;
wpath = u2wlongpath(path);
if(wpath)
handle = LoadLibraryW(wpath);
free(wpath);
#else
handle = dlopen(path, RTLD_NOW);
#endif
return handle;
}
void *compat_dlsym(void *handle, const char *name)
{
void *sym = NULL;
if(!handle)
return NULL;
#ifdef WANT_WIN32_UNICODE
sym = GetProcAddress(handle, name);
#else
sym = dlsym(handle, name);
#endif
return sym;
}
void compat_dlclose(void *handle)
{
if(!handle)
return;
#ifdef WANT_WIN32_UNICODE
FreeLibrary(handle);
#else
dlclose(handle);
#endif
}
#endif /* USE_MODULES */
/* This shall survive signals and any return value less than given byte count
is an error */
size_t unintr_write(int fd, void const *buffer, size_t bytes)
{
size_t written = 0;
while(bytes)
{
ssize_t part = write(fd, (char*)buffer+written, bytes);
if(part < 0 && errno != EINTR)
break;
bytes -= part;
written += part;
}
return written;
}
/* Same for reading the data. */
size_t unintr_read(int fd, void *buffer, size_t bytes)
{
size_t got = 0;
while(bytes)
{
ssize_t part = read(fd, (char*)buffer+got, bytes);
if(part < 0 && errno != EINTR)
break;
bytes -= part;
got += part;
}
return got;
}
#ifndef NO_CATCHSIGNAL
#if (!defined(WIN32) || defined (__CYGWIN__)) && defined(HAVE_SIGNAL_H)
void (*catchsignal(int signum, void(*handler)()))()
{
struct sigaction new_sa;
struct sigaction old_sa;
#ifdef DONT_CATCH_SIGNALS
fprintf (stderr, "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
#endif

View File

@ -0,0 +1,289 @@
/*
compat: Some compatibility functions and header inclusions.
Basic standard C stuff, that may barely be above/around C89.
The mpg123 code is determined to keep it's legacy. A legacy of old, old UNIX.
It is envisioned to include this compat header instead of any of the "standard" headers, to catch compatibility issues.
So, don't include stdlib.h or string.h ... include compat.h.
copyright 2007-8 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
*/
#ifndef MPG123_COMPAT_H
#define MPG123_COMPAT_H
#include "config.h"
#include "intsym.h"
/* For --nagging compilation with -std=c89, we need
to disable the inline keyword. */
#ifdef PLAIN_C89
#ifndef inline
#define inline
#endif
#endif
#include <errno.h>
#ifdef HAVE_STDLIB_H
/* realloc, size_t */
#include <stdlib.h>
#endif
#include <stdio.h>
#include <math.h>
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#else
#ifdef HAVE_SYS_SIGNAL_H
#include <sys/signal.h>
#endif
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
/* Types, types, types. */
/* Do we actually need these two in addition to sys/types.h? As replacement? */
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
/* We want SIZE_MAX, etc. */
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)-1)
#endif
#ifndef ULONG_MAX
#define ULONG_MAX ((unsigned long)-1)
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#ifdef OS2
#include <float.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
/* For select(), I need select.h according to POSIX 2001, else: sys/time.h sys/types.h unistd.h */
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
/* compat_open makes little sense without */
#include <fcntl.h>
/* To parse big numbers... */
#ifdef HAVE_ATOLL
#define atobigint atoll
#else
#define atobigint atol
#endif
typedef unsigned char byte;
#if defined(_MSC_VER) && !defined(MPG123_DEF_SSIZE_T)
#define MPG123_DEF_SSIZE_T
#include <stddef.h>
typedef ptrdiff_t ssize_t;
#endif
/* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */
void *safe_realloc(void *ptr, size_t size);
#ifndef HAVE_STRERROR
const char *strerror(int errnum);
#endif
/* Roll our own strdup() that does not depend on libc feature test macros
and returns NULL on NULL input instead of crashing. */
char* compat_strdup(const char *s);
/* If we have the size checks enabled, try to derive some sane printfs.
Simple start: Use max integer type and format if long is not big enough.
I am hesitating to use %ll without making sure that it's there... */
#if !(defined PLAIN_C89) && (defined SIZEOF_OFF_T) && (SIZEOF_OFF_T > SIZEOF_LONG) && (defined PRIiMAX)
# define OFF_P PRIiMAX
typedef intmax_t off_p;
#else
# define OFF_P "li"
typedef long off_p;
#endif
#if !(defined PLAIN_C89) && (defined SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > SIZEOF_LONG) && (defined PRIuMAX)
# define SIZE_P PRIuMAX
typedef uintmax_t size_p;
#else
# define SIZE_P "lu"
typedef unsigned long size_p;
#endif
#if !(defined PLAIN_C89) && (defined SIZEOF_SSIZE_T) && (SIZEOF_SSIZE_T > SIZEOF_LONG) && (defined PRIiMAX)
# define SSIZE_P PRIuMAX
typedef intmax_t ssize_p;
#else
# define SSIZE_P "li"
typedef long ssize_p;
#endif
/* Get an environment variable, possibly converted to UTF-8 from wide string.
The return value is a copy that you shall free. */
char *compat_getenv(const char* name);
/**
* Opening a file handle can be different.
* This function here is defined to take a path in native encoding (ISO8859 / UTF-8 / ...), or, when MS Windows Unicode support is enabled, an UTF-8 string that will be converted back to native UCS-2 (wide character) before calling the system's open function.
* @param[in] wptr Pointer to wide string.
* @param[in] mbptr Pointer to multibyte string.
* @return file descriptor (>=0) or error code.
*/
int compat_open(const char *filename, int flags);
FILE* compat_fopen(const char *filename, const char *mode);
/**
* Also fdopen to avoid having to define POSIX macros in various source files.
*/
FILE* compat_fdopen(int fd, const char *mode);
/**
* Closing a file handle can be platform specific.
* This function takes a file descriptor that is to be closed.
* @param[in] infd File descriptor to be closed.
* @return 0 if the file was successfully closed. A return value of -1 indicates an error.
*/
int compat_close(int infd);
int compat_fclose(FILE* stream);
/* Those do make sense in a separate file, but I chose to include them in compat.c because that's the one source whose object is shared between mpg123 and libmpg123 -- and both need the functionality internally. */
#ifdef WANT_WIN32_UNICODE
/**
* win32_uni2mbc
* Converts a null terminated UCS-2 string to a multibyte (UTF-8) equivalent.
* Caller is supposed to free allocated buffer.
* @param[in] wptr Pointer to wide string.
* @param[out] mbptr Pointer to multibyte string.
* @param[out] buflen Optional parameter for length of allocated buffer.
* @return status of WideCharToMultiByte conversion.
*
* WideCharToMultiByte - http://msdn.microsoft.com/en-us/library/dd374130(VS.85).aspx
*/
int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen);
/**
* win32_mbc2uni
* Converts a null terminated UTF-8 string to a UCS-2 equivalent.
* Caller is supposed to free allocated buffer.
* @param[out] mbptr Pointer to multibyte string.
* @param[in] wptr Pointer to wide string.
* @param[out] buflen Optional parameter for length of allocated buffer.
* @return status of WideCharToMultiByte conversion.
*
* MultiByteToWideChar - http://msdn.microsoft.com/en-us/library/dd319072(VS.85).aspx
*/
int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen);
#endif
/*
A little bit of path abstraction: We always work with plain char strings
that usually represent POSIX-ish UTF-8 paths (something like c:/some/file
might appear). For Windows, those are converted to wide strings with \
instead of / and possible fun is had with prefixes to get around the old
path length limit. Outside of the compat library, that stuff should not
matter, although something like //?/UNC/server/some/file could be thrown
around as UTF-8 string, to be converted to a wide \\?\UNC\server\some\file
just before handing it to Windows API.
There is a lot of unnecessary memory allocation and string copying because
of this, but this filesystem stuff is not really relevant to mpg123
performance, so the goal is to keep the code outside the compatibility layer
simple.
*/
/*
Concatenate a prefix and a path, one of them alowed to be NULL.
If the path is already absolute, the prefix is ignored. Relative
parts (like /..) are resolved if this is sensible for the platform
(meaning: for Windows), else they are preserved (on POSIX, actual
file system access would be needed because of symlinks).
*/
char* compat_catpath(const char *prefix, const char* path);
/* Return 1 if the given path indicates an existing directory,
0 otherwise. */
int compat_isdir(const char *path);
/*
Directory traversal. This talks ASCII/UTF-8 paths externally, converts
to/from wchar_t internally if the platform wants that. Returning NULL
means failure to open/end of listing.
There is no promise about sorting entries.
*/
struct compat_dir;
/* Returns NULL if either directory failed to open or listing is empty.
Listing can still be empty even if non-NULL, so always rely on the
nextfile/nextdir functions. */
struct compat_dir* compat_diropen(char *path);
void compat_dirclose(struct compat_dir*);
/* Get the next entry that is a file (or symlink to one).
The returned string is a copy that needs to be freed after use. */
char* compat_nextfile(struct compat_dir*);
/* Get the next entry that is a directory (or symlink to one).
The returned string is a copy that needs to be freed after use. */
char* compat_nextdir (struct compat_dir*);
#ifdef USE_MODULES
/*
For keeping the path mess local, a system-specific dlopen() variant
is contained in here, too. This is very thin wrapping, even sparing
definition of a handle type, just using void pointers.
Use of absolute paths is a good idea if you want to be sure which
file is openend, as default search paths vary.
*/
void *compat_dlopen (const char *path);
void *compat_dlsym (void *handle, const char* name);
void compat_dlclose(void *handle);
#endif
/* Blocking write/read of data with signal resilience.
Both continue after being interrupted by signals and always return the
amount of processed data (shortage indicating actual problem or EOF). */
size_t unintr_write(int fd, void const *buffer, size_t bytes);
size_t unintr_read (int fd, void *buffer, size_t bytes);
/* That one comes from Tellie on OS/2, needed in resolver. */
#ifdef __KLIBC__
typedef int socklen_t;
#endif
/* OSX SDK defines an enum with "normal" as value. That clashes with
optimize.h */
#ifdef __APPLE__
#define normal mpg123_normal
#endif
#include "true.h"
#if (!defined(WIN32) || defined (__CYGWIN__)) && defined(HAVE_SIGNAL_H)
void (*catchsignal(int signum, void(*handler)()))();
#endif
#endif

View File

@ -0,0 +1,43 @@
/*
compat: Some compatibility functions (basic memory and string stuff)
The mpg123 code is determined to keep it's legacy. A legacy of old, old UNIX.
So anything possibly somewhat advanced should be considered to be put here, with proper #ifdef;-)
copyright 2007-2016 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis, Windows Unicode stuff by JonY.
*/
#include "compat.h"
#include "debug.h"
/* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */
void *safe_realloc(void *ptr, size_t size)
{
if(ptr == NULL) return malloc(size);
else return realloc(ptr, size);
}
#ifndef HAVE_STRERROR
const char *strerror(int errnum)
{
extern int sys_nerr;
extern char *sys_errlist[];
return (errnum < sys_nerr) ? sys_errlist[errnum] : "";
}
#endif
char* compat_strdup(const char *src)
{
char *dest = NULL;
if(src)
{
size_t len;
len = strlen(src)+1;
if((dest = malloc(len)))
memcpy(dest, src, len);
}
return dest;
}

View File

@ -0,0 +1,477 @@
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* Define if your architecture wants/needs/can use attribute_align_arg and
alignment checks. It is for 32bit x86... */
#undef ABI_ALIGN_FUN
/* Define to use proper rounding. */
#undef ACCURATE_ROUNDING
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
/* Define if .balign is present. */
#undef ASMALIGN_BALIGN
/* Define if .align just takes byte count. */
#undef ASMALIGN_BYTE
/* Define if .align takes 3 for alignment of 2^3=8 bytes instead of 8. */
#undef ASMALIGN_EXP
/* Define if __attribute__((aligned(16))) shall be used */
#undef CCALIGN
/* Define if debugging is enabled. */
#undef DEBUG
/* The default audio output module(s) to use */
#undef DEFAULT_OUTPUT_MODULE
/* Define if building with dynamcally linked libmpg123 */
#undef DYNAMIC_BUILD
/* Use EFBIG as substitude for EOVERFLOW, mingw.org may lack the latter */
#undef EOVERFLOW
/* Define if FIFO support is enabled. */
#undef FIFO
/* Define if frame index should be used. */
#undef FRAME_INDEX
/* Define if gapless is enabled. */
#undef GAPLESS
/* Define to 1 if you have the <alc.h> header file. */
#undef HAVE_ALC_H
/* Define to 1 if you have the <Alib.h> header file. */
#undef HAVE_ALIB_H
/* Define to 1 if you have the <AL/alc.h> header file. */
#undef HAVE_AL_ALC_H
/* Define to 1 if you have the <AL/al.h> header file. */
#undef HAVE_AL_AL_H
/* Define to 1 if you have the <al.h> header file. */
#undef HAVE_AL_H
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Define to 1 if you have the <asm/audioio.h> header file. */
#undef HAVE_ASM_AUDIOIO_H
/* Define to 1 if you have the `atoll' function. */
#undef HAVE_ATOLL
/* Define to 1 if you have the <audios.h> header file. */
#undef HAVE_AUDIOS_H
/* Define to 1 if you have the <AudioToolbox/AudioToolbox.h> header file. */
#undef HAVE_AUDIOTOOLBOX_AUDIOTOOLBOX_H
/* Define to 1 if you have the <AudioUnit/AudioUnit.h> header file. */
#undef HAVE_AUDIOUNIT_AUDIOUNIT_H
/* Define to 1 if you have the <CoreServices/CoreServices.h> header file. */
#undef HAVE_CORESERVICES_CORESERVICES_H
/* Define to 1 if you have the <CUlib.h> header file. */
#undef HAVE_CULIB_H
/* Define to 1 if you have the <dirent.h> header file. */
#undef HAVE_DIRENT_H
/* Define to 1 if you have the `dlclose' function. */
#undef HAVE_DLCLOSE
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `dlopen' function. */
#undef HAVE_DLOPEN
/* Define to 1 if you have the `dlsym' function. */
#undef HAVE_DLSYM
/* Define if getaddrinfo accepts the AI_ADDRCONFIG flag */
#undef HAVE_GAI_ADDRCONFIG
/* Define to 1 if you have the `getaddrinfo' function. */
#undef HAVE_GETADDRINFO
/* Define to 1 if you have the `getpagesize' function. */
#undef HAVE_GETPAGESIZE
/* Define to 1 if you have the `getuid' function. */
#undef HAVE_GETUID
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <langinfo.h> header file. */
#undef HAVE_LANGINFO_H
/* Define to 1 if you have the `m' library (-lm). */
#undef HAVE_LIBM
/* Define to 1 if you have the `mx' library (-lmx). */
#undef HAVE_LIBMX
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define to 1 if you have the <linux/soundcard.h> header file. */
#undef HAVE_LINUX_SOUNDCARD_H
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define to 1 if you have the <machine/soundcard.h> header file. */
#undef HAVE_MACHINE_SOUNDCARD_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `mkfifo' function. */
#undef HAVE_MKFIFO
/* Define to 1 if you have a working `mmap' system call. */
#undef HAVE_MMAP
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <netinet/tcp.h> header file. */
#undef HAVE_NETINET_TCP_H
/* Define to 1 if you have the `nl_langinfo' function. */
#undef HAVE_NL_LANGINFO
/* Define to 1 if you have the <OpenAL/alc.h> header file. */
#undef HAVE_OPENAL_ALC_H
/* Define to 1 if you have the <OpenAL/al.h> header file. */
#undef HAVE_OPENAL_AL_H
/* Define to 1 if you have the <os2me.h> header file. */
#undef HAVE_OS2ME_H
/* Define to 1 if you have the <os2.h> header file. */
#undef HAVE_OS2_H
/* Define to 1 if you have the `random' function. */
#undef HAVE_RANDOM
/* Define to 1 if you have the <sched.h> header file. */
#undef HAVE_SCHED_H
/* Define to 1 if you have the `sched_setscheduler' function. */
#undef HAVE_SCHED_SETSCHEDULER
/* Define to 1 if you have the `setlocale' function. */
#undef HAVE_SETLOCALE
/* Define to 1 if you have the `setpriority' function. */
#undef HAVE_SETPRIORITY
/* Define to 1 if you have the `setuid' function. */
#undef HAVE_SETUID
/* Define to 1 if you have the <signal.h> header file. */
#undef HAVE_SIGNAL_H
/* Define to 1 if you have the <sndio.h> header file. */
#undef HAVE_SNDIO_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sun/audioio.h> header file. */
#undef HAVE_SUN_AUDIOIO_H
/* Define to 1 if you have the <sys/audioio.h> header file. */
#undef HAVE_SYS_AUDIOIO_H
/* Define to 1 if you have the <sys/audio.h> header file. */
#undef HAVE_SYS_AUDIO_H
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/signal.h> header file. */
#undef HAVE_SYS_SIGNAL_H
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/soundcard.h> header file. */
#undef HAVE_SYS_SOUNDCARD_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
/* Define this if you have the POSIX termios library */
#undef HAVE_TERMIOS
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the <windows.h> header file. */
#undef HAVE_WINDOWS_H
/* Define to 1 if you have the <ws2tcpip.h> header file. */
#undef HAVE_WS2TCPIP_H
/* Define to indicate that float storage follows IEEE754. */
#undef IEEE_FLOAT
/* size of the frame index seek table */
#undef INDEX_SIZE
/* Define if IPV6 support is enabled. */
#undef IPV6
/* Define this to the size of native offset type in bits, used for LFS alias
functions. */
#undef LFS_ALIAS_BITS
/* Define to the extension used for runtime loadable modules, say, ".so". */
#undef LT_MODULE_EXT
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
/* Define to the shared library suffix, say, ".dylib". */
#undef LT_SHARED_EXT
/* Define to the shared archive member specification, say "(shr.o)". */
#undef LT_SHARED_LIB_MEMBER
/* Define if network support is enabled. */
#undef NETWORK
/* Define to disable 16 bit integer output. */
#undef NO_16BIT
/* Define to disable 32 bit and 24 bit integer output. */
#undef NO_32BIT
/* Define to disable 8 bit integer output. */
#undef NO_8BIT
/* Define to disable downsampled decoding. */
#undef NO_DOWNSAMPLE
/* Define to disable equalizer. */
#undef NO_EQUALIZER
/* Define to disable error messages in combination with a return value (the
return is left intact). */
#undef NO_ERETURN
/* Define to disable error messages. */
#undef NO_ERRORMSG
/* Define to disable feeder and buffered readers. */
#undef NO_FEEDER
/* Define to disable ICY handling. */
#undef NO_ICY
/* Define to disable ID3v2 parsing. */
#undef NO_ID3V2
/* Define to disable layer I. */
#undef NO_LAYER1
/* Define to disable layer II. */
#undef NO_LAYER2
/* Define to disable layer III. */
#undef NO_LAYER3
/* Define to disable ntom resampling. */
#undef NO_NTOM
/* Define to disable real output. */
#undef NO_REAL
/* Define to disable string functions. */
#undef NO_STRING
/* Define for post-processed 32 bit formats. */
#undef NO_SYNTH32
/* Define to disable warning messages. */
#undef NO_WARNING
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define if portaudio v18 API is wanted. */
#undef PORTAUDIO18
/* The size of `int32_t', as computed by sizeof. */
#undef SIZEOF_INT32_T
/* The size of `long', as computed by sizeof. */
#undef SIZEOF_LONG
/* The size of `off_t', as computed by sizeof. */
#undef SIZEOF_OFF_T
/* The size of `size_t', as computed by sizeof. */
#undef SIZEOF_SIZE_T
/* The size of `ssize_t', as computed by sizeof. */
#undef SIZEOF_SSIZE_T
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define if modules are enabled */
#undef USE_MODULES
/* Define for new Huffman decoding scheme. */
#undef USE_NEW_HUFFTABLE
/* Define to use yasm for assemble AVX sources. */
#undef USE_YASM_FOR_AVX
/* Version number of package */
#undef VERSION
/* Define to use Win32 named pipes */
#undef WANT_WIN32_FIFO
/* Define to use Win32 sockets */
#undef WANT_WIN32_SOCKETS
/* Define to use Unicode for Windows */
#undef WANT_WIN32_UNICODE
/* WinXP and above for ipv6 */
#undef WINVER
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* WinXP and above for ipv6 */
#undef _WIN32_WINNT
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to `short' if <sys/types.h> does not define. */
#undef int16_t
/* Define to `int' if <sys/types.h> does not define. */
#undef int32_t
/* Define to `long long' if <sys/types.h> does not define. */
#undef int64_t
/* Define to the native offset type (long or actually off_t). */
#undef lfs_alias_t
/* Define to `long int' if <sys/types.h> does not define. */
#undef off_t
/* Define to `unsigned long' if <sys/types.h> does not define. */
#undef size_t
/* Define to `long' if <sys/types.h> does not define. */
#undef ssize_t
/* Define to `unsigned short' if <sys/types.h> does not define. */
#undef uint16_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef uint32_t
/* Define to `unsigned long' if <sys/types.h> does not define. */
#undef uintptr_t

View File

@ -0,0 +1,832 @@
/*
control_generic.c: control interface for frontends and real console warriors
copyright 1997-99,2004-8 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Andreas Neuhaus and Michael Hipp
reworked by Thomas Orgis - it was the entry point for eventually becoming maintainer...
*/
#include "config.h"
/* _BSD_SOURCE needed for setlinebuf, erm, but that's deprecated
so trying _DEFAULT_SOURCE */
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE
#endif
/* Defining that after _DEFAULT_SOURCE seems fine and is still
needed for older glibc. I guess I need a configure check
about setlinebuf()/setvbuf() if I really care about old
systems. */
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
#endif
#include "compat.h"
#include "mpg123app.h"
#include "out123.h"
#include <stdarg.h>
#include <ctype.h>
#if !defined (WIN32) || defined (__CYGWIN__)
#include <sys/wait.h>
#include <sys/socket.h>
#endif
#include <errno.h>
#include <string.h>
#include "common.h"
#include "genre.h"
#include "playlist.h"
#include "audio.h"
#define MODE_STOPPED 0
#define MODE_PLAYING 1
#define MODE_PAUSED 2
extern out123_handle *ao;
#ifdef FIFO
#include <sys/stat.h>
int control_file = STDIN_FILENO;
#else
#define control_file STDIN_FILENO
#ifdef WANT_WIN32_FIFO
#error Control interface does not work on win32 stdin
#endif /* WANT_WIN32_FIFO */
#endif
FILE *outstream;
static int mode = MODE_STOPPED;
static int init = 0;
#include "debug.h"
void generic_sendmsg (const char *fmt, ...)
{
va_list ap;
fprintf(outstream, "@");
va_start(ap, fmt);
vfprintf(outstream, fmt, ap);
va_end(ap);
fprintf(outstream, "\n");
}
/* Split up a number of lines separated by \n, \r, both or just zero byte
and print out each line with specified prefix. */
static void generic_send_lines(const char* fmt, mpg123_string *inlines)
{
size_t i;
int hadcr = 0, hadlf = 0;
char *lines = NULL;
char *line = NULL;
size_t len = 0;
if(inlines != NULL && inlines->fill)
{
lines = inlines->p;
len = inlines->fill;
}
else return;
line = lines;
for(i=0; i<len; ++i)
{
if(lines[i] == '\n' || lines[i] == '\r' || lines[i] == 0)
{
char save = lines[i]; /* saving, changing, restoring a byte in the data */
if(save == '\n') ++hadlf;
if(save == '\r') ++hadcr;
if((hadcr || hadlf) && hadlf % 2 == 0 && hadcr % 2 == 0) line = "";
if(line)
{
lines[i] = 0;
generic_sendmsg(fmt, line);
line = NULL;
lines[i] = save;
}
}
else
{
hadlf = hadcr = 0;
if(line == NULL) line = lines+i;
}
}
}
void generic_sendstat (mpg123_handle *fr)
{
off_t current_frame, frames_left;
double current_seconds, seconds_left;
if(!mpg123_position(fr, 0, out123_buffered(ao), &current_frame, &frames_left, &current_seconds, &seconds_left))
generic_sendmsg("F %"OFF_P" %"OFF_P" %3.2f %3.2f", (off_p)current_frame, (off_p)frames_left, current_seconds, seconds_left);
}
static void generic_sendv1(mpg123_id3v1 *v1, const char *prefix)
{
int i;
char info[125] = "";
memcpy(info, v1->title, 30);
memcpy(info+30, v1->artist, 30);
memcpy(info+60, v1->album, 30);
memcpy(info+90, v1->year, 4);
memcpy(info+94, v1->comment, 30);
for(i=0;i<124; ++i) if(info[i] == 0) info[i] = ' ';
info[i] = 0;
generic_sendmsg("%s ID3:%s%s", prefix, info, (v1->genre<=genre_count) ? genre_table[v1->genre] : "Unknown");
generic_sendmsg("%s ID3.genre:%i", prefix, v1->genre);
if(v1->comment[28] == 0 && v1->comment[29] != 0)
generic_sendmsg("%s ID3.track:%i", prefix, (unsigned char)v1->comment[29]);
}
static void generic_sendinfoid3(mpg123_handle *mh)
{
mpg123_id3v1 *v1;
mpg123_id3v2 *v2;
if(MPG123_OK != mpg123_id3(mh, &v1, &v2))
{
error1("Cannot get ID3 data: %s", mpg123_strerror(mh));
return;
}
if(v1 != NULL)
{
generic_sendv1(v1, "I");
}
if(v2 != NULL)
{
generic_send_lines("I ID3v2.title:%s", v2->title);
generic_send_lines("I ID3v2.artist:%s", v2->artist);
generic_send_lines("I ID3v2.album:%s", v2->album);
generic_send_lines("I ID3v2.year:%s", v2->year);
generic_send_lines("I ID3v2.comment:%s", v2->comment);
generic_send_lines("I ID3v2.genre:%s", v2->genre);
}
}
void generic_sendalltag(mpg123_handle *mh)
{
mpg123_id3v1 *v1;
mpg123_id3v2 *v2;
generic_sendmsg("T {");
if(MPG123_OK != mpg123_id3(mh, &v1, &v2))
{
error1("Cannot get ID3 data: %s", mpg123_strerror(mh));
v2 = NULL;
v1 = NULL;
}
if(v1 != NULL) generic_sendv1(v1, "T");
if(v2 != NULL)
{
size_t i;
for(i=0; i<v2->texts; ++i)
{
char id[5];
memcpy(id, v2->text[i].id, 4);
id[4] = 0;
generic_sendmsg("T ID3v2.%s:", id);
generic_send_lines("T =%s", &v2->text[i].text);
}
for(i=0; i<v2->extras; ++i)
{
char id[5];
memcpy(id, v2->extra[i].id, 4);
id[4] = 0;
generic_sendmsg("T ID3v2.%s desc(%s):",
id,
v2->extra[i].description.fill ? v2->extra[i].description.p : "" );
generic_send_lines("T =%s", &v2->extra[i].text);
}
for(i=0; i<v2->comments; ++i)
{
char id[5];
char lang[4];
memcpy(id, v2->comment_list[i].id, 4);
id[4] = 0;
memcpy(lang, v2->comment_list[i].lang, 3);
lang[3] = 0;
generic_sendmsg("T ID3v2.%s lang(%s) desc(%s):",
id, lang,
v2->comment_list[i].description.fill ? v2->comment_list[i].description.p : "");
generic_send_lines("T =%s", &v2->comment_list[i].text);
}
}
generic_sendmsg("T }");
}
void generic_sendinfo (char *filename)
{
char *s, *t;
s = strrchr(filename, '/');
if (!s)
s = filename;
else
s++;
t = strrchr(s, '.');
if (t)
*t = 0;
generic_sendmsg("I %s", s);
}
static void generic_load(mpg123_handle *fr, char *arg, int state)
{
out123_drop(ao);
if(mode != MODE_STOPPED)
{
close_track();
mode = MODE_STOPPED;
}
if(!open_track(arg))
{
generic_sendmsg("E Error opening stream: %s", arg);
generic_sendmsg("P 0");
return;
}
mpg123_seek(fr, 0, SEEK_SET); /* This finds ID3v2 at beginning. */
if(mpg123_meta_check(fr) & MPG123_NEW_ID3)
{
generic_sendinfoid3(fr);
}
else generic_sendinfo(arg);
if(htd.icy_name.fill) generic_sendmsg("I ICY-NAME: %s", htd.icy_name.p);
if(htd.icy_url.fill) generic_sendmsg("I ICY-URL: %s", htd.icy_url.p);
mode = state;
init = 1;
generic_sendmsg(mode == MODE_PAUSED ? "P 1" : "P 2");
}
static void generic_loadlist(mpg123_handle *fr, char *arg)
{
/* arguments are two: first the index to play, then the URL */
long entry;
long i = 0;
char *file = NULL;
char *thefile = NULL;
/* I feel retarted with string parsing outside Perl. */
while(*arg && isspace(*arg)) ++arg;
entry = atol(arg);
while(*arg && !isspace(*arg)) ++arg;
while(*arg && isspace(*arg)) ++arg;
if(!*arg)
{
generic_sendmsg("E empty list name");
return;
}
/* Now got the plain playlist path in arg. On to evil manupulation of mpg123's playlist code. */
param.listname = arg;
param.listentry = 0; /* The playlist shall not filter. */
param.loop = 1;
param.shuffle = 0;
prepare_playlist(0, NULL);
while((file = get_next_file()))
{
++i;
/* semantics: 0 brings you to the last track */
if(entry == 0 || entry == i) thefile = file;
generic_sendmsg("I LISTENTRY %li: %s", i, file);
}
if(!i) generic_sendmsg("I LIST EMPTY");
/* If we have something to play, play it. */
if(thefile) generic_load(fr, thefile, MODE_PLAYING);
free_playlist(); /* Free memory after it is not needed anymore. */
}
int control_generic (mpg123_handle *fr)
{
struct timeval tv;
fd_set fds;
int n;
/* ThOr */
char alive = 1;
char silent = 0;
/* responses to stderr for frontends needing audio data from stdout */
if (param.remote_err)
outstream = stderr;
else
outstream = stdout;
#ifndef WIN32
setlinebuf(outstream);
#else /* perhaps just use setvbuf as it's C89 */
/*
fprintf(outstream, "You are on Win32 and want to use the control interface... tough luck: We need a replacement for select on STDIN first.\n");
return 0;
setvbuf(outstream, (char*)NULL, _IOLBF, 0);
*/
#endif
/* the command behaviour is different, so is the ID */
/* now also with version for command availability */
fprintf(outstream, "@R MPG123 (ThOr) v8\n");
#ifdef FIFO
if(param.fifo)
{
if(param.fifo[0] == 0)
{
error("You wanted an empty FIFO name??");
return 1;
}
#ifndef WANT_WIN32_FIFO
unlink(param.fifo);
if(mkfifo(param.fifo, 0666) == -1)
{
error2("Failed to create FIFO at %s (%s)", param.fifo, strerror(errno));
return 1;
}
debug("going to open named pipe ... blocking until someone gives command");
#endif /* WANT_WIN32_FIFO */
#ifdef WANT_WIN32_FIFO
control_file = win32_fifo_mkfifo(param.fifo);
#else
control_file = open(param.fifo,O_RDONLY);
#endif /* WANT_WIN32_FIFO */
debug("opened");
}
#endif
while (alive)
{
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(control_file, &fds);
/* play frame if no command needs to be processed */
if (mode == MODE_PLAYING) {
#ifdef WANT_WIN32_FIFO
n = win32_fifo_read_peek(&tv);
#else
n = select(32, &fds, NULL, NULL, &tv);
#endif
if (n == 0) {
if (!play_frame())
{
out123_pause(ao);
/* When the track ended, user may want to keep it open (to seek back),
so there is a decision between stopping and pausing at the end. */
if(param.keep_open)
{
mode = MODE_PAUSED;
/* Hm, buffer should be stopped already, shouldn't it? */
generic_sendmsg("P 1");
}
else
{
mode = MODE_STOPPED;
close_track();
generic_sendmsg("P 0");
}
continue;
}
if (init) {
print_remote_header(fr);
init = 0;
}
if(silent == 0)
{
generic_sendstat(fr);
if(mpg123_meta_check(fr) & MPG123_NEW_ICY)
{
char *meta;
if(mpg123_icy(fr, &meta) == MPG123_OK)
generic_sendmsg("I ICY-META: %s", meta != NULL ? meta : "<nil>");
}
}
}
}
else {
/* wait for command */
while (1) {
#ifdef WANT_WIN32_FIFO
n = win32_fifo_read_peek(NULL);
#else
n = select(32, &fds, NULL, NULL, NULL);
#endif
if (n > 0)
break;
}
}
/* on error */
if (n < 0) {
fprintf(stderr, "Error waiting for command: %s\n", strerror(errno));
return 1;
}
/* read & process commands */
if (n > 0)
{
short int len = 1; /* length of buffer */
char *cmd, *arg; /* variables for parsing, */
char *comstr = NULL; /* gcc thinks that this could be used uninitialited... */
char buf[REMOTE_BUFFER_SIZE];
short int counter;
char *next_comstr = buf; /* have it initialized for first command */
/* read as much as possible, maybe multiple commands */
/* When there is nothing to read (EOF) or even an error, it is the end */
#ifdef WANT_WIN32_FIFO
len = win32_fifo_read(buf,REMOTE_BUFFER_SIZE);
#else
len = read(control_file, buf, REMOTE_BUFFER_SIZE);
#endif
if(len < 1)
{
#ifdef FIFO
if(len == 0 && param.fifo)
{
debug("fifo ended... reopening");
#ifdef WANT_WIN32_FIFO
win32_fifo_mkfifo(param.fifo);
#else
close(control_file);
control_file = open(param.fifo,O_RDONLY|O_NONBLOCK);
#endif
if(control_file < 0){ error1("open of fifo failed... %s", strerror(errno)); break; }
continue;
}
#endif
if(len < 0) error1("command read error: %s", strerror(errno));
break;
}
debug1("read %i bytes of commands", len);
/* one command on a line - separation by \n -> C strings in a row */
for(counter = 0; counter < len; ++counter)
{
/* line end is command end */
if( (buf[counter] == '\n') || (buf[counter] == '\r') )
{
debug1("line end at counter=%i", counter);
buf[counter] = 0; /* now it's a properly ending C string */
comstr = next_comstr;
/* skip the additional line ender of \r\n or \n\r */
if( (counter < (len - 1)) && ((buf[counter+1] == '\n') || (buf[counter+1] == '\r')) ) buf[++counter] = 0;
/* next "real" char is first of next command */
next_comstr = buf + counter+1;
/* directly process the command now */
debug1("interpreting command: %s", comstr);
if(strlen(comstr) == 0) continue;
/* PAUSE */
if (!strcasecmp(comstr, "P") || !strcasecmp(comstr, "PAUSE")) {
if(mode != MODE_STOPPED)
{
if (mode == MODE_PLAYING) {
mode = MODE_PAUSED;
out123_pause(ao);
generic_sendmsg("P 1");
} else {
mode = MODE_PLAYING;
out123_continue(ao);
generic_sendmsg("P 2");
}
} else generic_sendmsg("P 0");
continue;
}
/* STOP */
if (!strcasecmp(comstr, "S") || !strcasecmp(comstr, "STOP")) {
if (mode != MODE_STOPPED) {
/* Do we want to drop here? */
out123_drop(ao);
out123_pause(ao);
close_track();
mode = MODE_STOPPED;
generic_sendmsg("P 0");
} else generic_sendmsg("P 0");
continue;
}
/* SILENCE */
if(!strcasecmp(comstr, "SILENCE")) {
silent = 1;
generic_sendmsg("silence");
continue;
}
if(!strcasecmp(comstr, "T") || !strcasecmp(comstr, "TAG")) {
generic_sendalltag(fr);
continue;
}
if(!strcasecmp(comstr, "SCAN"))
{
if(mode != MODE_STOPPED)
{
if(mpg123_scan(fr) == MPG123_OK)
generic_sendmsg("SCAN done");
else
generic_sendmsg("E %s", mpg123_strerror(fr));
}
else generic_sendmsg("E No track loaded!");
continue;
}
if(!strcasecmp(comstr, "SAMPLE"))
{
off_t pos = mpg123_tell(fr);
off_t len = mpg123_length(fr);
/* I need to have portable printf specifiers that do not truncate the type... more autoconf... */
if(len < 0) generic_sendmsg("E %s", mpg123_strerror(fr));
else generic_sendmsg("SAMPLE %li %li", (long)pos, (long)len);
continue;
}
if(!strcasecmp(comstr, "FORMAT"))
{
long rate;
int ch;
int ret = mpg123_getformat2(fr, &rate, &ch, NULL, 0);
/* I need to have portable printf specifiers that do not truncate the type... more autoconf... */
if(ret < 0) generic_sendmsg("E %s", mpg123_strerror(fr));
else generic_sendmsg("FORMAT %li %i", rate, ch);
continue;
}
if(!strcasecmp(comstr, "SHOWEQ"))
{
int i;
generic_sendmsg("SHOWEQ {");
for(i=0; i<32; ++i)
{
generic_sendmsg("SHOWEQ %i : %i : %f", MPG123_LEFT, i, mpg123_geteq(fr, MPG123_LEFT, i));
generic_sendmsg("SHOWEQ %i : %i : %f", MPG123_RIGHT, i, mpg123_geteq(fr, MPG123_RIGHT, i));
}
generic_sendmsg("SHOWEQ }");
continue;
}
if(!strcasecmp(comstr, "STATE"))
{
long val;
generic_sendmsg("STATE {");
/* Get some state information bits and display them. */
if(mpg123_getstate(fr, MPG123_ACCURATE, &val, NULL) == MPG123_OK)
generic_sendmsg("STATE accurate %li", val);
generic_sendmsg("STATE }");
continue;
}
/* QUIT */
if (!strcasecmp(comstr, "Q") || !strcasecmp(comstr, "QUIT")){
alive = FALSE; continue;
}
/* some HELP */
if (!strcasecmp(comstr, "H") || !strcasecmp(comstr, "HELP")) {
generic_sendmsg("H {");
generic_sendmsg("H HELP/H: command listing (LONG/SHORT forms), command case insensitve");
generic_sendmsg("H LOAD/L <trackname>: load and start playing resource <trackname>");
generic_sendmsg("H LOADPAUSED/LP <trackname>: load but do not start playing resource <trackname>");
generic_sendmsg("H LOADLIST/LL <entry> <url>: load a playlist from given <url>, and display its entries, optionally load and play one of these specificed by the integer <entry> (<0: just list, 0: play last track, >0:play track with that position in list)");
generic_sendmsg("H PAUSE/P: pause playback");
generic_sendmsg("H STOP/S: stop playback (closes file)");
generic_sendmsg("H JUMP/J <frame>|<+offset>|<-offset>|<[+|-]seconds>s: jump to mpeg frame <frame> or change position by offset, same in seconds if number followed by \"s\"");
generic_sendmsg("H VOLUME/V <percent>: set volume in % (0..100...); float value");
generic_sendmsg("H RVA off|(mix|radio)|(album|audiophile): set rva mode");
generic_sendmsg("H EQ/E <channel> <band> <value>: set equalizer value for frequency band 0 to 31 on channel %i (left) or %i (right) or %i (both)", MPG123_LEFT, MPG123_RIGHT, MPG123_LR);
generic_sendmsg("H EQFILE <filename>: load EQ settings from a file");
generic_sendmsg("H SHOWEQ: show all equalizer settings (as <channel> <band> <value> lines in a SHOWEQ block (like TAG))");
generic_sendmsg("H SEEK/K <sample>|<+offset>|<-offset>: jump to output sample position <samples> or change position by offset");
generic_sendmsg("H SCAN: scan through the file, building seek index");
generic_sendmsg("H SAMPLE: print out the sample position and total number of samples");
generic_sendmsg("H FORMAT: print out sampling rate in Hz and channel count");
generic_sendmsg("H SEQ <bass> <mid> <treble>: simple eq setting...");
generic_sendmsg("H PITCH <[+|-]value>: adjust playback speed (+0.01 is 1 %% faster)");
generic_sendmsg("H SILENCE: be silent during playback (meaning silence in text form)");
generic_sendmsg("H STATE: Print auxiliary state info in several lines (just try it to see what info is there).");
generic_sendmsg("H TAG/T: Print all available (ID3) tag info, for ID3v2 that gives output of all collected text fields, using the ID3v2.3/4 4-character names. NOTE: ID3v2 data will be deleted on non-forward seeks.");
generic_sendmsg("H The output is multiple lines, begin marked by \"@T {\", end by \"@T }\".");
generic_sendmsg("H ID3v1 data is like in the @I info lines (see below), just with \"@T\" in front.");
generic_sendmsg("H An ID3v2 data field is introduced via ([ ... ] means optional):");
generic_sendmsg("H @T ID3v2.<NAME>[ [lang(<LANG>)] desc(<description>)]:");
generic_sendmsg("H The lines of data follow with \"=\" prefixed:");
generic_sendmsg("H @T =<one line of content in UTF-8 encoding>");
generic_sendmsg("H meaning of the @S stream info:");
generic_sendmsg("H %s", remote_header_help);
generic_sendmsg("H The @I lines after loading a track give some ID3 info, the format:");
generic_sendmsg("H @I ID3:artist album year comment genretext");
generic_sendmsg("H where artist,album and comment are exactly 30 characters each, year is 4 characters, genre text unspecified.");
generic_sendmsg("H You will encounter \"@I ID3.genre:<number>\" and \"@I ID3.track:<number>\".");
generic_sendmsg("H Then, there is an excerpt of ID3v2 info in the structure");
generic_sendmsg("H @I ID3v2.title:Blabla bla Bla");
generic_sendmsg("H for every line of the \"title\" data field. Likewise for other fields (author, album, etc).");
generic_sendmsg("H }");
continue;
}
/* commands with arguments */
cmd = NULL;
arg = NULL;
cmd = strtok(comstr," \t"); /* get the main command */
arg = strtok(NULL,""); /* get the args */
if (cmd && strlen(cmd) && arg && strlen(arg))
{
#ifndef NO_EQUALIZER
/* Simple EQ: SEQ <BASS> <MID> <TREBLE> */
if (!strcasecmp(cmd, "SEQ")) {
double b,m,t;
int cn;
if(sscanf(arg, "%lf %lf %lf", &b, &m, &t) == 3)
{
/* Consider adding mpg123_seq()... but also, on could define a nicer courve for that. */
if ((t >= 0) && (t <= 3))
for(cn=0; cn < 1; ++cn) mpg123_eq(fr, MPG123_LEFT|MPG123_RIGHT, cn, b);
if ((m >= 0) && (m <= 3))
for(cn=1; cn < 2; ++cn) mpg123_eq(fr, MPG123_LEFT|MPG123_RIGHT, cn, m);
if ((b >= 0) && (b <= 3))
for(cn=2; cn < 32; ++cn) mpg123_eq(fr, MPG123_LEFT|MPG123_RIGHT, cn, t);
generic_sendmsg("bass: %f mid: %f treble: %f", b, m, t);
}
else generic_sendmsg("E invalid arguments for SEQ: %s", arg);
continue;
}
/* Equalizer control :) (JMG) */
if (!strcasecmp(cmd, "E") || !strcasecmp(cmd, "EQ")) {
double e; /* ThOr: equalizer is of type real... whatever that is */
int c, v;
/*generic_sendmsg("%s",updown);*/
if(sscanf(arg, "%i %i %lf", &c, &v, &e) == 3)
{
if(mpg123_eq(fr, c, v, e) == MPG123_OK)
generic_sendmsg("%i : %i : %f", c, v, e);
else
generic_sendmsg("E failed to set eq: %s", mpg123_strerror(fr));
}
else generic_sendmsg("E invalid arguments for EQ: %s", arg);
continue;
}
if(!strcasecmp(cmd, "EQFILE"))
{
equalfile = arg;
if(load_equalizer(fr) == 0)
generic_sendmsg("EQFILE done");
else
generic_sendmsg("E failed to parse given eq file");
continue;
}
#endif
/* SEEK to a sample offset */
if(!strcasecmp(cmd, "K") || !strcasecmp(cmd, "SEEK"))
{
off_t soff;
off_t oldpos;
off_t newpos;
char *spos = arg;
int whence = SEEK_SET;
if(mode == MODE_STOPPED)
{
generic_sendmsg("E No track loaded!");
continue;
}
oldpos = mpg123_tell(fr);
soff = (off_t) atobigint(spos);
if(spos[0] == '-' || spos[0] == '+') whence = SEEK_CUR;
if(0 > (soff = mpg123_seek(fr, soff, whence)))
{
generic_sendmsg("E Error while seeking: %s", mpg123_strerror(fr));
mpg123_seek(fr, 0, SEEK_SET);
}
out123_drop(ao);
newpos = mpg123_tell(fr);
if(newpos <= oldpos) mpg123_meta_free(fr);
generic_sendmsg("K %"OFF_P, (off_p)newpos);
continue;
}
/* JUMP */
if (!strcasecmp(cmd, "J") || !strcasecmp(cmd, "JUMP")) {
char *spos;
off_t offset;
off_t oldpos;
double secs;
spos = arg;
if(mode == MODE_STOPPED)
{
generic_sendmsg("E No track loaded!");
continue;
}
oldpos = framenum;
if(spos[strlen(spos)-1] == 's' && sscanf(arg, "%lf", &secs) == 1) offset = mpg123_timeframe(fr, secs);
else offset = atol(spos);
/* totally replaced that stuff - it never fully worked
a bit usure about why +pos -> spos+1 earlier... */
if (spos[0] == '-' || spos[0] == '+') offset += framenum;
if(0 > (framenum = mpg123_seek_frame(fr, offset, SEEK_SET)))
{
generic_sendmsg("E Error while seeking");
mpg123_seek_frame(fr, 0, SEEK_SET);
}
out123_drop(ao);
if(framenum <= oldpos) mpg123_meta_free(fr);
generic_sendmsg("J %d", framenum);
continue;
}
/* VOLUME in percent */
if(!strcasecmp(cmd, "V") || !strcasecmp(cmd, "VOLUME"))
{
double v;
mpg123_volume(fr, atof(arg)/100);
mpg123_getvolume(fr, &v, NULL, NULL); /* Necessary? */
generic_sendmsg("V %f%%", v * 100);
continue;
}
/* PITCH (playback speed) in percent */
if(!strcasecmp(cmd, "PITCH"))
{
double p;
if(sscanf(arg, "%lf", &p) == 1)
{
set_pitch(fr, ao, p);
generic_sendmsg("PITCH %f", param.pitch);
}
else generic_sendmsg("E invalid arguments for PITCH: %s", arg);
continue;
}
/* RVA mode */
if(!strcasecmp(cmd, "RVA"))
{
if(!strcasecmp(arg, "off")) param.rva = MPG123_RVA_OFF;
else if(!strcasecmp(arg, "mix") || !strcasecmp(arg, "radio")) param.rva = MPG123_RVA_MIX;
else if(!strcasecmp(arg, "album") || !strcasecmp(arg, "audiophile")) param.rva = MPG123_RVA_ALBUM;
mpg123_volume_change(fr, 0.);
generic_sendmsg("RVA %s", rva_name[param.rva]);
continue;
}
/* LOAD - actually play */
if (!strcasecmp(cmd, "L") || !strcasecmp(cmd, "LOAD")){ generic_load(fr, arg, MODE_PLAYING); continue; }
if (!strcasecmp(cmd, "LL") || !strcasecmp(cmd, "LOADLIST")){ generic_loadlist(fr, arg); continue; }
/* LOADPAUSED */
if (!strcasecmp(cmd, "LP") || !strcasecmp(cmd, "LOADPAUSED")){ generic_load(fr, arg, MODE_PAUSED); continue; }
/* no command matched */
generic_sendmsg("E Unknown command: %s", cmd); /* unknown command */
} /* end commands with arguments */
else generic_sendmsg("E Unknown command or no arguments: %s", comstr); /* unknown command */
} /* end of single command processing */
} /* end of scanning the command buffer */
/*
when last command had no \n... should I discard it?
Ideally, I should remember the part and wait for next
read() to get the rest up to a \n. But that can go
to infinity. Too long commands too quickly are just
bad. Cannot/Won't change that. So, discard the unfinished
command and have fingers crossed that the rest of this
unfinished one qualifies as "unknown".
*/
if(buf[len-1] != 0)
{
char lasti = buf[len-1];
buf[len-1] = 0;
generic_sendmsg("E Unfinished command: %s%c", comstr, lasti);
}
} /* end command reading & processing */
} /* end main (alive) loop */
debug("going to end");
/* quit gracefully */
debug("closing control");
#ifdef FIFO
#if WANT_WIN32_FIFO
win32_fifo_close();
#else
close(control_file); /* be it FIFO or STDIN */
if(param.fifo) unlink(param.fifo);
#endif /* WANT_WIN32_FIFO */
#endif
debug("control_generic returning");
return 0;
}
/* EOF */

View File

@ -0,0 +1,50 @@
/*
equalizer: code for loading equalizer settings
copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp (exported to this file by Thomas Orgis)
*/
#include "mpg123app.h"
/* Load the settings from the path in the global variable equalfile.
If there is no file, restore equalizer defaults.
If NO_EQUALIZER is defined, it does nothing else that return zero */
int load_equalizer(mpg123_handle *mh)
{
#ifndef NO_EQUALIZER
if(equalfile != NULL)
{ /* tst; ThOr: not TRUE or FALSE: allocated or not... */
FILE *fe;
int i;
fe = fopen(equalfile,"r");
if(fe) {
char line[256];
for(i=0;i<32;i++) {
float e0 = 1.0;
float e1 = 1.0; /* %f -> float! */
do /* ignore comments */
{
line[0]=0;
fgets(line,255,fe);
}
while(line[0]=='#');
/* Hm, why not use fscanf? Comments... */
sscanf(line,"%f %f",&e0,&e1);
/* If scanning failed, we have default 1.0 value. */
mpg123_eq(mh, MPG123_LEFT, i, e0);
mpg123_eq(mh, MPG123_RIGHT, i, e1);
}
fclose(fe);
}
else
{
fprintf(stderr,"Can't open equalizer file '%s'\n",equalfile);
return -1;
}
}
else mpg123_reset_eq(mh);
#endif
return 0;
}

View File

@ -0,0 +1,271 @@
/*
genre: id3 genre definition
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Shane Wegner
*/
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",
"Psychedelic",
"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);

View File

@ -0,0 +1,15 @@
/*
genre: id3 genre definition
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Shane Wegner
*/
#ifndef _MPG123_GENRE_H_
#define _MPG123_GENRE_H_
extern char *genre_table[];
extern const int genre_count;
#endif

View File

@ -0,0 +1,155 @@
/*
getlopt: command line option/parameter parsing
copyright ?-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written Oliver Fromme
old timestamp: Tue Apr 8 07:15:13 MET DST 1997
*/
#include "config.h"
#include "compat.h"
#include "getlopt.h"
#include "debug.h"
int loptind = 1; /* index in argv[] */
int loptchr = 0; /* index in argv[loptind] */
char *loptarg; /* points to argument if present, else to option */
topt *findopt (int islong, char *opt, topt *opts)
{
if (!opts)
return (0);
while (opts->lname) {
if (islong) {
if (!strcmp(opts->lname, opt))
return (opts);
}
else
if (opts->sname == *opt)
return (opts);
opts++;
}
return (0);
}
static int performoption (int argc, char *argv[], topt *opt)
{
int result = GLO_CONTINUE;
/* this really is not supposed to happen, so the exit may be justified to create asap ficing pressure */
#define prog_error() \
{ \
fprintf(stderr, __FILE__ ":%i Option without type flag! This is a programming error! Developer: fix this ASAP to regain your honor.\n", __LINE__); \
exit(1); \
}
debug2("performoption on %c / %s"
, opt->sname ? opt->sname : '_', opt->lname ? opt->lname : "");
if (!(opt->flags & GLO_ARG)) { /* doesn't take argument */
if (opt->var) {
if (opt->flags & GLO_CHAR) /* var is *char */
{
debug1("char at %p", opt->var);
*((char *) opt->var) = (char) opt->value;\
}
else if(opt->flags & GLO_LONG)
{
debug1("long at %p", opt->var);
*( (long *) opt->var ) = opt->value;
}
else if(opt->flags & GLO_INT)
{
debug1("int at %p", opt->var);
*( (int *) opt->var ) = (int) opt->value;
}
/* GLO_DOUBLE is not supported here */
else prog_error();
debug("casting assignment done");
}
#if 0 /* Oliver: What was this for?! --ThOr */
else
result = opt->value ? opt->value : opt->sname;
#endif
}
else { /* requires argument */
debug("argument required");
if (loptind >= argc)
return (GLO_NOARG);
loptarg = argv[loptind++]+loptchr;
loptchr = 0;
if (opt->var) {
if (opt->flags & GLO_CHAR) /* var is *char */
*((char **) opt->var) = compat_strdup(loptarg); /* valgrind claims lost memory here */
else if(opt->flags & GLO_LONG)
*((long *) opt->var) = atol(loptarg);
else if(opt->flags & GLO_INT)
*((int *) opt->var) = atoi(loptarg);
else if(opt->flags & GLO_DOUBLE)
*((double *) opt->var) = atof(loptarg);
else prog_error();
}
#if 0 /* Oliver: What was this for?! --ThOr */
else
result = opt->value ? opt->value : opt->sname;
#endif
}
if (opt->func)
opt->func(loptarg);
debug4("result: %i (%p, %li, %i)", result, opt->var, opt->value, opt->sname);
return (result);
}
int getsingleopt (int argc, char *argv[], topt *opts)
{
char *thisopt;
topt *opt;
static char shortopt[2] = {0, 0};
if (loptind >= argc)
return (GLO_END);
thisopt = argv[loptind];
debug1("getsingleopt: %s", thisopt);
if (!loptchr) { /* start new option string */
if (thisopt[0] != '-' || !thisopt[1]) /* no more options */
return (GLO_END);
if (thisopt[1] == '-') { /* "--" */
if (thisopt[2]) { /* long option */
loptarg = thisopt+2;
loptind++;
if (!(opt = findopt(1, thisopt+2, opts)))
return (GLO_UNKNOWN);
else
return (performoption(argc, argv, opt));
}
else { /* "--" == end of options */
loptind++;
return (GLO_END);
}
}
else /* start short option(s) */
loptchr = 1;
}
shortopt[0] = thisopt[loptchr];
loptarg = shortopt;
opt = findopt(0, thisopt+(loptchr++), opts);
if (!thisopt[loptchr]) {
loptind++;
loptchr = 0;
}
if (!opt)
return (GLO_UNKNOWN);
else
return (performoption(argc, argv, opt));
}
int getlopt (int argc, char *argv[], topt *opts)
{
int result;
while ((result = getsingleopt(argc, argv, opts)) == GLO_CONTINUE);
return (result);
}
/* EOF */

View File

@ -0,0 +1,77 @@
/*
getlopt: command line option/parameter parsing
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written Oliver Fromme
old timestamp: Tue Apr 8 07:13:39 MET DST 1997
*/
#include <stdlib.h>
#include <string.h>
#ifndef _MPG123_GETLOPT_H_
#define _MPG123_GETLOPT_H_
extern int loptind; /* index in argv[] */
extern int loptchr; /* index in argv[loptind] */
extern char *loptarg; /* points to argument if present, else to option */
typedef struct {
char sname; /* short option name, can be 0 */
char *lname; /* long option name, can be 0 */
int flags; /* see below */
void (*func)(char *); /* called if != 0 (after setting of var) */
void *var; /* type is *long, *char or **char, see below */
long value;
} topt;
/* ThOr: make this clear; distict long from int (since this is != on my Alpha) and really use a flag for every case (spare the 0 case
for .... no flag) */
#define GLO_ARG 1
#define GLO_CHAR 2
#define GLO_INT 4
#define GLO_LONG 8
#define GLO_DOUBLE 16
/* flags:
* bit 0 = 0 - no argument
* if var != NULL
* *var := value or (char)value [see bit 1]
* else
* loptarg = &option
* return ((value != 0) ? value : sname)
* bit 0 = 1 - argument required
* if var != NULL
* *var := atoi(arg) or strdup(arg) [see bit 1]
* else
* loptarg = &arg
* return ((value != 0) ? value : sname)
*
* bit 1 = 1 - var is a pointer to a char (or string),
* and value is interpreted as char
* bit 2 = 1 - var is a pointer to int
* bit 3 = 1 - var is a pointer to long
*
* Note: The options definition is terminated by a topt
* containing only zeroes.
*/
#define GLO_END 0
#define GLO_UNKNOWN -1
#define GLO_NOARG -2
#define GLO_CONTINUE -3
int getlopt (int argc, char *argv[], topt *opts);
/* return values:
* GLO_END (0) end of options
* GLO_UNKNOWN (-1) unknown option *loptarg
* GLO_NOARG (-2) missing argument
* GLO_CONTINUE (-3) (reserved for internal use)
* else - return value according to flags (see above)
*/
#endif

View File

@ -0,0 +1,731 @@
/*
httpget.c: http communication
copyright ?-2011 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written Oliver Fromme
old timestamp: Wed Apr 9 20:57:47 MET DST 1997
Thomas' notes:
;
I used to do
GET http://server/path HTTP/1.0
But RFC 1945 says: The absoluteURI form is only allowed when the request is being made to a proxy.
so I should not do that. Since name based virtual hosts need the hostname in the request, I still need to provide that info.
Enter HTTP/1.1... there is a Host eader field to use (that mpg123 supposedly has used since some time anyway - but did it really work with my vhost test server)?
Now
GET /path/bla HTTP/1.1\r\nHost: host[:port]
Should work, but as a funny sidenote:
RFC2616: To allow for transition to absoluteURIs in all requests in future versions of HTTP, all HTTP/1.1 servers MUST accept the absoluteURI form in requests, even though HTTP/1.1 clients will only generate them in requests to proxies.
I was already full-on HTTP/1.1 as I recognized that mpg123 then would have to accept the chunked transfer encoding.
That is not desireable for its purpose... maybe when interleaving of shoutcasts with metadata chunks is supported, we can upgrade to 1.1.
Funny aspect there is that shoutcast servers do not do HTTP/1.1 chunked transfer but implement some different chunking themselves...
*/
#include "mpg123app.h"
#include "httpget.h"
#ifdef NETWORK
#include "resolver.h"
#include <errno.h>
#include "true.h"
#endif
#include <ctype.h>
#include "debug.h"
void httpdata_init(struct httpdata *e)
{
mpg123_init_string(&e->content_type);
mpg123_init_string(&e->icy_url);
mpg123_init_string(&e->icy_name);
e->icy_interval = 0;
e->proxystate = PROXY_UNKNOWN;
mpg123_init_string(&e->proxyhost);
mpg123_init_string(&e->proxyport);
}
void httpdata_reset(struct httpdata *e)
{
mpg123_free_string(&e->content_type);
mpg123_free_string(&e->icy_url);
mpg123_free_string(&e->icy_name);
e->icy_interval = 0;
/* the other stuff shall persist */
}
void httpdata_free(struct httpdata *e)
{
httpdata_reset(e);
mpg123_free_string(&e->proxyhost);
mpg123_free_string(&e->proxyport);
}
/* mime type classes */
#define M_FILE 0
#define M_M3U 1
#define M_PLS 2
static const char* mime_file[] =
{
"audio/mpeg", "audio/x-mpeg",
"audio/mp3", "audio/x-mp3",
"audio/mpeg3", "audio/x-mpeg3",
"audio/mpg", "audio/x-mpg",
"audio/x-mpegaudio",
"application/octet-stream", /* Assume raw binary data is some MPEG data. */
NULL
};
static const char* mime_m3u[] = { "audio/mpegurl", "audio/mpeg-url", "audio/x-mpegurl", NULL };
static const char* mime_pls[] =
{
"audio/x-scpls"
, "audio/scpls"
, "application/pls"
, "application/x-scpls"
, "application/pls+xml"
, NULL
};
static const char** mimes[] = { mime_file, mime_m3u, mime_pls, NULL };
int debunk_mime(const char* mime)
{
int i,j;
size_t len;
int r = 0;
char *aux;
/* Watch out for such: "audio/x-mpegurl; charset=utf-8" */
aux = strchr(mime, ';');
if(aux != NULL)
{
if(!param.quiet)
fprintf(stderr, "Warning: additional info in content-type ignored (%s)\n", aux+1);
/* Just compare up to before the ";" */
len = aux-mime;
}
/* Else, compare the whole string -- including the end. */
else len = strlen(mime)+1;
/* Skip trailing whitespace, to ne nice to strange folks. */
while(len && isspace(mime[len-1])) --len;
for(i=0; mimes[i] != NULL; ++i)
for(j=0; mimes[i][j] != NULL; ++j)
if(!strncasecmp(mimes[i][j], mime, len)) goto debunk_result;
debunk_result:
if(mimes[i] != NULL)
{
switch(i)
{
case M_FILE: r = IS_FILE; break;
case M_M3U: r = IS_LIST|IS_M3U; break;
case M_PLS: r = IS_LIST|IS_PLS; break;
default: error("unexpected MIME debunk result -- coding error?!");
}
}
return r;
}
#ifdef NETWORK
#if !defined (WANT_WIN32_SOCKETS)
static int writestring (int fd, mpg123_string *string)
{
size_t result, bytes;
char *ptr = string->p;
bytes = string->fill ? string->fill-1 : 0;
while(bytes)
{
result = write(fd, ptr, bytes);
if(result < 0 && errno != EINTR)
{
perror ("writing http string");
return FALSE;
}
else if(result == 0)
{
error("write: socket closed unexpectedly");
return FALSE;
}
ptr += result;
bytes -= result;
}
return TRUE;
}
static size_t readstring (mpg123_string *string, size_t maxlen, int fd)
{
int err;
debug2("Attempting readstring on %d for %"SIZE_P" bytes", fd, (size_p)maxlen);
string->fill = 0;
while(maxlen == 0 || string->fill < maxlen)
{
if(string->size-string->fill < 1)
if(!mpg123_grow_string(string, string->fill+4096))
{
error("Cannot allocate memory for reading.");
string->fill = 0;
return 0;
}
err = read(fd,string->p+string->fill,1);
/* Whoa... reading one byte at a time... one could ensure the line break in another way, but more work. */
if( err == 1)
{
string->fill++;
if(string->p[string->fill-1] == '\n') break;
}
else if(errno != EINTR)
{
error("Error reading from socket or unexpected EOF.");
string->fill = 0;
/* bail out to prevent endless loop */
return 0;
}
}
if(!mpg123_grow_string(string, string->fill+1))
{
string->fill=0;
}
else
{
string->p[string->fill] = 0;
string->fill++;
}
return string->fill;
}
#endif /* WANT_WIN32_SOCKETS */
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;
}
/* Look out for HTTP header field to parse, construct C string with the value.
Attention: Modifies argument, since it's so convenient... */
char *get_header_val(const char *hname, mpg123_string *response)
{
char *tmp = NULL;
size_t prelen = strlen(hname);
/* if header name found, next char is at least something, so just check for : */
if(!strncasecmp(hname, response->p, prelen) && (response->p[prelen] == ':'))
{
++prelen;
if((tmp = strchr(response->p, '\r')) != NULL ) tmp[0] = 0;
if((tmp = strchr(response->p, '\n')) != NULL ) tmp[0] = 0;
tmp = response->p+prelen;
/* I _know_ that there is a terminating zero, so this loop is safe. */
while((tmp[0] == ' ') || (tmp[0] == '\t'))
{
++tmp;
}
}
return tmp;
}
/* Iterate over header field names and storage locations, to possibly get those values. */
void get_header_string(mpg123_string *response, const char *fieldname, mpg123_string *store)
{
char *tmp;
if((tmp = get_header_val(fieldname, response)))
{
if(mpg123_set_string(store, tmp)){ debug2("got %s %s", fieldname, store->p); return; }
else{ error2("unable to set %s to %s!", fieldname, tmp); }
}
}
/* shoutcsast meta data: 1=on, 0=off */
char *httpauth = NULL;
size_t accept_length(void)
{
int i,j;
static size_t l = 0;
if(l) return l;
l += strlen("Accept: ");
for(i=0; mimes[i] != NULL; ++i)
for(j=0; mimes[i][j] != NULL; ++j){ l += strlen(mimes[i][j]) + strlen(", "); }
l += strlen("*/*\r\n");
debug1("initial computation of accept header length: %lu", (unsigned long)l);
return l;
}
/* Returns TRUE or FALSE for success. */
int proxy_init(struct httpdata *hd)
{
int ret = TRUE;
/* If we don't have explicit proxy given, probe the environment. */
if (!param.proxyurl)
if (!(param.proxyurl = getenv("MP3_HTTP_PROXY")))
if (!(param.proxyurl = getenv("http_proxy")))
param.proxyurl = getenv("HTTP_PROXY");
/* Now continue if we have something. */
if (param.proxyurl && param.proxyurl[0] && strcmp(param.proxyurl, "none"))
{
mpg123_string proxyurl;
mpg123_init_string(&proxyurl);
if( !mpg123_set_string(&proxyurl, param.proxyurl)
|| !split_url(&proxyurl, NULL, &hd->proxyhost, &hd->proxyport, NULL))
{
error("splitting proxy URL");
ret = FALSE;
}
else if(param.verbose > 1) fprintf(stderr, "Note: Using proxy %s\n", hd->proxyhost.p);
#if 0 /* not yet there */
if(!try_host_lookup(proxyhost))
{
error("Unknown proxy host \"%s\".\n", proxyhost.p);
ret = FALSE;
}
#endif
mpg123_free_string(&proxyurl);
if(ret) hd->proxystate = PROXY_HOST; /* We got hostname and port settled. */
else hd->proxystate = PROXY_NONE;
}
else hd->proxystate = PROXY_NONE;
return ret;
}
static int append_accept(mpg123_string *s)
{
size_t i,j;
if(!mpg123_add_string(s, "Accept: ")) return FALSE;
/* We prefer what we know. */
for(i=0; mimes[i] != NULL; ++i)
for(j=0; mimes[i][j] != NULL; ++j)
{
if( !mpg123_add_string(s, mimes[i][j])
|| !mpg123_add_string(s, ", ") )
return FALSE;
}
/* Well... in the end, we accept everything, trying to make sense with reality. */
if(!mpg123_add_string(s, "*/*\r\n")) return FALSE;
return TRUE;
}
/*
Converts spaces to "%20" ... actually, I have to ask myself why.
What about converting them to "+" instead? Would make things a lot easier.
Or, on the other hand... what about avoiding HTML encoding at all?
*/
int translate_url(const char *url, mpg123_string *purl)
{
const char *sptr;
/* The length of purl is upper bound by 3*strlen(url) + 1 if
* everything in it is a space (%20) - or any encoded character */
if (strlen(url) >= SIZE_MAX/3)
{
error("URL too long. Skipping...");
return FALSE;
}
/* Prepare purl in one chunk, to minimize mallocs. */
if(!mpg123_resize_string(purl, strlen(url) + 31)) return FALSE;
/*
* 2000-10-21:
* We would like spaces to be automatically converted to %20's when
* fetching via HTTP.
* -- Martin Sj<53>gren <md9ms@mdstud.chalmers.se>
* Hm, why only spaces? Maybe one should do this http stuff more properly...
*/
if ((sptr = strchr(url, ' ')) == NULL)
mpg123_set_string(purl, url);
else
{ /* Note that sptr is set from the if to this else... */
const char *urlptr = url;
mpg123_set_string(purl, "");
do {
if(! ( mpg123_add_substring(purl, urlptr, 0, sptr-urlptr)
&& mpg123_add_string(purl, "%20") ) )
return FALSE;
urlptr = sptr + 1;
} while ((sptr = strchr (urlptr, ' ')) != NULL);
if(!mpg123_add_string(purl, urlptr)) return FALSE;
}
/* now see if a terminating / may be needed */
if(strchr(purl->p+(strncmp("http://", purl->p, 7) ? 0 : 7), '/') == NULL
&& !mpg123_add_string(purl, "/"))
return FALSE;
return TRUE;
}
int fill_request(mpg123_string *request, mpg123_string *host, mpg123_string *port, mpg123_string *httpauth1, int *try_without_port)
{
char* ttemp;
int ret = TRUE;
const char *icy = param.talk_icy ? icy_yes : icy_no;
/* hm, my test redirection had troubles with line break before HTTP/1.0 */
if((ttemp = strchr(request->p,'\r')) != NULL){ *ttemp = 0; request->fill = ttemp-request->p+1; }
if((ttemp = strchr(request->p,'\n')) != NULL){ *ttemp = 0; request->fill = ttemp-request->p+1; }
/* Fill out the request further... */
if( !mpg123_add_string(request, " HTTP/1.0\r\nUser-Agent: ")
|| !mpg123_add_string(request, PACKAGE_NAME)
|| !mpg123_add_string(request, "/")
|| !mpg123_add_string(request, PACKAGE_VERSION)
|| !mpg123_add_string(request, "\r\n") )
return FALSE;
if(host->fill)
{ /* Give virtual hosting a chance... adding the "Host: ... " line. */
debug2("Host: %s:%s", host->p, port->p);
if( mpg123_add_string(request, "Host: ")
&& mpg123_add_string(request, host->p)
&& ( *try_without_port || (
mpg123_add_string(request, ":")
&& mpg123_add_string(request, port->p) ))
&& mpg123_add_string(request, "\r\n") )
{
if(*try_without_port) *try_without_port = 0;
}
else return FALSE;
}
/* Acceptance, stream setup. */
if( !append_accept(request)
|| !mpg123_add_string(request, CONN_HEAD)
|| !mpg123_add_string(request, icy) )
return FALSE;
/* Authorization. */
if (httpauth1->fill || httpauth) {
char *buf;
if(!mpg123_add_string(request,"Authorization: Basic ")) return FALSE;
if(httpauth1->fill) {
if(httpauth1->fill > SIZE_MAX / 4) return FALSE;
buf=(char *)malloc(httpauth1->fill * 4);
if(!buf)
{
error("malloc() failed for http auth, out of memory.");
return FALSE;
}
encode64(httpauth1->p,buf);
} else {
if(strlen(httpauth) > SIZE_MAX / 4 - 4 ) return FALSE;
buf=(char *)malloc((strlen(httpauth) + 1) * 4);
if(!buf)
{
error("malloc() for http auth failed, out of memory.");
return FALSE;
}
encode64(httpauth,buf);
}
if( !mpg123_add_string(request, buf) || !mpg123_add_string(request, "\r\n"))
ret = FALSE;
free(buf); /* Watch out for leaking if you introduce returns before this line. */
}
if(ret) ret = mpg123_add_string(request, "\r\n");
return ret;
}
#if !defined (WANT_WIN32_SOCKETS)
static int resolve_redirect(mpg123_string *response, mpg123_string *request_url, mpg123_string *purl)
{
debug1("request_url:%s", request_url->p);
/* initialized with full old url */
if(!mpg123_copy_string(request_url, purl)) return FALSE;
/* We may strip it down to a prefix ot totally. */
if(strncasecmp(response->p, "Location: http://", 17))
{ /* OK, only partial strip, need prefix for relative path. */
char* ptmp = NULL;
/* though it's not RFC (?), accept relative URIs as wget does */
fprintf(stderr, "NOTE: no complete URL in redirect, constructing one\n");
/* not absolute uri, could still be server-absolute */
/* I prepend a part of the request... out of the request */
if(response->p[10] == '/')
{
/* only prepend http://server/ */
/* I null the first / after http:// */
ptmp = strchr(purl->p+7,'/');
if(ptmp != NULL){ purl->fill = ptmp-purl->p+1; purl->p[purl->fill-1] = 0; }
}
else
{
/* prepend http://server/path/ */
/* now we want the last / */
ptmp = strrchr(purl->p+7, '/');
if(ptmp != NULL){ purl->fill = ptmp-purl->p+2; purl->p[purl->fill-1] = 0; }
}
}
else purl->fill = 0;
debug1("prefix=%s", purl->fill ? purl->p : "");
if(!mpg123_add_string(purl, response->p+10)) return FALSE;
debug1(" purl: %s", purl->p);
debug1("old request_url: %s", request_url->p);
return TRUE;
}
int http_open(char* url, struct httpdata *hd)
{
mpg123_string purl, host, port, path;
mpg123_string request, response, request_url;
mpg123_string httpauth1;
int sock = -1;
int oom = 0;
int relocate, numrelocs = 0;
int got_location = FALSE;
/*
workaround for http://www.global24music.com/rautemusik/files/extreme/isdn.pls
this site's apache gives me a relocation to the same place when I give the port in Host request field
for the record: Apache/2.0.51 (Fedora)
*/
int try_without_port = 0;
mpg123_init_string(&purl);
mpg123_init_string(&host);
mpg123_init_string(&port);
mpg123_init_string(&path);
mpg123_init_string(&request);
mpg123_init_string(&response);
mpg123_init_string(&request_url);
mpg123_init_string(&httpauth1);
/* Get initial info for proxy server. Once. */
if(hd->proxystate == PROXY_UNKNOWN && !proxy_init(hd)) goto exit;
if(!translate_url(url, &purl)){ oom=1; goto exit; }
/* Don't confuse the different auth strings... */
if(!split_url(&purl, &httpauth1, NULL, NULL, NULL) ){ oom=1; goto exit; }
/* "GET http://" 11
* " HTTP/1.0\r\nUser-Agent: <PACKAGE_NAME>/<PACKAGE_VERSION>\r\n"
* 26 + PACKAGE_NAME + PACKAGE_VERSION
* accept header + accept_length()
* "Authorization: Basic \r\n" 23
* "\r\n" 2
* ... plus the other predefined header lines
*/
/* Just use this estimate as first guess to reduce malloc calls in string library. */
{
size_t length_estimate = 62 + strlen(PACKAGE_NAME) + strlen(PACKAGE_VERSION)
+ accept_length() + strlen(CONN_HEAD) + strlen(icy_yes) + purl.fill;
if( !mpg123_grow_string(&request, length_estimate)
|| !mpg123_grow_string(&response,4096) )
{
oom=1; goto exit;
}
}
do
{
/* Storing the request url, with http:// prepended if needed. */
/* used to be url here... seemed wrong to me (when loop advanced...) */
if(strncasecmp(purl.p, "http://", 7) != 0) mpg123_set_string(&request_url, "http://");
else mpg123_set_string(&request_url, "");
mpg123_chomp_string(&purl);
mpg123_add_string(&request_url, purl.p);
/* Always store the host and port from the URL for correct host header
in the request. Proxy server is used for connection, but never in the
host header! */
if(!split_url(&purl, NULL, &host, &port, &path)){ oom=1; goto exit; }
if (hd->proxystate >= PROXY_HOST)
{
/* We will connect to proxy, full URL goes into the request. */
if( !mpg123_set_string(&request, "GET ")
|| !mpg123_add_string(&request, request_url.p) )
{
oom=1; goto exit;
}
}
else
{
/* We will connect to the host from the URL and only the path goes into the request. */
if( !mpg123_set_string(&request, "GET ")
|| !mpg123_add_string(&request, path.p) )
{
oom=1; goto exit;
}
}
if(!fill_request(&request, &host, &port, &httpauth1, &try_without_port)){ oom=1; goto exit; }
httpauth1.fill = 0; /* We use the auth data from the URL only once. */
if (hd->proxystate >= PROXY_HOST)
{
/* Only the host:port used for actual connection is replaced by
proxy. */
if( !mpg123_copy_string(&hd->proxyhost, &host)
|| !mpg123_copy_string(&hd->proxyport, &port) )
{
oom=1; goto exit;
}
}
debug2("attempting to open_connection to %s:%s", host.p, port.p);
sock = open_connection(&host, &port);
if(sock < 0)
{
error1("Unable to establish connection to %s", host.fill ? host.p : "");
goto exit;
}
#define http_failure close(sock); sock=-1; goto exit;
if(param.verbose > 2) fprintf(stderr, "HTTP request:\n%s\n",request.p);
if(!writestring(sock, &request)){ http_failure; }
relocate = FALSE;
/* Arbitrary length limit here... */
#define safe_readstring \
readstring(&response, SIZE_MAX/16, sock); \
if(response.fill > SIZE_MAX/16) /* > because of appended zero. */ \
{ \
error("HTTP response line exceeds max. length"); \
http_failure; \
} \
else if(response.fill == 0) \
{ \
error("readstring failed"); \
http_failure; \
} \
if(param.verbose > 2) fprintf(stderr, "HTTP in: %s", response.p);
safe_readstring;
{
char *sptr;
if((sptr = strchr(response.p, ' ')))
{
if(response.fill > sptr-response.p+2)
switch (sptr[1])
{
case '3':
relocate = TRUE;
case '2':
break;
default:
fprintf (stderr, "HTTP request failed: %s", sptr+1); /* '\n' is included */
http_failure;
}
else{ error("Too short response,"); http_failure; }
}
}
/* If we are relocated, we need to look out for a Location header. */
got_location = FALSE;
do
{
safe_readstring; /* Think about that: Should we really error out when we get nothing? Could be that the server forgot the trailing empty line... */
if (!strncasecmp(response.p, "Location: ", 10))
{ /* It is a redirection! */
if(!resolve_redirect(&response, &request_url, &purl)){ oom=1, http_failure; }
if(!strcmp(purl.p, request_url.p))
{
warning("relocated to very same place! trying request again without host port");
try_without_port = 1;
}
got_location = TRUE;
}
else
{ /* We got a header line (or the closing empty line). */
char *tmp;
debug1("searching for header values... %s", response.p);
/* Not sure if I want to bail out on error here. */
/* Also: What text encoding are these strings in? Doesn't need to be plain ASCII... */
get_header_string(&response, "content-type", &hd->content_type);
get_header_string(&response, "icy-name", &hd->icy_name);
get_header_string(&response, "icy-url", &hd->icy_url);
/* watch out for icy-metaint */
if((tmp = get_header_val("icy-metaint", &response)))
{
hd->icy_interval = (off_t) atol(tmp); /* atoll ? */
debug1("got icy-metaint %li", (long int)hd->icy_interval);
}
}
} while(response.p[0] != '\r' && response.p[0] != '\n');
if(relocate)
{
close(sock);
sock = -1;
/* Forget content type, might just relate to a displayed error page,
not the resource being redirected to. */
mpg123_free_string(&hd->content_type);
mpg123_init_string(&hd->content_type);
}
} while(relocate && got_location && purl.fill && numrelocs++ < HTTP_MAX_RELOCATIONS);
if(relocate)
{
if(!got_location)
error("Server meant to redirect but failed to provide a location!");
else
error1("Too many HTTP relocations (%i).", numrelocs);
http_failure;
}
exit: /* The end as well as the exception handling point... */
if(oom) error("Apparently, I ran out of memory or had some bad input data...");
mpg123_free_string(&purl);
mpg123_free_string(&host);
mpg123_free_string(&port);
mpg123_free_string(&path);
mpg123_free_string(&request);
mpg123_free_string(&response);
mpg123_free_string(&request_url);
mpg123_free_string(&httpauth1);
return sock;
}
#endif /*WANT_WIN32_SOCKETS*/
#else /* NETWORK */
/* stub */
int http_open (char* url, struct httpdata *hd)
{
if(!param.quiet)
error("HTTP support not built in.");
return -1;
}
#endif
/* EOF */

View File

@ -0,0 +1,66 @@
/*
httpget: HTTP input routines (the header)
copyright 2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
Note about MIME types:
You feed debunk_mime() a MIME string and it classifies it as it is relevant for mpg123.
In httpget.c are the MIME class lists, which may be appended to to support more bogus MIME types.
*/
#ifndef _HTTPGET_H_
#define _HTTPGET_H_
#include "mpg123.h"
/* Pulled in by mpg123app.h! */
struct httpdata
{
mpg123_string content_type;
mpg123_string icy_name;
mpg123_string icy_url;
off_t icy_interval;
mpg123_string proxyhost;
mpg123_string proxyport;
/* Partly dummy for now... later proxy host resolution will be cached (PROXY_ADDR). */
enum { PROXY_UNKNOWN=0, PROXY_NONE, PROXY_HOST, PROXY_ADDR } proxystate;
};
void httpdata_init(struct httpdata *e);
void httpdata_reset(struct httpdata *e);
void httpdata_free(struct httpdata *e);
/* There is a whole lot of MIME types for the same thing.
the function will reduce it to a combination of these flags */
#define IS_FILE 1
#define IS_LIST 2
#define IS_M3U 4
#define IS_PLS 8
#define HTTP_MAX_RELOCATIONS 20
int debunk_mime(const char* mime);
/*Previously static functions, shared for win32_net_support */
int proxy_init(struct httpdata *hd);
int translate_url(const char *url, mpg123_string *purl);
size_t accept_length(void);
int fill_request(mpg123_string *request, mpg123_string *host, mpg123_string *port, mpg123_string *httpauth1, int *try_without_port);
void get_header_string(mpg123_string *response, const char *fieldname, mpg123_string *store);
char *get_header_val(const char *hname, mpg123_string *response);
/* needed for HTTP/1.1 non-pipelining mode */
/* #define CONN_HEAD "Connection: close\r\n" */
#define CONN_HEAD ""
#define icy_yes "Icy-MetaData: 1\r\n"
#define icy_no "Icy-MetaData: 0\r\n"
extern char *proxyurl;
extern unsigned long proxyip;
/* takes url and content type string address, opens resource, returns fd for data, allocates and sets content type */
extern int http_open (char* url, struct httpdata *hd);
extern char *httpauth;
#endif

View File

@ -0,0 +1,360 @@
#ifndef MPG123_INTSYM_H
#define MPG123_INTSYM_H
/* Mapping of internal mpg123 symbols to something that is less likely to
conflict in case of static linking. */
#include "config.h"
#define COS9 INT123_COS9
#define tfcos36 INT123_tfcos36
#define pnts INT123_pnts
#define catchsignal INT123_catchsignal
#define safe_realloc INT123_safe_realloc
#define compat_strdup INT123_compat_strdup
#define compat_open INT123_compat_open
#define compat_fopen INT123_compat_fopen
#define compat_fdopen INT123_compat_fdopen
#define compat_close INT123_compat_close
#define compat_fclose INT123_compat_fclose
#define win32_wide_utf8 INT123_win32_wide_utf8
#define win32_utf8_wide INT123_win32_utf8_wide
#define unintr_write INT123_unintr_write
#define unintr_read INT123_unintr_read
#define ntom_set_ntom INT123_ntom_set_ntom
#define synth_1to1 INT123_synth_1to1
#define synth_1to1_dither INT123_synth_1to1_dither
#define synth_1to1_i386 INT123_synth_1to1_i386
#define synth_1to1_i586 INT123_synth_1to1_i586
#define synth_1to1_i586_dither INT123_synth_1to1_i586_dither
#define synth_1to1_mmx INT123_synth_1to1_mmx
#define synth_1to1_3dnow INT123_synth_1to1_3dnow
#define synth_1to1_sse INT123_synth_1to1_sse
#define synth_1to1_stereo_sse INT123_synth_1to1_stereo_sse
#define synth_1to1_3dnowext INT123_synth_1to1_3dnowext
#define synth_1to1_altivec INT123_synth_1to1_altivec
#define synth_1to1_stereo_altivec INT123_synth_1to1_stereo_altivec
#define synth_1to1_x86_64 INT123_synth_1to1_x86_64
#define synth_1to1_stereo_x86_64 INT123_synth_1to1_stereo_x86_64
#define synth_1to1_avx INT123_synth_1to1_avx
#define synth_1to1_stereo_avx INT123_synth_1to1_stereo_avx
#define synth_1to1_arm INT123_synth_1to1_arm
#define synth_1to1_neon INT123_synth_1to1_neon
#define synth_1to1_stereo_neon INT123_synth_1to1_stereo_neon
#define synth_1to1_neon64 INT123_synth_1to1_neon64
#define synth_1to1_stereo_neon64 INT123_synth_1to1_stereo_neon64
#define absynth_1to1_i486 INT123_absynth_1to1_i486
#define synth_1to1_mono INT123_synth_1to1_mono
#define synth_1to1_m2s INT123_synth_1to1_m2s
#define synth_2to1 INT123_synth_2to1
#define synth_2to1_dither INT123_synth_2to1_dither
#define synth_2to1_i386 INT123_synth_2to1_i386
#define synth_2to1_mono INT123_synth_2to1_mono
#define synth_2to1_m2s INT123_synth_2to1_m2s
#define synth_4to1 INT123_synth_4to1
#define synth_4to1_dither INT123_synth_4to1_dither
#define synth_4to1_i386 INT123_synth_4to1_i386
#define synth_4to1_mono INT123_synth_4to1_mono
#define synth_4to1_m2s INT123_synth_4to1_m2s
#define synth_ntom INT123_synth_ntom
#define synth_ntom_mono INT123_synth_ntom_mono
#define synth_ntom_m2s INT123_synth_ntom_m2s
#define synth_1to1_8bit INT123_synth_1to1_8bit
#define synth_1to1_8bit_i386 INT123_synth_1to1_8bit_i386
#define synth_1to1_8bit_wrap INT123_synth_1to1_8bit_wrap
#define synth_1to1_8bit_mono INT123_synth_1to1_8bit_mono
#define synth_1to1_8bit_m2s INT123_synth_1to1_8bit_m2s
#define synth_1to1_8bit_wrap_mono INT123_synth_1to1_8bit_wrap_mono
#define synth_1to1_8bit_wrap_m2s INT123_synth_1to1_8bit_wrap_m2s
#define synth_2to1_8bit INT123_synth_2to1_8bit
#define synth_2to1_8bit_i386 INT123_synth_2to1_8bit_i386
#define synth_2to1_8bit_mono INT123_synth_2to1_8bit_mono
#define synth_2to1_8bit_m2s INT123_synth_2to1_8bit_m2s
#define synth_4to1_8bit INT123_synth_4to1_8bit
#define synth_4to1_8bit_i386 INT123_synth_4to1_8bit_i386
#define synth_4to1_8bit_mono INT123_synth_4to1_8bit_mono
#define synth_4to1_8bit_m2s INT123_synth_4to1_8bit_m2s
#define synth_ntom_8bit INT123_synth_ntom_8bit
#define synth_ntom_8bit_mono INT123_synth_ntom_8bit_mono
#define synth_ntom_8bit_m2s INT123_synth_ntom_8bit_m2s
#define synth_1to1_real INT123_synth_1to1_real
#define synth_1to1_real_i386 INT123_synth_1to1_real_i386
#define synth_1to1_real_sse INT123_synth_1to1_real_sse
#define synth_1to1_real_stereo_sse INT123_synth_1to1_real_stereo_sse
#define synth_1to1_real_x86_64 INT123_synth_1to1_real_x86_64
#define synth_1to1_real_stereo_x86_64 INT123_synth_1to1_real_stereo_x86_64
#define synth_1to1_real_avx INT123_synth_1to1_real_avx
#define synth_1to1_fltst_avx INT123_synth_1to1_fltst_avx
#define synth_1to1_real_altivec INT123_synth_1to1_real_altivec
#define synth_1to1_fltst_altivec INT123_synth_1to1_fltst_altivec
#define synth_1to1_real_neon INT123_synth_1to1_real_neon
#define synth_1to1_real_stereo_neon INT123_synth_1to1_real_stereo_neon
#define synth_1to1_real_neon64 INT123_synth_1to1_real_neon64
#define synth_1to1_fltst_neon64 INT123_synth_1to1_fltst_neon64
#define synth_1to1_real_mono INT123_synth_1to1_real_mono
#define synth_1to1_real_m2s INT123_synth_1to1_real_m2s
#define synth_2to1_real INT123_synth_2to1_real
#define synth_2to1_real_i386 INT123_synth_2to1_real_i386
#define synth_2to1_real_mono INT123_synth_2to1_real_mono
#define synth_2to1_real_m2s INT123_synth_2to1_real_m2s
#define synth_4to1_real INT123_synth_4to1_real
#define synth_4to1_real_i386 INT123_synth_4to1_real_i386
#define synth_4to1_real_mono INT123_synth_4to1_real_mono
#define synth_4to1_real_m2s INT123_synth_4to1_real_m2s
#define synth_ntom_real INT123_synth_ntom_real
#define synth_ntom_real_mono INT123_synth_ntom_real_mono
#define synth_ntom_real_m2s INT123_synth_ntom_real_m2s
#define synth_1to1_s32 INT123_synth_1to1_s32
#define synth_1to1_s32_i386 INT123_synth_1to1_s32_i386
#define synth_1to1_s32_sse INT123_synth_1to1_s32_sse
#define synth_1to1_s32_stereo_sse INT123_synth_1to1_s32_stereo_sse
#define synth_1to1_s32_x86_64 INT123_synth_1to1_s32_x86_64
#define synth_1to1_s32_stereo_x86_64 INT123_synth_1to1_s32_stereo_x86_64
#define synth_1to1_s32_avx INT123_synth_1to1_s32_avx
#define synth_1to1_s32_stereo_avx INT123_synth_1to1_s32_stereo_avx
#define synth_1to1_s32_altivec INT123_synth_1to1_s32_altivec
#define synth_1to1_s32_stereo_altivec INT123_synth_1to1_s32_stereo_altivec
#define synth_1to1_s32_neon INT123_synth_1to1_s32_neon
#define synth_1to1_s32_stereo_neon INT123_synth_1to1_s32_stereo_neon
#define synth_1to1_s32_neon64 INT123_synth_1to1_s32_neon64
#define synth_1to1_s32st_neon64 INT123_synth_1to1_s32st_neon64
#define synth_1to1_s32_mono INT123_synth_1to1_s32_mono
#define synth_1to1_s32_m2s INT123_synth_1to1_s32_m2s
#define synth_2to1_s32 INT123_synth_2to1_s32
#define synth_2to1_s32_i386 INT123_synth_2to1_s32_i386
#define synth_2to1_s32_mono INT123_synth_2to1_s32_mono
#define synth_2to1_s32_m2s INT123_synth_2to1_s32_m2s
#define synth_4to1_s32 INT123_synth_4to1_s32
#define synth_4to1_s32_i386 INT123_synth_4to1_s32_i386
#define synth_4to1_s32_mono INT123_synth_4to1_s32_mono
#define synth_4to1_s32_m2s INT123_synth_4to1_s32_m2s
#define synth_ntom_s32 INT123_synth_ntom_s32
#define synth_ntom_s32_mono INT123_synth_ntom_s32_mono
#define synth_ntom_s32_m2s INT123_synth_ntom_s32_m2s
#define dct64 INT123_dct64
#define dct64_i386 INT123_dct64_i386
#define dct64_altivec INT123_dct64_altivec
#define dct64_i486 INT123_dct64_i486
#define dct36 INT123_dct36
#define dct36_3dnow INT123_dct36_3dnow
#define dct36_3dnowext INT123_dct36_3dnowext
#define dct36_x86_64 INT123_dct36_x86_64
#define dct36_sse INT123_dct36_sse
#define dct36_avx INT123_dct36_avx
#define dct36_neon INT123_dct36_neon
#define dct36_neon64 INT123_dct36_neon64
#define synth_ntom_set_step INT123_synth_ntom_set_step
#define ntom_val INT123_ntom_val
#define ntom_frame_outsamples INT123_ntom_frame_outsamples
#define ntom_frmouts INT123_ntom_frmouts
#define ntom_ins2outs INT123_ntom_ins2outs
#define ntom_frameoff INT123_ntom_frameoff
#define init_layer3 INT123_init_layer3
#define init_layer3_gainpow2 INT123_init_layer3_gainpow2
#define init_layer3_stuff INT123_init_layer3_stuff
#define init_layer12 INT123_init_layer12
#define init_layer12_table INT123_init_layer12_table
#define init_layer12_stuff INT123_init_layer12_stuff
#define prepare_decode_tables INT123_prepare_decode_tables
#define make_decode_tables INT123_make_decode_tables
#define make_decode_tables_mmx INT123_make_decode_tables_mmx
#define init_layer3_gainpow2_mmx INT123_init_layer3_gainpow2_mmx
#define init_layer12_table_mmx INT123_init_layer12_table_mmx
#define make_conv16to8_table INT123_make_conv16to8_table
#define do_layer3 INT123_do_layer3
#define do_layer2 INT123_do_layer2
#define do_layer1 INT123_do_layer1
#define do_equalizer INT123_do_equalizer
#define dither_table_init INT123_dither_table_init
#define frame_dither_init INT123_frame_dither_init
#define invalidate_format INT123_invalidate_format
#define frame_init INT123_frame_init
#define frame_init_par INT123_frame_init_par
#define frame_outbuffer INT123_frame_outbuffer
#define frame_output_format INT123_frame_output_format
#define frame_buffers INT123_frame_buffers
#define frame_reset INT123_frame_reset
#define frame_buffers_reset INT123_frame_buffers_reset
#define frame_exit INT123_frame_exit
#define frame_index_find INT123_frame_index_find
#define frame_index_setup INT123_frame_index_setup
#define do_volume INT123_do_volume
#define do_rva INT123_do_rva
#define frame_gapless_init INT123_frame_gapless_init
#define frame_gapless_realinit INT123_frame_gapless_realinit
#define frame_gapless_update INT123_frame_gapless_update
#define frame_gapless_bytify INT123_frame_gapless_bytify
#define frame_gapless_ignore INT123_frame_gapless_ignore
#define frame_expect_outsamples INT123_frame_expect_outsamples
#define frame_skip INT123_frame_skip
#define frame_ins2outs INT123_frame_ins2outs
#define frame_outs INT123_frame_outs
#define frame_expect_outsampels INT123_frame_expect_outsampels
#define frame_offset INT123_frame_offset
#define frame_set_frameseek INT123_frame_set_frameseek
#define frame_set_seek INT123_frame_set_seek
#define frame_tell_seek INT123_frame_tell_seek
#define frame_fill_toc INT123_frame_fill_toc
#define getbits INT123_getbits
#define getcpuflags INT123_getcpuflags
#define icy2utf8 INT123_icy2utf8
#define init_icy INT123_init_icy
#define clear_icy INT123_clear_icy
#define reset_icy INT123_reset_icy
#define init_id3 INT123_init_id3
#define exit_id3 INT123_exit_id3
#define reset_id3 INT123_reset_id3
#define id3_link INT123_id3_link
#define parse_new_id3 INT123_parse_new_id3
#define id3_to_utf8 INT123_id3_to_utf8
#define fi_init INT123_fi_init
#define fi_exit INT123_fi_exit
#define fi_resize INT123_fi_resize
#define fi_add INT123_fi_add
#define fi_set INT123_fi_set
#define fi_reset INT123_fi_reset
#define double_to_long_rounded INT123_double_to_long_rounded
#define scale_rounded INT123_scale_rounded
#define decode_update INT123_decode_update
#define decoder_synth_bytes INT123_decoder_synth_bytes
#define samples_to_bytes INT123_samples_to_bytes
#define bytes_to_samples INT123_bytes_to_samples
#define outblock_bytes INT123_outblock_bytes
#define postprocess_buffer INT123_postprocess_buffer
#define frame_cpu_opt INT123_frame_cpu_opt
#define set_synth_functions INT123_set_synth_functions
#define dectype INT123_dectype
#define defdec INT123_defdec
#define decclass INT123_decclass
#define check_decoders INT123_check_decoders
#define read_frame_init INT123_read_frame_init
#define frame_bitrate INT123_frame_bitrate
#define frame_freq INT123_frame_freq
#define read_frame_recover INT123_read_frame_recover
#define read_frame INT123_read_frame
#define set_pointer INT123_set_pointer
#define position_info INT123_position_info
#define compute_bpf INT123_compute_bpf
#define time_to_frame INT123_time_to_frame
#define get_songlen INT123_get_songlen
#define bc_prepare INT123_bc_prepare
#define bc_cleanup INT123_bc_cleanup
#define bc_poolsize INT123_bc_poolsize
#define bc_fill INT123_bc_fill
#define open_stream INT123_open_stream
#define open_stream_handle INT123_open_stream_handle
#define open_feed INT123_open_feed
#define feed_more INT123_feed_more
#define feed_forget INT123_feed_forget
#define feed_set_pos INT123_feed_set_pos
#define open_bad INT123_open_bad
#define open_module INT123_open_module
#define close_module INT123_close_module
#define list_modules INT123_list_modules
#define buffer_init INT123_buffer_init
#define buffer_exit INT123_buffer_exit
#define buffer_sync_param INT123_buffer_sync_param
#define buffer_open INT123_buffer_open
#define buffer_encodings INT123_buffer_encodings
#define buffer_formats INT123_buffer_formats
#define buffer_start INT123_buffer_start
#define buffer_ndrain INT123_buffer_ndrain
#define buffer_stop INT123_buffer_stop
#define buffer_close INT123_buffer_close
#define buffer_continue INT123_buffer_continue
#define buffer_ignore_lowmem INT123_buffer_ignore_lowmem
#define buffer_drain INT123_buffer_drain
#define buffer_end INT123_buffer_end
#define buffer_pause INT123_buffer_pause
#define buffer_drop INT123_buffer_drop
#define buffer_write INT123_buffer_write
#define buffer_fill INT123_buffer_fill
#define read_buf INT123_read_buf
#define xfer_write_string INT123_xfer_write_string
#define xfer_read_string INT123_xfer_read_string
#define xfermem_init INT123_xfermem_init
#define xfermem_init_writer INT123_xfermem_init_writer
#define xfermem_init_reader INT123_xfermem_init_reader
#define xfermem_get_freespace INT123_xfermem_get_freespace
#define xfermem_get_usedspace INT123_xfermem_get_usedspace
#define xfermem_getcmd INT123_xfermem_getcmd
#define xfermem_getcmds INT123_xfermem_getcmds
#define xfermem_putcmd INT123_xfermem_putcmd
#define xfermem_writer_block INT123_xfermem_writer_block
#define xfermem_write INT123_xfermem_write
#define xfermem_done INT123_xfermem_done
#define au_open INT123_au_open
#define cdr_open INT123_cdr_open
#define raw_open INT123_raw_open
#define wav_open INT123_wav_open
#define wav_write INT123_wav_write
#define wav_close INT123_wav_close
#define au_close INT123_au_close
#define raw_close INT123_raw_close
#define cdr_formats INT123_cdr_formats
#define au_formats INT123_au_formats
#define raw_formats INT123_raw_formats
#define wav_formats INT123_wav_formats
#define wav_drain INT123_wav_drain
#define write_parameters INT123_write_parameters
#define read_parameters INT123_read_parameters
#define stringlists_add INT123_stringlists_add
#define check_neon INT123_check_neon
#define dct64_3dnow INT123_dct64_3dnow
#define dct64_3dnowext INT123_dct64_3dnowext
#define dct64_avx INT123_dct64_avx
#define dct64_real_avx INT123_dct64_real_avx
#define dct64_mmx INT123_dct64_mmx
#define dct64_MMX INT123_dct64_MMX
#define dct64_neon INT123_dct64_neon
#define dct64_neon64 INT123_dct64_neon64
#define dct64_real_neon64 INT123_dct64_real_neon64
#define dct64_real_neon INT123_dct64_real_neon
#define dct64_sse INT123_dct64_sse
#define dct64_real_sse INT123_dct64_real_sse
#define dct64_x86_64 INT123_dct64_x86_64
#define dct64_real_x86_64 INT123_dct64_real_x86_64
#define do_equalizer_3dnow INT123_do_equalizer_3dnow
#define synth_1to1_3dnow_asm INT123_synth_1to1_3dnow_asm
#define synth_1to1_arm_asm INT123_synth_1to1_arm_asm
#define synth_1to1_arm_accurate_asm INT123_synth_1to1_arm_accurate_asm
#define synth_1to1_i586_asm INT123_synth_1to1_i586_asm
#define synth_1to1_i586_asm_dither INT123_synth_1to1_i586_asm_dither
#define synth_1to1_MMX INT123_synth_1to1_MMX
#define synth_1to1_neon_asm INT123_synth_1to1_neon_asm
#define synth_1to1_neon64_asm INT123_synth_1to1_neon64_asm
#define synth_1to1_neon64_accurate_asm INT123_synth_1to1_neon64_accurate_asm
#define synth_1to1_real_neon64_asm INT123_synth_1to1_real_neon64_asm
#define synth_1to1_s32_neon64_asm INT123_synth_1to1_s32_neon64_asm
#define synth_1to1_neon_accurate_asm INT123_synth_1to1_neon_accurate_asm
#define synth_1to1_real_neon_asm INT123_synth_1to1_real_neon_asm
#define synth_1to1_s32_neon_asm INT123_synth_1to1_s32_neon_asm
#define synth_1to1_sse_accurate_asm INT123_synth_1to1_sse_accurate_asm
#define synth_1to1_real_sse_asm INT123_synth_1to1_real_sse_asm
#define synth_1to1_s32_sse_asm INT123_synth_1to1_s32_sse_asm
#define synth_1to1_s_avx_asm INT123_synth_1to1_s_avx_asm
#define synth_1to1_s_avx_accurate_asm INT123_synth_1to1_s_avx_accurate_asm
#define synth_1to1_real_s_avx_asm INT123_synth_1to1_real_s_avx_asm
#define synth_1to1_s32_s_avx_asm INT123_synth_1to1_s32_s_avx_asm
#define synth_1to1_s_neon_asm INT123_synth_1to1_s_neon_asm
#define synth_1to1_s_neon64_asm INT123_synth_1to1_s_neon64_asm
#define synth_1to1_s_neon64_accurate_asm INT123_synth_1to1_s_neon64_accurate_asm
#define synth_1to1_real_s_neon64_asm INT123_synth_1to1_real_s_neon64_asm
#define synth_1to1_s32_s_neon64_asm INT123_synth_1to1_s32_s_neon64_asm
#define synth_1to1_s_neon_accurate_asm INT123_synth_1to1_s_neon_accurate_asm
#define synth_1to1_real_s_neon_asm INT123_synth_1to1_real_s_neon_asm
#define synth_1to1_s32_s_neon_asm INT123_synth_1to1_s32_s_neon_asm
#define synth_1to1_s_sse_accurate_asm INT123_synth_1to1_s_sse_accurate_asm
#define synth_1to1_real_s_sse_asm INT123_synth_1to1_real_s_sse_asm
#define synth_1to1_s32_s_sse_asm INT123_synth_1to1_s32_s_sse_asm
#define synth_1to1_s_x86_64_asm INT123_synth_1to1_s_x86_64_asm
#define synth_1to1_s_x86_64_accurate_asm INT123_synth_1to1_s_x86_64_accurate_asm
#define synth_1to1_real_s_x86_64_asm INT123_synth_1to1_real_s_x86_64_asm
#define synth_1to1_s32_s_x86_64_asm INT123_synth_1to1_s32_s_x86_64_asm
#define synth_1to1_x86_64_asm INT123_synth_1to1_x86_64_asm
#define synth_1to1_x86_64_accurate_asm INT123_synth_1to1_x86_64_accurate_asm
#define synth_1to1_real_x86_64_asm INT123_synth_1to1_real_x86_64_asm
#define synth_1to1_s32_x86_64_asm INT123_synth_1to1_s32_x86_64_asm
#define costab_mmxsse INT123_costab_mmxsse
#define make_decode_tables_mmx_asm INT123_make_decode_tables_mmx_asm
#ifndef HAVE_STRERROR
#define strerror INT123_strerror
#endif
#endif

View File

@ -0,0 +1,193 @@
# Module for non-recursive mpg123 build system.
EXTRA_DIST += src/libmpg123/mpg123.h.in
EXTRA_PROGRAMS += src/libmpg123/testcpu
src_libmpg123_testcpu_DEPENDENCIES = src/libmpg123/getcpuflags.$(OBJEXT)
src_libmpg123_testcpu_SOURCES = src/libmpg123/testcpu.c
src_libmpg123_testcpu_LDADD = \
src/compat/libcompat.la \
src/libmpg123/getcpuflags.$(OBJEXT)
# Necessary?
CLEANFILES += src/libmpg123/*.a
lib_LTLIBRARIES += src/libmpg123/libmpg123.la
nodist_include_HEADERS += src/libmpg123/mpg123.h
include_HEADERS += src/libmpg123/fmt123.h
src_libmpg123_libmpg123_la_LDFLAGS = \
-no-undefined \
-version-info @LIBMPG123_VERSION@ \
-export-symbols-regex '^mpg123_'
src_libmpg123_libmpg123_la_LIBADD = \
src/compat/libcompat.la \
@DECODER_LOBJ@ @LFS_LOBJ@ @LIBS@
src_libmpg123_libmpg123_la_DEPENDENCIES = \
src/compat/libcompat.la \
@DECODER_LOBJ@ @LFS_LOBJ@
src_libmpg123_libmpg123_la_SOURCES = \
src/libmpg123/fmt123.h \
src/libmpg123/mpeghead.h \
src/libmpg123/parse.c \
src/libmpg123/parse.h \
src/libmpg123/frame.c \
src/libmpg123/format.c \
src/libmpg123/frame.h \
src/libmpg123/reader.h \
src/libmpg123/debug.h \
src/libmpg123/decode.h \
src/libmpg123/sample.h \
src/libmpg123/dct64.c \
src/libmpg123/synth.h \
src/libmpg123/synth_mono.h \
src/libmpg123/synth_ntom.h \
src/libmpg123/synth_8bit.h \
src/libmpg123/synths.h \
src/libmpg123/equalizer.c \
src/libmpg123/huffman.h \
src/libmpg123/newhuffman.h \
src/libmpg123/icy.h \
src/libmpg123/icy2utf8.h \
src/libmpg123/id3.h \
src/libmpg123/id3.c \
src/libmpg123/true.h \
src/libmpg123/getbits.h \
src/libmpg123/optimize.h \
src/libmpg123/optimize.c \
src/libmpg123/readers.c \
src/libmpg123/tabinit.c \
src/libmpg123/libmpg123.c \
src/libmpg123/gapless.h \
src/libmpg123/mpg123lib_intern.h \
src/libmpg123/abi_align.h \
src/libmpg123/mangle.h \
src/libmpg123/getcpuflags.h \
src/libmpg123/index.h \
src/libmpg123/index.c
EXTRA_src_libmpg123_libmpg123_la_SOURCES = \
src/libmpg123/lfs_alias.c \
src/libmpg123/lfs_wrap.c \
src/libmpg123/icy.c \
src/libmpg123/icy2utf8.c \
src/libmpg123/l2tables.h \
src/libmpg123/layer1.c \
src/libmpg123/layer2.c \
src/libmpg123/layer3.c \
src/libmpg123/dither.h \
src/libmpg123/dither_impl.h \
src/libmpg123/dither.c \
src/libmpg123/feature.c \
src/libmpg123/dct36_3dnowext.S \
src/libmpg123/dct36_3dnow.S \
src/libmpg123/dct36_sse.S \
src/libmpg123/dct36_x86_64.S \
src/libmpg123/dct36_avx.S \
src/libmpg123/dct36_neon.S \
src/libmpg123/dct36_neon64.S \
src/libmpg123/dct64_3dnowext.S \
src/libmpg123/dct64_3dnow.S \
src/libmpg123/dct64_altivec.c \
src/libmpg123/dct64_i386.c \
src/libmpg123/dct64_i486.c \
src/libmpg123/dct64_mmx.S \
src/libmpg123/dct64_sse.S \
src/libmpg123/dct64_sse_float.S \
src/libmpg123/dct64_x86_64.S \
src/libmpg123/dct64_x86_64_float.S \
src/libmpg123/dct64_neon.S \
src/libmpg123/dct64_neon_float.S \
src/libmpg123/dct64_neon64.S \
src/libmpg123/dct64_neon64_float.S \
src/libmpg123/dct64_avx.S \
src/libmpg123/dct64_avx_float.S \
src/libmpg123/synth_3dnowext.S \
src/libmpg123/synth_3dnow.S \
src/libmpg123/synth_altivec.c \
src/libmpg123/synth_i486.c \
src/libmpg123/synth_i586_dither.S \
src/libmpg123/synth_i586.S \
src/libmpg123/synth_mmx.S \
src/libmpg123/synth_sse3d.h \
src/libmpg123/synth_sse.S \
src/libmpg123/synth_sse_float.S \
src/libmpg123/synth_sse_s32.S \
src/libmpg123/synth_sse_accurate.S \
src/libmpg123/synth_stereo_sse_float.S \
src/libmpg123/synth_stereo_sse_s32.S \
src/libmpg123/synth_stereo_sse_accurate.S \
src/libmpg123/synth_x86_64.S \
src/libmpg123/synth_x86_64_float.S \
src/libmpg123/synth_x86_64_s32.S \
src/libmpg123/synth_x86_64_accurate.S \
src/libmpg123/synth_stereo_x86_64.S \
src/libmpg123/synth_stereo_x86_64_float.S \
src/libmpg123/synth_stereo_x86_64_s32.S \
src/libmpg123/synth_stereo_x86_64_accurate.S \
src/libmpg123/synth_arm.S \
src/libmpg123/synth_arm_accurate.S \
src/libmpg123/synth_neon.S \
src/libmpg123/synth_neon_float.S \
src/libmpg123/synth_neon_s32.S \
src/libmpg123/synth_neon_accurate.S \
src/libmpg123/synth_stereo_neon.S \
src/libmpg123/synth_stereo_neon_float.S \
src/libmpg123/synth_stereo_neon_s32.S \
src/libmpg123/synth_stereo_neon_accurate.S \
src/libmpg123/synth_neon64.S \
src/libmpg123/synth_neon64_float.S \
src/libmpg123/synth_neon64_s32.S \
src/libmpg123/synth_neon64_accurate.S \
src/libmpg123/synth_stereo_neon64.S \
src/libmpg123/synth_stereo_neon64_float.S \
src/libmpg123/synth_stereo_neon64_s32.S \
src/libmpg123/synth_stereo_neon64_accurate.S \
src/libmpg123/synth_stereo_avx.S \
src/libmpg123/synth_stereo_avx_float.S \
src/libmpg123/synth_stereo_avx_s32.S \
src/libmpg123/synth_stereo_avx_accurate.S \
src/libmpg123/ntom.c \
src/libmpg123/synth.c \
src/libmpg123/synth_8bit.c \
src/libmpg123/synth_real.c \
src/libmpg123/synth_s32.c \
src/libmpg123/equalizer_3dnow.S \
src/libmpg123/tabinit_mmx.S \
src/libmpg123/stringbuf.c \
src/libmpg123/getcpuflags.S \
src/libmpg123/getcpuflags_x86_64.S \
src/libmpg123/getcpuflags_arm.c \
src/libmpg123/check_neon.S \
src/libmpg123/l12_integer_tables.h \
src/libmpg123/l3_integer_tables.h
if USE_YASM_FOR_AVX
## Override rules for the sources that should be assembled with yasm
AVX_SRCS = \
src/libmpg123/dct36_avx.S \
src/libmpg123/dct64_avx.S \
src/libmpg123/dct64_avx_float.S \
src/libmpg123/synth_stereo_avx.S \
src/libmpg123/synth_stereo_avx_float.S \
src/libmpg123/synth_stereo_avx_s32.S \
src/libmpg123/synth_stereo_avx_accurate.S
AVX_OBJS = $(AVX_SRCS:.S=.@OBJEXT@)
ASM_DEPS = \
src/libmpg123/mangle.h \
$(top_builddir)/src/config.h \
src/intsym.h
$(AVX_OBJS): %.@OBJEXT@: %.S $(ASM_DEPS)
$(CPP) $(DEFAULT_INCLUDES) $(INCLUDES) -DASMALIGN_BALIGN $< | @YASM@ - @YASMFLAGS@ @YASM_FORMAT@ -o $@
$(AVX_OBJS:.@OBJEXT@=.lo): %.lo: %.@OBJEXT@
@echo "# Generated by ltmain.sh (GNU libtool)" >$@
@echo "pic_object='`basename $<`'" >>$@
@echo "non_pic_object='`basename $<`'" >>$@
endif

View File

@ -0,0 +1,41 @@
/*
abi_align: An attempt to avoid breakage because of mixing
compilers with different alignment.
copyright 1995-2015 by the mpg123 project
free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
There used to be code that checks alignment, but it did not really
work anyway. The only straw we have is putting that alignment
attribute to API functions.
*/
#ifndef MPG123_H_ABI_ALIGN
#define MPG123_H_ABI_ALIGN
#include "config.h"
/* ABI conformance for other compilers.
mpg123 needs 16byte-aligned (or more) stack for SSE and friends.
gcc provides that, but others don't necessarily. */
#ifdef ABI_ALIGN_FUN
#ifndef attribute_align_arg
#if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__>1)
# define attribute_align_arg __attribute__((force_align_arg_pointer))
/* The gcc that can align the stack does not need the check... nor does it work with gcc 4.3+, anyway. */
#else
# define attribute_align_arg
#endif
#endif /* attribute_align_arg */
#else /* ABI_ALIGN_FUN */
#define attribute_align_arg
#endif /* ABI_ALIGN_FUN */
#endif /* MPG123_H_ABI_ALIGN */

View File

@ -0,0 +1,35 @@
/*
check_neon: check NEON availability
copyright 1995-2014 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Momma
*/
#include "mangle.h"
#ifndef __aarch64__
#ifndef _M_ARM
.code 32
#endif
#ifndef __APPLE__
.fpu neon
#endif
#endif
.text
GLOBAL_SYMBOL ASM_NAME(check_neon)
#ifdef __ELF__
.type ASM_NAME(check_neon), %function
#endif
ALIGN4
ASM_NAME(check_neon):
#ifdef __aarch64__
orr v0.16b, v0.16b, v0.16b
ret
#else
vorr d0, d0, d0
bx lr
#endif
NONEXEC_STACK

View File

@ -0,0 +1,560 @@
/*
dct64_3dnow.s: Replacement of dct36() with AMD's 3DNow! SIMD operations support
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Syuuhei Kashiyama
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.
*/
#include "mangle.h"
.globl ASM_NAME(dct36_3dnow)
/* .type ASM_NAME(dct36_3dnow),@function */
ASM_NAME(dct36_3dnow):
pushl %ebp
movl %esp,%ebp
#if defined(PIC) && defined(__APPLE__)
sub $4,%esp
#endif
pushl %esi
pushl %ebx
#undef _EBX_
#define _EBX_ %edi
PREPARE_GOT
GET_GOT
#if defined(PIC) && defined(__APPLE__)
#define _COS9_ 0(%edi)
#define _tfcos36_ 0(%eax)
mov GLOBAL_VAR_PTR(tfcos36), %eax
mov GLOBAL_VAR_PTR(COS9), %edi
mov %eax, -4(%ebp)
#else
#define _COS9_ GLOBAL_VAR(COS9)
#define _tfcos36_ GLOBAL_VAR(tfcos36)
#endif
movl 8(%ebp),%eax
movl 12(%ebp),%esi
movl 16(%ebp),%ecx
movl 20(%ebp),%edx
movl 24(%ebp),%ebx
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 12+_COS9_,%mm2
punpckldq %mm2,%mm2
movd 24+_COS9_,%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 4+_COS9_,%mm3
punpckldq %mm3,%mm3
pfmul %mm3,%mm2
pfadd %mm0,%mm2
movq 40(%eax),%mm3
movd 20+_COS9_,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq 56(%eax),%mm3
movd 28+_COS9_,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq (%eax),%mm3
movq 16(%eax),%mm4
movd 8+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
movq 32(%eax),%mm4
movd 16+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
pfadd %mm1,%mm3
movq 64(%eax),%mm4
movd 32+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
movq %mm2,%mm4
pfadd %mm3,%mm4
movq %mm7,%mm5
#if defined(PIC) && defined(__APPLE__)
mov -4(%ebp),%eax
#endif
punpckldq 0+_tfcos36_,%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 32+_tfcos36_,%mm5
#if defined(PIC) && defined(__APPLE__)
mov 8(%ebp),%eax
#endif
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 12+_COS9_,%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 24+_COS9_,%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
#if defined(PIC) && defined(__APPLE__)
mov -4(%ebp),%eax
#endif
punpckldq 4+_tfcos36_,%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 28+_tfcos36_,%mm5
#if defined(PIC) && defined(__APPLE__)
mov 8(%ebp),%eax
#endif
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 20+_COS9_,%mm3
punpckldq %mm3,%mm3
pfmul %mm3,%mm2
pfsub %mm0,%mm2
movq 40(%eax),%mm3
movd 28+_COS9_,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfsub %mm3,%mm2
movq 56(%eax),%mm3
movd 4+_COS9_,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq (%eax),%mm3
movq 16(%eax),%mm4
movd 32+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
movq 32(%eax),%mm4
movd 8+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
pfadd %mm1,%mm3
movq 64(%eax),%mm4
movd 16+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
movq %mm2,%mm4
pfadd %mm3,%mm4
movq %mm7,%mm5
#if defined(PIC) && defined(__APPLE__)
mov -4(%ebp),%eax
#endif
punpckldq 8+_tfcos36_,%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 24+_tfcos36_,%mm5
#if defined(PIC) && defined(__APPLE__)
mov 8(%ebp),%eax
#endif
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 28+_COS9_,%mm3
punpckldq %mm3,%mm3
pfmul %mm3,%mm2
pfsub %mm0,%mm2
movq 40(%eax),%mm3
movd 4+_COS9_,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq 56(%eax),%mm3
movd 20+_COS9_,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfsub %mm3,%mm2
movq (%eax),%mm3
movq 16(%eax),%mm4
movd 16+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
movq 32(%eax),%mm4
movd 32+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
pfadd %mm1,%mm3
movq 64(%eax),%mm4
movd 8+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
movq %mm2,%mm4
pfadd %mm3,%mm4
movq %mm7,%mm5
#if defined(PIC) && defined(__APPLE__)
mov -4(%ebp),%eax
#endif
punpckldq 12+_tfcos36_,%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 20+_tfcos36_,%mm5
#if defined(PIC) && defined(__APPLE__)
mov 8(%ebp),%eax
#endif
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
#if defined(PIC) && defined(__APPLE__)
mov -4(%ebp),%eax
#endif
punpckldq 16+_tfcos36_,%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
RESTORE_GOT
popl %ebx
popl %esi
movl %ebp,%esp
popl %ebp
ret
#if defined(PIC) && defined(__APPLE__)
.section __IMPORT,__pointers,non_lazy_symbol_pointers
L_tfcos36:
.indirect_symbol ASM_NAME(tfcos36)
.long 0
L_COS9:
.indirect_symbol ASM_NAME(COS9)
.long 0
#endif
NONEXEC_STACK

View File

@ -0,0 +1,570 @@
/*
dct36_3dnowext: extended 3DNow optimized DCT36
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
Transformed back into standalone asm, with help of
gcc -S -DHAVE_CONFIG_H -I. -march=k6-3 -O3 -Wall -pedantic -fno-strict-aliasing -DREAL_IS_FLOAT -c -o dct36_3dnowext.{S,c}
MPlayer comment follows.
*/
/*
* dct36_3dnow.c - 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:
*
* - removed PREFETCH instruction for speedup
* - changed function name for support 3DNow! automatic detection
*
* 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
*
* Modified for use with MPlayer, for details see the changelog at
* http://svn.mplayerhq.hu/mplayer/trunk/
* $Id: dct36_3dnow.c 18786 2006-06-22 13:34:00Z diego $
*
* Original disclaimer:
* 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.
*
* 2003/06/21: Moved to GCC inline assembly - Alex Beregszaszi
*/
#include "mangle.h"
.text
ALIGN32
.globl ASM_NAME(dct36_3dnowext)
/* .type ASM_NAME(dct36_3dnowext), @function */
ASM_NAME(dct36_3dnowext):
pushl %ebp
movl %esp, %ebp
#if defined(PIC) && defined(__APPLE__)
sub $4, %esp
#endif
pushl %esi
pushl %ebx
#undef _EBX_
#define _EBX_ %edi
PREPARE_GOT
GET_GOT
#if defined(PIC) && defined(__APPLE__)
#define _COS9_ 0(%edi)
#define _tfcos36_ 0(%eax)
mov GLOBAL_VAR_PTR(tfcos36), %eax
mov GLOBAL_VAR_PTR(COS9), %edi
mov %eax, -4(%ebp)
#else
#define _COS9_ GLOBAL_VAR(COS9)
#define _tfcos36_ GLOBAL_VAR(tfcos36)
#endif
movl 8(%ebp), %eax
movl 12(%ebp), %esi
movl 16(%ebp), %ecx
movl 20(%ebp), %edx
movl 24(%ebp), %ebx
/* APP */
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 12+_COS9_,%mm2
punpckldq %mm2,%mm2
movd 24+_COS9_,%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 4+_COS9_,%mm3
punpckldq %mm3,%mm3
pfmul %mm3,%mm2
pfadd %mm0,%mm2
movq 40(%eax),%mm3
movd 20+_COS9_,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq 56(%eax),%mm3
movd 28+_COS9_,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq (%eax),%mm3
movq 16(%eax),%mm4
movd 8+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
movq 32(%eax),%mm4
movd 16+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
pfadd %mm1,%mm3
movq 64(%eax),%mm4
movd 32+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
movq %mm2,%mm4
pfadd %mm3,%mm4
movq %mm7,%mm5
#if defined(PIC) && defined(__APPLE__)
mov -4(%ebp),%eax
#endif
punpckldq 0+_tfcos36_,%mm5
pfmul %mm5,%mm4
movq %mm4,%mm5
pfacc %mm5,%mm5
movd 108(%edx),%mm6
punpckldq 104(%edx),%mm6
pfmul %mm6,%mm5
pswapd %mm5,%mm5
movq %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 32+_tfcos36_,%mm5
#if defined(PIC) && defined(__APPLE__)
mov 8(%ebp),%eax
#endif
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 12+_COS9_,%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 24+_COS9_,%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
#if defined(PIC) && defined(__APPLE__)
mov -4(%ebp),%eax
#endif
punpckldq 4+_tfcos36_,%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 28+_tfcos36_,%mm5
#if defined(PIC) && defined(__APPLE__)
mov 8(%ebp),%eax
#endif
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 20+_COS9_,%mm3
punpckldq %mm3,%mm3
pfmul %mm3,%mm2
pfsub %mm0,%mm2
movq 40(%eax),%mm3
movd 28+_COS9_,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfsub %mm3,%mm2
movq 56(%eax),%mm3
movd 4+_COS9_,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq (%eax),%mm3
movq 16(%eax),%mm4
movd 32+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
movq 32(%eax),%mm4
movd 8+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
pfadd %mm1,%mm3
movq 64(%eax),%mm4
movd 16+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
movq %mm2,%mm4
pfadd %mm3,%mm4
movq %mm7,%mm5
#if defined(PIC) && defined(__APPLE__)
mov -4(%ebp),%eax
#endif
punpckldq 8+_tfcos36_,%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 24+_tfcos36_,%mm5
#if defined(PIC) && defined(__APPLE__)
mov 8(%ebp),%eax
#endif
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 28+_COS9_,%mm3
punpckldq %mm3,%mm3
pfmul %mm3,%mm2
pfsub %mm0,%mm2
movq 40(%eax),%mm3
movd 4+_COS9_,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfadd %mm3,%mm2
movq 56(%eax),%mm3
movd 20+_COS9_,%mm4
punpckldq %mm4,%mm4
pfmul %mm4,%mm3
pfsub %mm3,%mm2
movq (%eax),%mm3
movq 16(%eax),%mm4
movd 16+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
movq 32(%eax),%mm4
movd 32+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfadd %mm4,%mm3
pfadd %mm1,%mm3
movq 64(%eax),%mm4
movd 8+_COS9_,%mm5
punpckldq %mm5,%mm5
pfmul %mm5,%mm4
pfsub %mm4,%mm3
movq %mm2,%mm4
pfadd %mm3,%mm4
movq %mm7,%mm5
#if defined(PIC) && defined(__APPLE__)
mov -4(%ebp),%eax
#endif
punpckldq 12+_tfcos36_,%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 20+_tfcos36_,%mm5
#if defined(PIC) && defined(__APPLE__)
mov 8(%ebp),%eax
#endif
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
#if defined(PIC) && defined(__APPLE__)
mov -4(%ebp),%eax
#endif
punpckldq 16+_tfcos36_,%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
/* NO_APP */
RESTORE_GOT
popl %ebx
popl %esi
leave
ret
/* .size ASM_NAME(dct36_3dnowext), .-ASM_NAME(dct36_3dnowext) */
#if defined(PIC) && defined(__APPLE__)
.section __IMPORT,__pointers,non_lazy_symbol_pointers
L_tfcos36:
.indirect_symbol ASM_NAME(tfcos36)
.long 0
L_COS9:
.indirect_symbol ASM_NAME(COS9)
.long 0
#endif
NONEXEC_STACK

View File

@ -0,0 +1,358 @@
/*
dct36_avx: AVX optimized dct36 for x86-64
copyright 1995-2013 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#ifdef IS_MSABI
#define in %rcx
#define out1 %rdx
#define out2 %r8
#define w %r9
#define ts %r10
#define COS9_ %rax
#define tfcos36_ %r11
#else
#define in %rdi
#define out1 %rsi
#define out2 %rdx
#define w %rcx
#define ts %r8
#define COS9_ %rax
#define tfcos36_ %r9
#endif
/*
void dct36_avx(real *inbuf,real *o1,real *o2,real *wintab,real *tsbuf);
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN16
dct36_avx_COS9:
.long 0x3f5db3d7
.long 0x3f5db3d7
.long 0x3f000000
.long 0x3f000000
.long 0x3f7c1c5c
.long 0x3f7c1c5c
.long 0x3f708fb2
.long 0x3f708fb2
.long 0x3f248dbb
.long 0x3f248dbb
.long 0x3e31d0d4
.long 0x3e31d0d4
.long 0x3eaf1d44
.long 0x3eaf1d44
.long 0x3f441b7d
.long 0x3f441b7d
ALIGN16
dct36_avx_tfcos36:
.long 0x3f007d2b
.long 0x3f0483ee
.long 0x3f0d3b7d
.long 0x3f1c4257
.long 0x40b79454
.long 0x3ff746ea
.long 0x3f976fd9
.long 0x3f5f2944
.long 0x3f3504f3
ALIGN16
dct36_avx_sign:
.long 0x80000000,0x80000000,0x80000000,0x80000000
.text
ALIGN16
.globl ASM_NAME(dct36_avx)
ASM_NAME(dct36_avx):
#ifdef IS_MSABI
push %rbp
mov %rsp, %rbp
sub $160, %rsp
movaps %xmm6, (%rsp)
movaps %xmm7, 16(%rsp)
movaps %xmm8, 32(%rsp)
movaps %xmm9, 48(%rsp)
movaps %xmm10, 64(%rsp)
movaps %xmm11, 80(%rsp)
movaps %xmm12, 96(%rsp)
movaps %xmm13, 112(%rsp)
movaps %xmm14, 128(%rsp)
movaps %xmm15, 144(%rsp)
movq 48(%rbp), ts
#endif
lea dct36_avx_COS9(%rip), COS9_
lea dct36_avx_tfcos36(%rip), tfcos36_
xorps %xmm4, %xmm4
movups (in), %xmm0
movups 16(in), %xmm1
movups 32(in), %xmm2
movups 48(in), %xmm3
movlps 64(in), %xmm4
vshufps $0x93, %xmm0, %xmm0, %xmm5
vshufps $0x93, %xmm1, %xmm1, %xmm6
vshufps $0x93, %xmm2, %xmm2, %xmm7
vshufps $0x93, %xmm3, %xmm3, %xmm8
vshufps $0xe1, %xmm4, %xmm4, %xmm9
movss %xmm8, %xmm9 #[fg--]
addps %xmm9, %xmm4 #[gh--]
movss %xmm7, %xmm8
addps %xmm8, %xmm3 #[cdef]
movss %xmm6, %xmm7
addps %xmm7, %xmm2 #[89ab]
movss %xmm5, %xmm6
addps %xmm6, %xmm1 #[4567]
xorps %xmm6, %xmm6
movss %xmm6, %xmm5
addps %xmm5, %xmm0 #[0123]
vblendps $0x5, %xmm6, %xmm3, %xmm7
vshufps $0x4e, %xmm4, %xmm3, %xmm4
addps %xmm7, %xmm4
vblendps $0x5, %xmm6, %xmm2, %xmm7
vshufps $0x4e, %xmm3, %xmm2, %xmm3
addps %xmm7, %xmm3
vblendps $0x5, %xmm6, %xmm1, %xmm7
vshufps $0x4e, %xmm2, %xmm1, %xmm2
addps %xmm7, %xmm2
vblendps $0x5, %xmm6, %xmm0, %xmm7
vshufps $0x4e, %xmm1, %xmm0, %xmm1
addps %xmm7, %xmm1
vmovlhps %xmm0, %xmm6, %xmm0
/*
xmm0 in[-,-,0,1]
xmm1 in[2,3,4,5]
xmm2 in[6,7,8,9]
xmm3 in[10,11,12,13]
xmm4 in[14,15,16,17]
*/
vblendps $0xc, %xmm3, %xmm2, %xmm5
blendps $0xc, %xmm4, %xmm3
blendps $0xc, %xmm2, %xmm4
movaps %xmm5, %xmm2
/*
xmm2 in[6,7,12,13]
xmm3 in[10,11,16,17]
xmm4 in[14,15,8,9]
*/
movaps (COS9_), %xmm15
movaps 16(COS9_), %xmm6
movaps 32(COS9_), %xmm7
movaps 48(COS9_), %xmm8
vmulps %xmm2, %xmm15, %xmm5
addps %xmm0, %xmm5
/*
xmm5 [ta33,tb33,ta66,tb66]
xmm6 COS9_[1,1,2,2]
xmm7 COS9_[5,5,8,8]
xmm8 COS9_[7,7,4,4]
xmm15 COS9_[3,3,6,6]
*/
vmulps %xmm1, %xmm6, %xmm9
vmulps %xmm3, %xmm7, %xmm12
vmulps %xmm4, %xmm8, %xmm13
addps %xmm5, %xmm9
addps %xmm13, %xmm12
addps %xmm9, %xmm12
vsubps %xmm3, %xmm1, %xmm13
vshufps $0xe0, %xmm2, %xmm0, %xmm14
vsubps %xmm14, %xmm0, %xmm14
subps %xmm4, %xmm13
mulps %xmm15, %xmm13
addps %xmm14, %xmm13
vmulps %xmm1, %xmm7, %xmm9
vmulps %xmm3, %xmm8, %xmm15
vmulps %xmm4, %xmm6, %xmm14
subps %xmm5, %xmm9
subps %xmm15, %xmm14
addps %xmm9, %xmm14
mulps %xmm1, %xmm8
mulps %xmm3, %xmm6
mulps %xmm4, %xmm7
subps %xmm5, %xmm8
subps %xmm7, %xmm6
vaddps %xmm6, %xmm8, %xmm15
movss 32(tfcos36_), %xmm5
subps %xmm1, %xmm0
subps %xmm2, %xmm4
addps %xmm3, %xmm0
addps %xmm4, %xmm0
shufps $0xaf, %xmm0, %xmm0
vmulss %xmm5, %xmm0, %xmm11
/*
xmm12 [1a-0,1b-0, 2a-0, 2b-0]
xmm13 [1a-1,1b-1, 2a-1, 2b-1]
xmm14 [1a-2,1b-2,-2a-2,-2b-2]
xmm15 [1a-3,1b-3,-2a-3,-2b-3]
*/
vunpckhps %xmm13, %xmm12, %xmm5
vunpcklps %xmm13, %xmm12, %xmm12
vunpckhps %xmm15, %xmm14, %xmm6
vunpcklps %xmm15, %xmm14, %xmm14
xorps dct36_avx_sign(%rip), %xmm6
/*
xmm12 [1a-0,1a-1,1b-0,1b-1]
xmm5 [2a-0,2a-1,2b-0,2b-1]
xmm14 [1a-2,1a-3,1b-2,1b-3]
xmm6 [2a-2,2a-3,2b-2,2b-3]
*/
vmovlhps %xmm14, %xmm12, %xmm0
movhlps %xmm12, %xmm14
vmovlhps %xmm6, %xmm5, %xmm1
vmovhlps %xmm5, %xmm6, %xmm15
/*
xmm0 tmp1a
xmm1 tmp2a
xmm14 tmp1b
xmm15 tmp2b
*/
movaps (tfcos36_), %xmm6
movaps 16(tfcos36_), %xmm7
vsubps %xmm14, %xmm15, %xmm10
addps %xmm14, %xmm15
vsubps %xmm0, %xmm1, %xmm14
addps %xmm1, %xmm0
vmulps %xmm6, %xmm15, %xmm1
mulps %xmm10, %xmm7
/*
%xmm0 tmp[0,1,2,3]
%xmm1 tmp[17,16,15,14]
%xmm14 tmp[8,7,6,5]
%xmm7 tmp[9,10,11,12]
%xmm11 tmp[13,-,4,-]
*/
movups 108(w), %xmm2
movups 92(w), %xmm3
shufps $0x1b, %xmm3, %xmm3
movups 36(w), %xmm4
movups 20(w), %xmm5
shufps $0x1b, %xmm5, %xmm5
vsubps %xmm1, %xmm0, %xmm6
addps %xmm1, %xmm0
mulps %xmm0, %xmm2
mulps %xmm3, %xmm0
mulps %xmm6, %xmm4
mulps %xmm5, %xmm6
movups 36(out1), %xmm1
movups 20(out1), %xmm3
shufps $0x1b, %xmm6, %xmm6
addps %xmm4, %xmm1
addps %xmm6, %xmm3
shufps $0x1b, %xmm0, %xmm0
movups %xmm2, 36(out2)
movups %xmm0, 20(out2)
movss %xmm1, 32*36(ts)
movss %xmm3, 32*20(ts)
movhlps %xmm1, %xmm2
movhlps %xmm3, %xmm4
movss %xmm2, 32*44(ts)
movss %xmm4, 32*28(ts)
shufps $0xb1, %xmm1, %xmm1
shufps $0xb1, %xmm3, %xmm3
movss %xmm1, 32*40(ts)
movss %xmm3, 32*24(ts)
movhlps %xmm1, %xmm2
movhlps %xmm3, %xmm4
movss %xmm2, 32*48(ts)
movss %xmm4, 32*32(ts)
movhlps %xmm11, %xmm0
movss 124(w), %xmm2
movss 88(w), %xmm3
movss 52(w), %xmm4
movss 16(w), %xmm5
movss %xmm0, %xmm6
addss %xmm11, %xmm0
subss %xmm11, %xmm6
mulss %xmm0, %xmm2
mulss %xmm3, %xmm0
mulss %xmm6, %xmm4
mulss %xmm5, %xmm6
addss 52(out1), %xmm4
addss 16(out1), %xmm6
movss %xmm2, 52(out2)
movss %xmm0, 16(out2)
movss %xmm4, 32*52(ts)
movss %xmm6, 32*16(ts)
movaps %xmm14, %xmm0
movaps %xmm7, %xmm1
MOVUAPS 128(w), %xmm2
movups 72(w), %xmm3
shufps $0x1b, %xmm2, %xmm2
movlps 56(w), %xmm4
movhps 64(w), %xmm4
MOVUAPS (w), %xmm5
shufps $0x1b, %xmm4, %xmm4
vsubps %xmm1, %xmm0, %xmm6
addps %xmm1, %xmm0
mulps %xmm0, %xmm2
mulps %xmm3, %xmm0
mulps %xmm6, %xmm4
mulps %xmm5, %xmm6
movlps 56(out1), %xmm1
movhps 64(out1), %xmm1
movups (out1), %xmm3
shufps $0x1b, %xmm4, %xmm4
addps %xmm6, %xmm3
addps %xmm4, %xmm1
shufps $0x1b, %xmm2, %xmm2
movups %xmm0, (out2)
movlps %xmm2, 56(out2)
movhps %xmm2, 64(out2)
movss %xmm1, 32*56(ts)
movss %xmm3, (ts)
movhlps %xmm1, %xmm2
movhlps %xmm3, %xmm4
movss %xmm2, 32*64(ts)
movss %xmm4, 32*8(ts)
shufps $0xb1, %xmm1, %xmm1
shufps $0xb1, %xmm3, %xmm3
movss %xmm1, 32*60(ts)
movss %xmm3, 32*4(ts)
movhlps %xmm1, %xmm2
movhlps %xmm3, %xmm4
movss %xmm2, 32*68(ts)
movss %xmm4, 32*12(ts)
#ifdef IS_MSABI
movaps (%rsp), %xmm6
movaps 16(%rsp), %xmm7
movaps 32(%rsp), %xmm8
movaps 48(%rsp), %xmm9
movaps 64(%rsp), %xmm10
movaps 80(%rsp), %xmm11
movaps 96(%rsp), %xmm12
movaps 112(%rsp), %xmm13
movaps 128(%rsp), %xmm14
movaps 144(%rsp), %xmm15
mov %rbp, %rsp
pop %rbp
#endif
ret
NONEXEC_STACK

View File

@ -0,0 +1,283 @@
/*
dct36_neon: ARM NEON optimized dct36
copyright 1995-2014 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#ifndef _M_ARM
.code 32
#endif
#ifndef __APPLE__
.fpu neon
#endif
.text
ALIGN16
dct36_neon_COS9:
.word 0x3f5db3d7
.word 0x3f5db3d7
.word 0x3f000000
.word 0x3f000000
.word 0x3f7c1c5c
.word 0x3f7c1c5c
.word 0x3f708fb2
.word 0x3f708fb2
.word 0x3f248dbb
.word 0x3f248dbb
.word 0x3e31d0d4
.word 0x3e31d0d4
.word 0x3eaf1d44
.word 0x3eaf1d44
.word 0x3f441b7d
.word 0x3f441b7d
.word 0x3f007d2b
.word 0x3f0483ee
.word 0x3f0d3b7d
.word 0x3f1c4257
.word 0x40b79454
.word 0x3ff746ea
.word 0x3f976fd9
.word 0x3f5f2944
.word 0x3f800000
.word 0x3f3504f3
ALIGN4
GLOBAL_SYMBOL ASM_NAME(dct36_neon)
#ifdef __ELF__
.type ASM_NAME(dct36_neon), %function
#endif
ASM_NAME(dct36_neon):
push {r4-r5, lr}
vpush {q4-q7}
ldr r4, [sp, #76]
adr r5, dct36_neon_COS9
vceq.i32 q14, q14, q14
veor q15, q15, q15
vshl.i64 q14, q14, #32
vld1.32 {q0, q1}, [r0]!
vld1.32 {q2, q3}, [r0]!
vld1.32 {d8}, [r0]
vext.8 q5, q15, q0, #12
vext.8 q6, q0, q1, #12
vext.8 q7, q1, q2, #12
vext.8 q8, q2, q3, #12
vext.8 d18, d7, d8, #4
vadd.f32 q0, q0, q5
vadd.f32 q1, q1, q6
vadd.f32 q2, q2, q7
vadd.f32 q3, q3, q8
vadd.f32 d8, d8, d18
vext.8 q6, q0, q1, #8
vext.8 q7, q1, q2, #8
vext.8 q8, q2, q3, #8
vext.8 q9, q3, q4, #8
vand q10, q0, q14
vext.8 q0, q15, q0, #8
vand q11, q1, q14
vand q12, q2, q14
vand q13, q3, q14
vadd.f32 q1, q10, q6
vadd.f32 q2, q11, q7
vadd.f32 q3, q12, q8
vadd.f32 q4, q13, q9
/*
q0 in[-,-,0,1]
q1 in[2,3,4,5]
q2 in[6,7,8,9]
q3 in[10,11,12,13]
q4 in[14,15,16,17]
*/
vswp d5, d7
vswp d7, d9
/*
q2 in[6,7,12,13]
q3 in[10,11,16,17]
q4 in[14,15,8,9]
*/
vld1.32 {q5, q6}, [r5, :128]!
vld1.32 {q7, q8}, [r5, :128]!
vmov q9, q0
vmla.f32 q9, q2, q5
/*
q6 COS9_[1,1,2,2]
q7 COS9_[5,5,8,8]
q8 COS9_[7,7,4,4]
q5 COS9_[3,3,6,6]
q9 [ta33,tb33,ta66,tb66]
*/
vmov q10, q9
vmov d26, d0
vmov d27, d5
vmul.f32 q12, q1, q6
vsub.f32 q11, q1, q3
vmla.f32 q10, q3, q7
vsub.f32 q13, q0, q13
vmla.f32 q12, q4, q8
vsub.f32 q11, q11, q4
vmul.f32 q14, q1, q7
vmul.f32 q15, q1, q8
vadd.f32 q12, q12, q10
vmov q10, q9
vmla.f32 q13, q11, q5
vmla.f32 q10, q3, q8
vmla.f32 q14, q4, q6
vmla.f32 q9, q4, q7
vmla.f32 q15, q3, q6
vsub.f32 q14, q14, q10
vsub.f32 q15, q15, q9
/*
q12 [1a-0,1b-0, 2a-0, 2b-0]
q13 [1a-1,1b-1, 2a-1, 2b-1]
q14 [1a-2,1b-2,-2a-2,-2b-2]
q15 [1a-3,1b-3,-2a-3,-2b-3]
*/
vzip.32 q12, q13
vzip.32 q14, q15
vneg.f32 q15, q15
/*
q12 [1a-0,1a-1,1b-0,1b-1]
q13 [2a-0,2a-1,2b-0,2b-1]
q14 [1a-2,1a-3,1b-2,1b-3]
q15 [2a-2,2a-3,2b-2,2b-3]
*/
vswp d25, d28
vswp d27, d30
/*
q12 tmp1a
q13 tmp2a
q14 tmp1b
q15 tmp2b
*/
vsub.f32 d1, d1, d3
vsub.f32 d9, d9, d5
vld1.32 {q5, q6}, [r5, :128]!
vld1.32 {d0}, [r5, :64]
vadd.f32 q10, q14, q15
vsub.f32 q8, q15, q14
vadd.f32 d1, d1, d7
vadd.f32 q9, q12, q13
vsub.f32 q7, q13, q12
vadd.f32 d1, d1, d9
vmul.f32 q10, q10, q5
vmul.f32 q8, q8, q6
vmul.f32 d0, d1, d0
/*
q9 tmp[0,1,2,3]
q10 tmp[17,16,15,14]
q7 tmp[8,7,6,5]
q8 tmp[9,10,11,12]
d0 tmp[4,13]
*/
add r0, r4, #640
add r5, r3, #20
vld1.32 {q1,q2}, [r5]
add r5, r3, #92
vld1.32 {q3,q4}, [r5]
add r5, r1, #20
vld1.32 {q5,q6}, [r5]
vadd.f32 q11, q9, q10
vsub.f32 q12, q9, q10
vmul.f32 q10, q11, q4
vmla.f32 q6, q12, q2
vrev64.32 q11, q11
vrev64.32 q12, q12
vswp d22, d23
vswp d24, d25
vmul.f32 q9, q11, q3
vmla.f32 q5, q12, q1
add r5, r2, #20
vst1.32 {q9,q10}, [r5]
mov r5, #128
vst1.32 {d10[0]}, [r0], r5
vst1.32 {d10[1]}, [r0], r5
vst1.32 {d11[0]}, [r0], r5
vst1.32 {d11[1]}, [r0], r5
vst1.32 {d12[0]}, [r0], r5
vst1.32 {d12[1]}, [r0], r5
vst1.32 {d13[0]}, [r0], r5
vst1.32 {d13[1]}, [r0], r5
add r0, r4, #1792
add r5, r3, #56
vld1.32 {q1}, [r3]
vld1.32 {q2,q3}, [r5]
add r5, r3, #128
vld1.32 {q4}, [r5]
add r5, r1, #56
vld1.32 {q5}, [r1]
vld1.32 {q6}, [r5]
vadd.f32 q9, q7, q8
vsub.f32 q10, q7, q8
vmul.f32 q7, q9, q3
vmla.f32 q5, q10, q1
vrev64.32 q9, q9
vrev64.32 q10, q10
vswp d18, d19
vswp d20, d21
vmul.f32 q8, q9, q4
vmla.f32 q6, q10, q2
add r5, r2, #56
vst1.32 {q7}, [r2]
vst1.32 {q8}, [r5]
mov r5, #128
vst1.32 {d10[0]}, [r4], r5
vst1.32 {d10[1]}, [r4], r5
vst1.32 {d11[0]}, [r4], r5
vst1.32 {d11[1]}, [r4], r5
vst1.32 {d12[0]}, [r0], r5
vst1.32 {d12[1]}, [r0], r5
vst1.32 {d13[0]}, [r0], r5
vst1.32 {d13[1]}, [r0], r5
vtrn.32 d0, d1
add r5, r3, #16
vld1.32 {d2}, [r5]
add r5, r3, #52
vld1.32 {d3}, [r5]
add r5, r3, #88
vld1.32 {d4}, [r5]
add r3, r3, #124
vld1.32 {d5}, [r3]
add r5, r1, #16
vld1.32 {d6}, [r5]
add r1, r1, #52
vld1.32 {d7}, [r1]
vadd.f32 d8, d0, d1
vsub.f32 d9, d0, d1
vmul.f32 d4, d8, d4
vmul.f32 d5, d8, d5
vmla.f32 d6, d9, d2
vmla.f32 d7, d9, d3
add r2, r2, #16
vst1.32 {d4[0]}, [r2]
add r2, r2, #36
vst1.32 {d5[0]}, [r2]
vst1.32 {d6[0]}, [r4]
add r4, r4, #1152
vst1.32 {d7[0]}, [r4]
vpop {q4-q7}
pop {r4-r5, pc}
NONEXEC_STACK

View File

@ -0,0 +1,249 @@
/*
dct36_neon64: NEON optimized dct36 for AArch64
copyright 1995-2014 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN16
dct36_aarch64_COS9:
.word 0x3f5db3d7
.word 0x3f5db3d7
.word 0x3f000000
.word 0x3f000000
.word 0x3f7c1c5c
.word 0x3f7c1c5c
.word 0x3f708fb2
.word 0x3f708fb2
.word 0x3f248dbb
.word 0x3f248dbb
.word 0x3e31d0d4
.word 0x3e31d0d4
.word 0x3eaf1d44
.word 0x3eaf1d44
.word 0x3f441b7d
.word 0x3f441b7d
.word 0x3f007d2b
.word 0x3f0483ee
.word 0x3f0d3b7d
.word 0x3f1c4257
.word 0x40b79454
.word 0x3ff746ea
.word 0x3f976fd9
.word 0x3f5f2944
.word 0x3f800000
.word 0x3f3504f3
.text
ALIGN4
.globl ASM_NAME(dct36_neon64)
#ifdef __ELF__
.type ASM_NAME(dct36_neon64), %function
#endif
ASM_NAME(dct36_neon64):
adrp x5, AARCH64_PCREL_HI(dct36_aarch64_COS9)
add x5, x5, AARCH64_PCREL_LO(dct36_aarch64_COS9)
cmeq v28.16b, v28.16b, v28.16b
eor v29.16b, v29.16b, v29.16b
shl v28.2d, v28.2d, #32
ld1 {v0.4s,v1.4s,v2.4s,v3.4s}, [x0], #64
ld1 {v4.2s}, [x0]
ext v16.16b, v29.16b, v0.16b, #12
ext v17.16b, v0.16b, v1.16b, #12
ext v18.16b, v1.16b, v2.16b, #12
ext v19.16b, v2.16b, v3.16b, #12
ext v20.16b, v3.16b, v4.16b, #12
fadd v0.4s, v0.4s, v16.4s
fadd v1.4s, v1.4s, v17.4s
fadd v2.4s, v2.4s, v18.4s
fadd v3.4s, v3.4s, v19.4s
fadd v4.2s, v4.2s, v20.2s
ext v16.16b, v0.16b, v1.16b, #8
ext v17.16b, v1.16b, v2.16b, #8
ext v18.16b, v2.16b, v3.16b, #8
ext v19.16b, v3.16b, v4.16b, #8
and v20.16b, v0.16b, v28.16b
ext v0.16b, v29.16b, v0.16b, #8
and v21.16b, v1.16b, v28.16b
and v22.16b, v2.16b, v28.16b
and v23.16b, v3.16b, v28.16b
fadd v1.4s, v20.4s, v16.4s
fadd v2.4s, v21.4s, v17.4s
fadd v3.4s, v22.4s, v18.4s
fadd v4.4s, v23.4s, v19.4s
/*
v0 in[-,-,0,1]
v1 in[2,3,4,5]
v2 in[6,7,8,9]
v3 in[10,11,12,13]
v4 in[14,15,16,17]
*/
orr v5.16b, v2.16b, v2.16b
ins v2.d[1], v3.d[1]
ins v3.d[1], v4.d[1]
ins v4.d[1], v5.d[1]
/*
v2 in[6,7,12,13]
v3 in[10,11,16,17]
v4 in[14,15,8,9]
*/
ld1 {v16.4s,v17.4s,v18.4s,v19.4s}, [x5], #64
orr v20.16b, v0.16b, v0.16b
fmla v20.4s, v2.4s, v16.4s
/*
v17 COS9_[1,1,2,2]
v18 COS9_[5,5,8,8]
v19 COS9_[7,7,4,4]
v16 COS9_[3,3,6,6]
v20 [ta33,tb33,ta66,tb66]
*/
orr v21.16b, v20.16b, v20.16b
orr v23.16b, v20.16b, v20.16b
zip2 v25.2d, v29.2d, v2.2d
fsub v22.4s, v1.4s, v3.4s
fmul v24.4s, v1.4s, v17.4s
fmul v26.4s, v1.4s, v18.4s
fmul v27.4s, v1.4s, v19.4s
fmla v21.4s, v3.4s, v18.4s
fmla v23.4s, v3.4s, v19.4s
fmla v20.4s, v4.4s, v18.4s
fsub v25.4s, v0.4s, v25.4s
fsub v22.4s, v22.4s, v4.4s
fmla v24.4s, v4.4s, v19.4s
fmla v26.4s, v4.4s, v17.4s
fmla v27.4s, v3.4s, v17.4s
fmla v25.4s, v22.4s, v16.4s
fadd v24.4s, v24.4s, v21.4s
fsub v26.4s, v26.4s, v23.4s
fsub v27.4s, v27.4s, v20.4s
zip1 v16.4s, v24.4s, v25.4s
zip2 v17.4s, v24.4s, v25.4s
zip1 v18.4s, v26.4s, v27.4s
zip2 v19.4s, v26.4s, v27.4s
fneg v19.4s, v19.4s
zip1 v20.2d, v16.2d, v18.2d
zip1 v21.2d, v17.2d, v19.2d
zip2 v22.2d, v16.2d, v18.2d
zip2 v23.2d, v17.2d, v19.2d
ld1 {v5.4s,v6.4s}, [x5], #32
ld1 {v7.2s}, [x5]
fsub v0.4s, v0.4s, v1.4s
fsub v4.4s, v4.4s, v2.4s
fadd v17.4s, v22.4s, v23.4s
fsub v19.4s, v23.4s, v22.4s
fadd v0.4s, v0.4s, v3.4s
fadd v16.4s, v20.4s, v21.4s
fsub v18.4s, v21.4s, v20.4s
fadd v0.4s, v0.4s, v4.4s
fmul v17.4s, v17.4s, v5.4s
fmul v19.4s, v19.4s, v6.4s
AARCH64_DUP_2D(v0, v0, 1)
fmul v0.2s, v0.2s, v7.2s
/*
v16 tmp[0,1,2,3]
v17 tmp[17,16,15,14]
v18 tmp[8,7,6,5]
v19 tmp[9,10,11,12]
v0 tmp[4,13]
*/
add x0, x4, #640
add x5, x3, #20
add x6, x3, #92
add x7, x1, #20
ld1 {v1.4s,v2.4s}, [x5]
ld1 {v3.4s,v4.4s}, [x6]
ld1 {v5.4s,v6.4s}, [x7]
fadd v20.4s, v16.4s, v17.4s
fsub v21.4s, v16.4s, v17.4s
fmul v4.4s, v20.4s, v4.4s
fmla v6.4s, v21.4s, v2.4s
rev64 v20.4s, v20.4s
rev64 v21.4s, v21.4s
ext v20.16b, v20.16b, v20.16b, #8
ext v21.16b, v21.16b, v21.16b, #8
fmul v3.4s, v20.4s, v3.4s
fmla v5.4s, v21.4s, v1.4s
add x5, x2, #20
mov x9, #128
st1 {v3.4s,v4.4s}, [x5]
st1 {v5.s}[0], [x0], x9
st1 {v5.s}[1], [x0], x9
st1 {v5.s}[2], [x0], x9
st1 {v5.s}[3], [x0], x9
st1 {v6.s}[0], [x0], x9
st1 {v6.s}[1], [x0], x9
st1 {v6.s}[2], [x0], x9
st1 {v6.s}[3], [x0], x9
add x0, x4, #1792
add x5, x3, #56
add x6, x3, #128
add x7, x1, #56
ld1 {v1.4s}, [x3]
ld1 {v2.4s,v3.4s}, [x5]
ld1 {v4.4s}, [x6]
ld1 {v5.4s}, [x1]
ld1 {v6.4s}, [x7]
fadd v20.4s, v18.4s, v19.4s
fsub v21.4s, v18.4s, v19.4s
fmul v3.4s, v20.4s, v3.4s
fmla v5.4s, v21.4s, v1.4s
rev64 v20.4s, v20.4s
rev64 v21.4s, v21.4s
ext v20.16b, v20.16b, v20.16b, #8
ext v21.16b, v21.16b, v21.16b, #8
fmul v4.4s, v20.4s, v4.4s
fmla v6.4s, v21.4s, v2.4s
add x5, x2, #56
st1 {v3.4s}, [x2]
st1 {v4.4s}, [x5]
st1 {v5.s}[0], [x4], x9
st1 {v5.s}[1], [x4], x9
st1 {v5.s}[2], [x4], x9
st1 {v5.s}[3], [x4], x9
st1 {v6.s}[0], [x0], x9
st1 {v6.s}[1], [x0], x9
st1 {v6.s}[2], [x0], x9
st1 {v6.s}[3], [x0], x9
ins v1.s[0], v0.s[1]
ldr s2, [x3, #16]
ldr s3, [x3, #52]
ldr s4, [x3, #88]
ldr s5, [x3, #124]
ldr s6, [x1, #16]
ldr s7, [x1, #52]
fadd s16, s0, s1
fsub s17, s0, s1
fmul s4, s16, s4
fmul s5, s16, s5
fmadd s6, s17, s2, s6
fmadd s7, s17, s3, s7
str s4, [x2, #16]
str s5, [x2, #52]
str s6, [x4]
str s7, [x4, #1152]
ret
NONEXEC_STACK

View File

@ -0,0 +1,387 @@
/*
dct36_sse: SSE optimized dct36
copyright 1995-2013 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#define in %edi
#define out1 %edi
#define out2 %edx
#define w %ecx
#define ts %eax
#define tmp %esi
/*
void dct36_sse(real *inbuf,real *o1,real *o2,real *wintab,real *tsbuf);
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN16
dct36_sse_COS9:
.long 0x3f5db3d7
.long 0x3f5db3d7
.long 0x3f000000
.long 0x3f000000
.long 0x3f7c1c5c
.long 0x3f7c1c5c
.long 0x3f708fb2
.long 0x3f708fb2
.long 0x3f248dbb
.long 0x3f248dbb
.long 0x3e31d0d4
.long 0x3e31d0d4
.long 0x3eaf1d44
.long 0x3eaf1d44
.long 0x3f441b7d
.long 0x3f441b7d
ALIGN16
dct36_sse_tfcos36:
.long 0x3f007d2b
.long 0x3f0483ee
.long 0x3f0d3b7d
.long 0x3f1c4257
.long 0x40b79454
.long 0x3ff746ea
.long 0x3f976fd9
.long 0x3f5f2944
.long 0x3f3504f3
ALIGN16
dct36_sse_mask:
.long 0,0xffffffff,0,0xffffffff
ALIGN16
dct36_sse_sign:
.long 0x80000000,0x80000000,0x80000000,0x80000000
.text
ALIGN16
.globl ASM_NAME(dct36_sse)
ASM_NAME(dct36_sse):
push %ebp
mov %esp, %ebp
and $-16, %esp
sub $80, %esp
push %ebx
push %esi
push %edi
lea 12(%esp), tmp
movl 8(%ebp), in
GET_GOT
lea LOCAL_VAR(dct36_sse_COS9), %eax
lea LOCAL_VAR(dct36_sse_tfcos36), %edx
xorps %xmm0, %xmm0
xorps %xmm5, %xmm5
movlps 64(in), %xmm5
movups 48(in), %xmm4
movups 32(in), %xmm3
movups 16(in), %xmm2
movups (in), %xmm1
movaps %xmm5, %xmm6
shufps $0xe1, %xmm6, %xmm6
movaps %xmm4, %xmm7
shufps $0x93, %xmm7, %xmm7
movss %xmm7, %xmm6
addps %xmm6, %xmm5
movaps %xmm3, %xmm6
shufps $0x93, %xmm6, %xmm6
movss %xmm6, %xmm7
addps %xmm7, %xmm4
movaps %xmm2, %xmm7
shufps $0x93, %xmm7, %xmm7
movss %xmm7, %xmm6
addps %xmm6, %xmm3
movaps %xmm1, %xmm6
shufps $0x93, %xmm6, %xmm6
movss %xmm6, %xmm7
addps %xmm7, %xmm2
movss %xmm0, %xmm6
addps %xmm6, %xmm1
movaps LOCAL_VAR(dct36_sse_mask), %xmm0
movaps %xmm4, %xmm6
shufps $0x4e, %xmm5, %xmm4
movaps %xmm3, %xmm7
shufps $0x4e, %xmm6, %xmm3
andps %xmm0, %xmm6
addps %xmm6, %xmm4
movaps %xmm2, %xmm6
shufps $0x4e, %xmm7, %xmm2
andps %xmm0, %xmm7
addps %xmm7, %xmm3
movaps %xmm1, %xmm7
shufps $0x4e, %xmm6, %xmm1
andps %xmm0, %xmm6
addps %xmm6, %xmm2
movaps %xmm7, %xmm6
andps %xmm0, %xmm7
xorps %xmm0, %xmm0
addps %xmm7, %xmm1
movlhps %xmm6, %xmm0
/*
xmm0 in[-,-,0,1]
xmm1 in[2,3,4,5]
xmm2 in[6,7,8,9]
xmm3 in[10,11,12,13]
xmm4 in[14,15,16,17]
*/
movaps %xmm2, %xmm5
shufps $0xe4, %xmm3, %xmm5
shufps $0xe4, %xmm4, %xmm3
shufps $0xe4, %xmm2, %xmm4
movaps %xmm5, %xmm2
/*
xmm2 in[6,7,12,13]
xmm3 in[10,11,16,17]
xmm4 in[14,15,8,9]
*/
mulps (%eax), %xmm5
addps %xmm0, %xmm5
movaps %xmm0, (tmp)
movaps %xmm2, 16(tmp)
/*
0(tmp) in[-,-,0,1]
xmm5 [ta33,tb33,ta66,tb66]
*/
movaps %xmm1, %xmm6
subps %xmm3, %xmm6
subps %xmm4, %xmm6
xorps %xmm7, %xmm7
shufps $0xe0, %xmm2, %xmm7
mulps (%eax), %xmm6
subps %xmm7, %xmm0
addps %xmm0, %xmm6
movaps %xmm6, 48(tmp)
movaps 16(%eax), %xmm2
movaps %xmm1, %xmm0
movaps %xmm3, %xmm6
movaps %xmm4, %xmm7
mulps %xmm2, %xmm0
mulps 32(%eax), %xmm6
mulps 48(%eax), %xmm7
addps %xmm5, %xmm0
addps %xmm7, %xmm6
addps %xmm6, %xmm0
movaps %xmm0, 32(tmp)
movaps %xmm1, %xmm0
movaps %xmm3, %xmm6
movaps %xmm4, %xmm7
mulps 32(%eax), %xmm0
mulps 48(%eax), %xmm6
mulps %xmm2, %xmm7
subps %xmm5, %xmm0
subps %xmm6, %xmm7
addps %xmm7, %xmm0
movaps %xmm0, 64(tmp)
movaps %xmm1, %xmm6
movaps %xmm4, %xmm7
mulps 48(%eax), %xmm6
mulps %xmm3, %xmm2
mulps 32(%eax), %xmm7
subps %xmm5, %xmm6
subps %xmm7, %xmm2
addps %xmm2, %xmm6
movaps (tmp), %xmm0
movss 32(%edx), %xmm5
subps %xmm1, %xmm0
subps 16(tmp), %xmm4
addps %xmm3, %xmm0
addps %xmm4, %xmm0
shufps $0xaf, %xmm0, %xmm0
mulss %xmm5, %xmm0
movaps %xmm0, (tmp)
movaps 32(tmp), %xmm0
movaps 48(tmp), %xmm1
movaps 64(tmp), %xmm2
/*
xmm0 [1a-0,1b-0, 2a-0, 2b-0]
xmm1 [1a-1,1b-1, 2a-1, 2b-1]
xmm2 [1a-2,1b-2,-2a-2,-2b-2]
xmm6 [1a-3,1b-3,-2a-3,-2b-3]
*/
movaps %xmm0, %xmm3
unpcklps %xmm1, %xmm0
unpckhps %xmm1, %xmm3
movaps %xmm2, %xmm5
unpcklps %xmm6, %xmm2
unpckhps %xmm6, %xmm5
xorps LOCAL_VAR(dct36_sse_sign), %xmm5
/*
xmm0 [1a-0,1a-1,1b-0,1b-1]
xmm3 [2a-0,2a-1,2b-0,2b-1]
xmm2 [1a-2,1a-3,1b-2,1b-3]
xmm5 [2a-2,2a-3,2b-2,2b-3]
*/
movaps %xmm0, %xmm1
movlhps %xmm2, %xmm0
movhlps %xmm1, %xmm2
movaps %xmm3, %xmm4
movlhps %xmm5, %xmm3
movhlps %xmm4, %xmm5
/*
xmm0 tmp1a
xmm3 tmp2a
xmm2 tmp1b
xmm5 tmp2b
*/
movaps (%edx), %xmm6
movaps 16(%edx), %xmm7
movaps %xmm5, %xmm1
addps %xmm2, %xmm5
subps %xmm2, %xmm1
movaps %xmm3, %xmm2
addps %xmm0, %xmm3
subps %xmm0, %xmm2
mulps %xmm6, %xmm5
mulps %xmm1, %xmm7
movaps %xmm2, 16(tmp)
/*
%xmm3 tmp[0,1,2,3]
%xmm5 tmp[17,16,15,14]
16(tmp) tmp[8,7,6,5]
%xmm7 tmp[9,10,11,12]
0(tmp) tmp[13,-,4,-]
*/
movl 12(%ebp), out1
movl 16(%ebp), out2
movl 20(%ebp), w
movl 24(%ebp), ts
movaps %xmm3, %xmm0
movaps %xmm5, %xmm1
movups 108(w), %xmm2
movups 92(w), %xmm3
shufps $0x1b, %xmm3, %xmm3
movups 36(w), %xmm4
movups 20(w), %xmm5
shufps $0x1b, %xmm5, %xmm5
movaps %xmm0, %xmm6
addps %xmm1, %xmm0
subps %xmm1, %xmm6
mulps %xmm0, %xmm2
mulps %xmm3, %xmm0
mulps %xmm6, %xmm4
mulps %xmm5, %xmm6
movups 36(out1), %xmm1
movups 20(out1), %xmm3
shufps $0x1b, %xmm6, %xmm6
addps %xmm4, %xmm1
addps %xmm6, %xmm3
shufps $0x1b, %xmm0, %xmm0
movups %xmm2, 36(out2)
movups %xmm0, 20(out2)
movss %xmm1, 32*36(ts)
movss %xmm3, 32*20(ts)
movhlps %xmm1, %xmm2
movhlps %xmm3, %xmm4
movss %xmm2, 32*44(ts)
movss %xmm4, 32*28(ts)
shufps $0xb1, %xmm1, %xmm1
shufps $0xb1, %xmm3, %xmm3
movss %xmm1, 32*40(ts)
movss %xmm3, 32*24(ts)
movhlps %xmm1, %xmm2
movhlps %xmm3, %xmm4
movss %xmm2, 32*48(ts)
movss %xmm4, 32*32(ts)
movss 8(tmp), %xmm0
movss (tmp), %xmm1
movss 124(w), %xmm2
movss 88(w), %xmm3
movss 52(w), %xmm4
movss 16(w), %xmm5
movss %xmm0, %xmm6
addss %xmm1, %xmm0
subss %xmm1, %xmm6
mulss %xmm0, %xmm2
mulss %xmm3, %xmm0
mulss %xmm6, %xmm4
mulss %xmm5, %xmm6
addss 52(out1), %xmm4
addss 16(out1), %xmm6
movss %xmm2, 52(out2)
movss %xmm0, 16(out2)
movss %xmm4, 32*52(ts)
movss %xmm6, 32*16(ts)
movaps 16(tmp), %xmm0
movaps %xmm7, %xmm1
MOVUAPS 128(w), %xmm2
movups 72(w), %xmm3
shufps $0x1b, %xmm2, %xmm2
movlps 56(w), %xmm4
movhps 64(w), %xmm4
MOVUAPS (w), %xmm5
shufps $0x1b, %xmm4, %xmm4
movaps %xmm0, %xmm6
addps %xmm1, %xmm0
subps %xmm1, %xmm6
mulps %xmm0, %xmm2
mulps %xmm3, %xmm0
mulps %xmm6, %xmm4
mulps %xmm5, %xmm6
movlps 56(out1), %xmm1
movhps 64(out1), %xmm1
movups (out1), %xmm3
shufps $0x1b, %xmm4, %xmm4
addps %xmm6, %xmm3
addps %xmm4, %xmm1
shufps $0x1b, %xmm2, %xmm2
movups %xmm0, (out2)
movlps %xmm2, 56(out2)
movhps %xmm2, 64(out2)
movss %xmm1, 32*56(ts)
movss %xmm3, (ts)
movhlps %xmm1, %xmm2
movhlps %xmm3, %xmm4
movss %xmm2, 32*64(ts)
movss %xmm4, 32*8(ts)
shufps $0xb1, %xmm1, %xmm1
shufps $0xb1, %xmm3, %xmm3
movss %xmm1, 32*60(ts)
movss %xmm3, 32*4(ts)
movhlps %xmm1, %xmm2
movhlps %xmm3, %xmm4
movss %xmm2, 32*68(ts)
movss %xmm4, 32*12(ts)
pop %edi
pop %esi
pop %ebx
mov %ebp, %esp
pop %ebp
ret
NONEXEC_STACK

View File

@ -0,0 +1,394 @@
/*
dct36_x86_64: SSE optimized dct36 for x86-64
copyright 1995-2013 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#ifdef IS_MSABI
#define in %rcx
#define out1 %rdx
#define out2 %r8
#define w %r9
#define ts %r10
#define COS9_ %rax
#define tfcos36_ %r11
#else
#define in %rdi
#define out1 %rsi
#define out2 %rdx
#define w %rcx
#define ts %r8
#define COS9_ %rax
#define tfcos36_ %r9
#endif
/*
void dct36_x86_64(real *inbuf,real *o1,real *o2,real *wintab,real *tsbuf);
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN16
dct36_x86_64_COS9:
.long 0x3f5db3d7
.long 0x3f5db3d7
.long 0x3f000000
.long 0x3f000000
.long 0x3f7c1c5c
.long 0x3f7c1c5c
.long 0x3f708fb2
.long 0x3f708fb2
.long 0x3f248dbb
.long 0x3f248dbb
.long 0x3e31d0d4
.long 0x3e31d0d4
.long 0x3eaf1d44
.long 0x3eaf1d44
.long 0x3f441b7d
.long 0x3f441b7d
ALIGN16
dct36_x86_64_tfcos36:
.long 0x3f007d2b
.long 0x3f0483ee
.long 0x3f0d3b7d
.long 0x3f1c4257
.long 0x40b79454
.long 0x3ff746ea
.long 0x3f976fd9
.long 0x3f5f2944
.long 0x3f3504f3
ALIGN16
dct36_x86_64_mask:
.long 0,0xffffffff,0,0xffffffff
ALIGN16
dct36_x86_64_sign:
.long 0x80000000,0x80000000,0x80000000,0x80000000
.text
ALIGN16
.globl ASM_NAME(dct36_x86_64)
ASM_NAME(dct36_x86_64):
#ifdef IS_MSABI
push %rbp
mov %rsp, %rbp
sub $160, %rsp
movaps %xmm6, (%rsp)
movaps %xmm7, 16(%rsp)
movaps %xmm8, 32(%rsp)
movaps %xmm9, 48(%rsp)
movaps %xmm10, 64(%rsp)
movaps %xmm11, 80(%rsp)
movaps %xmm12, 96(%rsp)
movaps %xmm13, 112(%rsp)
movaps %xmm14, 128(%rsp)
movaps %xmm15, 144(%rsp)
movq 48(%rbp), ts
#endif
lea dct36_x86_64_COS9(%rip), COS9_
lea dct36_x86_64_tfcos36(%rip), tfcos36_
xorps %xmm5, %xmm5
movups (in), %xmm1
movups 16(in), %xmm2
movups 32(in), %xmm3
movups 48(in), %xmm4
movlps 64(in), %xmm5
xorps %xmm6, %xmm6
movaps %xmm1, %xmm7
shufps $0x93, %xmm7, %xmm7
movaps %xmm2, %xmm8
shufps $0x93, %xmm8, %xmm8
movaps %xmm3, %xmm9
shufps $0x93, %xmm9, %xmm9
movaps %xmm4, %xmm10
shufps $0x93, %xmm10, %xmm10
movaps %xmm5, %xmm11
shufps $0xe1, %xmm11, %xmm11
movss %xmm10, %xmm11
addps %xmm11, %xmm5
movss %xmm9, %xmm10
addps %xmm10, %xmm4
movss %xmm8, %xmm9
addps %xmm9, %xmm3
movss %xmm7, %xmm8
addps %xmm8, %xmm2
movss %xmm6, %xmm7
addps %xmm7, %xmm1
movaps dct36_x86_64_mask(%rip), %xmm0
movaps %xmm4, %xmm6
shufps $0x4e, %xmm5, %xmm4
movaps %xmm3, %xmm7
shufps $0x4e, %xmm6, %xmm3
andps %xmm0, %xmm6
addps %xmm6, %xmm4
movaps %xmm2, %xmm6
shufps $0x4e, %xmm7, %xmm2
andps %xmm0, %xmm7
addps %xmm7, %xmm3
movaps %xmm1, %xmm7
shufps $0x4e, %xmm6, %xmm1
andps %xmm0, %xmm6
addps %xmm6, %xmm2
movaps %xmm7, %xmm6
andps %xmm0, %xmm7
xorps %xmm0, %xmm0
addps %xmm7, %xmm1
movlhps %xmm6, %xmm0
/*
xmm0 in[-,-,0,1]
xmm1 in[2,3,4,5]
xmm2 in[6,7,8,9]
xmm3 in[10,11,12,13]
xmm4 in[14,15,16,17]
*/
movaps %xmm2, %xmm5
shufps $0xe4, %xmm3, %xmm5
shufps $0xe4, %xmm4, %xmm3
shufps $0xe4, %xmm2, %xmm4
movaps %xmm5, %xmm2
/*
xmm2 in[6,7,12,13]
xmm3 in[10,11,16,17]
xmm4 in[14,15,8,9]
*/
movaps (COS9_), %xmm15
movaps 16(COS9_), %xmm6
movaps 32(COS9_), %xmm7
movaps 48(COS9_), %xmm8
mulps %xmm15, %xmm5
addps %xmm0, %xmm5
/*
xmm5 [ta33,tb33,ta66,tb66]
xmm6 COS9_[1,1,2,2]
xmm7 COS9_[5,5,8,8]
xmm8 COS9_[7,7,4,4]
xmm15 COS9_[3,3,6,6]
*/
movaps %xmm6, %xmm9
movaps %xmm7, %xmm12
movaps %xmm8, %xmm13
mulps %xmm1, %xmm9
mulps %xmm3, %xmm12
mulps %xmm4, %xmm13
addps %xmm5, %xmm9
addps %xmm13, %xmm12
addps %xmm9, %xmm12
movaps %xmm1, %xmm13
subps %xmm3, %xmm13
movaps %xmm0, %xmm10
shufps $0xe0, %xmm2, %xmm10
movaps %xmm0, %xmm14
subps %xmm10, %xmm14
subps %xmm4, %xmm13
mulps %xmm15, %xmm13
addps %xmm14, %xmm13
movaps %xmm7, %xmm9
movaps %xmm8, %xmm15
movaps %xmm6, %xmm14
mulps %xmm1, %xmm9
mulps %xmm3, %xmm15
mulps %xmm4, %xmm14
subps %xmm5, %xmm9
subps %xmm15, %xmm14
addps %xmm9, %xmm14
mulps %xmm1, %xmm8
mulps %xmm3, %xmm6
mulps %xmm4, %xmm7
subps %xmm5, %xmm8
subps %xmm7, %xmm6
addps %xmm6, %xmm8
movaps %xmm8, %xmm15
movss 32(tfcos36_), %xmm5
subps %xmm1, %xmm0
subps %xmm2, %xmm4
addps %xmm3, %xmm0
addps %xmm4, %xmm0
shufps $0xaf, %xmm0, %xmm0
mulss %xmm5, %xmm0
movaps %xmm0, %xmm11
/*
xmm12 [1a-0,1b-0, 2a-0, 2b-0]
xmm13 [1a-1,1b-1, 2a-1, 2b-1]
xmm14 [1a-2,1b-2,-2a-2,-2b-2]
xmm15 [1a-3,1b-3,-2a-3,-2b-3]
*/
movaps %xmm12, %xmm5
unpckhps %xmm13, %xmm5
unpcklps %xmm13, %xmm12
movaps %xmm14, %xmm6
unpckhps %xmm15, %xmm6
unpcklps %xmm15, %xmm14
xorps dct36_x86_64_sign(%rip), %xmm6
/*
xmm12 [1a-0,1a-1,1b-0,1b-1]
xmm5 [2a-0,2a-1,2b-0,2b-1]
xmm14 [1a-2,1a-3,1b-2,1b-3]
xmm6 [2a-2,2a-3,2b-2,2b-3]
*/
movaps %xmm12, %xmm0
movlhps %xmm14, %xmm12
movhlps %xmm0, %xmm14
movaps %xmm5, %xmm0
movlhps %xmm6, %xmm0
movhlps %xmm5, %xmm6
movaps %xmm6, %xmm15
/*
xmm12 tmp1a
xmm0 tmp2a
xmm14 tmp1b
xmm15 tmp2b
*/
movaps (tfcos36_), %xmm6
movaps 16(tfcos36_), %xmm7
movaps %xmm15, %xmm10
addps %xmm14, %xmm15
subps %xmm14, %xmm10
movaps %xmm0, %xmm14
addps %xmm12, %xmm0
subps %xmm12, %xmm14
mulps %xmm6, %xmm15
mulps %xmm10, %xmm7
/*
%xmm0 tmp[0,1,2,3]
%xmm15 tmp[17,16,15,14]
%xmm14 tmp[8,7,6,5]
%xmm7 tmp[9,10,11,12]
%xmm11 tmp[13,-,4,-]
*/
movaps %xmm15, %xmm1
movups 108(w), %xmm2
movups 92(w), %xmm3
shufps $0x1b, %xmm3, %xmm3
movups 36(w), %xmm4
movups 20(w), %xmm5
shufps $0x1b, %xmm5, %xmm5
movaps %xmm0, %xmm6
addps %xmm1, %xmm0
subps %xmm1, %xmm6
mulps %xmm0, %xmm2
mulps %xmm3, %xmm0
mulps %xmm6, %xmm4
mulps %xmm5, %xmm6
movups 36(out1), %xmm1
movups 20(out1), %xmm3
shufps $0x1b, %xmm6, %xmm6
addps %xmm4, %xmm1
addps %xmm6, %xmm3
shufps $0x1b, %xmm0, %xmm0
movups %xmm2, 36(out2)
movups %xmm0, 20(out2)
movss %xmm1, 32*36(ts)
movss %xmm3, 32*20(ts)
movhlps %xmm1, %xmm2
movhlps %xmm3, %xmm4
movss %xmm2, 32*44(ts)
movss %xmm4, 32*28(ts)
shufps $0xb1, %xmm1, %xmm1
shufps $0xb1, %xmm3, %xmm3
movss %xmm1, 32*40(ts)
movss %xmm3, 32*24(ts)
movhlps %xmm1, %xmm2
movhlps %xmm3, %xmm4
movss %xmm2, 32*48(ts)
movss %xmm4, 32*32(ts)
movhlps %xmm11, %xmm0
movaps %xmm11, %xmm1
movss 124(w), %xmm2
movss 88(w), %xmm3
movss 52(w), %xmm4
movss 16(w), %xmm5
movss %xmm0, %xmm6
addss %xmm1, %xmm0
subss %xmm1, %xmm6
mulss %xmm0, %xmm2
mulss %xmm3, %xmm0
mulss %xmm6, %xmm4
mulss %xmm5, %xmm6
addss 52(out1), %xmm4
addss 16(out1), %xmm6
movss %xmm2, 52(out2)
movss %xmm0, 16(out2)
movss %xmm4, 32*52(ts)
movss %xmm6, 32*16(ts)
movaps %xmm14, %xmm0
movaps %xmm7, %xmm1
MOVUAPS 128(w), %xmm2
movups 72(w), %xmm3
shufps $0x1b, %xmm2, %xmm2
movlps 56(w), %xmm4
movhps 64(w), %xmm4
MOVUAPS (w), %xmm5
shufps $0x1b, %xmm4, %xmm4
movaps %xmm0, %xmm6
addps %xmm1, %xmm0
subps %xmm1, %xmm6
mulps %xmm0, %xmm2
mulps %xmm3, %xmm0
mulps %xmm6, %xmm4
mulps %xmm5, %xmm6
movlps 56(out1), %xmm1
movhps 64(out1), %xmm1
movups (out1), %xmm3
shufps $0x1b, %xmm4, %xmm4
addps %xmm6, %xmm3
addps %xmm4, %xmm1
shufps $0x1b, %xmm2, %xmm2
movups %xmm0, (out2)
movlps %xmm2, 56(out2)
movhps %xmm2, 64(out2)
movss %xmm1, 32*56(ts)
movss %xmm3, (ts)
movhlps %xmm1, %xmm2
movhlps %xmm3, %xmm4
movss %xmm2, 32*64(ts)
movss %xmm4, 32*8(ts)
shufps $0xb1, %xmm1, %xmm1
shufps $0xb1, %xmm3, %xmm3
movss %xmm1, 32*60(ts)
movss %xmm3, 32*4(ts)
movhlps %xmm1, %xmm2
movhlps %xmm3, %xmm4
movss %xmm2, 32*68(ts)
movss %xmm4, 32*12(ts)
#ifdef IS_MSABI
movaps (%rsp), %xmm6
movaps 16(%rsp), %xmm7
movaps 32(%rsp), %xmm8
movaps 48(%rsp), %xmm9
movaps 64(%rsp), %xmm10
movaps 80(%rsp), %xmm11
movaps 96(%rsp), %xmm12
movaps 112(%rsp), %xmm13
movaps 128(%rsp), %xmm14
movaps 144(%rsp), %xmm15
mov %rbp, %rsp
pop %rbp
#endif
ret
NONEXEC_STACK

View File

@ -0,0 +1,174 @@
/*
dct64.c: DCT64, the plain C version
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
/*
* 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 "mpg123lib_intern.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] = REAL_SCALE_DCT64(bufs[0]);
out0[0x10*15] = REAL_SCALE_DCT64(bufs[16+0] + bufs[16+8]);
out0[0x10*14] = REAL_SCALE_DCT64(bufs[8]);
out0[0x10*13] = REAL_SCALE_DCT64(bufs[16+8] + bufs[16+4]);
out0[0x10*12] = REAL_SCALE_DCT64(bufs[4]);
out0[0x10*11] = REAL_SCALE_DCT64(bufs[16+4] + bufs[16+12]);
out0[0x10*10] = REAL_SCALE_DCT64(bufs[12]);
out0[0x10* 9] = REAL_SCALE_DCT64(bufs[16+12] + bufs[16+2]);
out0[0x10* 8] = REAL_SCALE_DCT64(bufs[2]);
out0[0x10* 7] = REAL_SCALE_DCT64(bufs[16+2] + bufs[16+10]);
out0[0x10* 6] = REAL_SCALE_DCT64(bufs[10]);
out0[0x10* 5] = REAL_SCALE_DCT64(bufs[16+10] + bufs[16+6]);
out0[0x10* 4] = REAL_SCALE_DCT64(bufs[6]);
out0[0x10* 3] = REAL_SCALE_DCT64(bufs[16+6] + bufs[16+14]);
out0[0x10* 2] = REAL_SCALE_DCT64(bufs[14]);
out0[0x10* 1] = REAL_SCALE_DCT64(bufs[16+14] + bufs[16+1]);
out0[0x10* 0] = REAL_SCALE_DCT64(bufs[1]);
out1[0x10* 0] = REAL_SCALE_DCT64(bufs[1]);
out1[0x10* 1] = REAL_SCALE_DCT64(bufs[16+1] + bufs[16+9]);
out1[0x10* 2] = REAL_SCALE_DCT64(bufs[9]);
out1[0x10* 3] = REAL_SCALE_DCT64(bufs[16+9] + bufs[16+5]);
out1[0x10* 4] = REAL_SCALE_DCT64(bufs[5]);
out1[0x10* 5] = REAL_SCALE_DCT64(bufs[16+5] + bufs[16+13]);
out1[0x10* 6] = REAL_SCALE_DCT64(bufs[13]);
out1[0x10* 7] = REAL_SCALE_DCT64(bufs[16+13] + bufs[16+3]);
out1[0x10* 8] = REAL_SCALE_DCT64(bufs[3]);
out1[0x10* 9] = REAL_SCALE_DCT64(bufs[16+3] + bufs[16+11]);
out1[0x10*10] = REAL_SCALE_DCT64(bufs[11]);
out1[0x10*11] = REAL_SCALE_DCT64(bufs[16+11] + bufs[16+7]);
out1[0x10*12] = REAL_SCALE_DCT64(bufs[7]);
out1[0x10*13] = REAL_SCALE_DCT64(bufs[16+7] + bufs[16+15]);
out1[0x10*14] = REAL_SCALE_DCT64(bufs[15]);
out1[0x10*15] = REAL_SCALE_DCT64(bufs[16+15]);
}

View File

@ -0,0 +1,749 @@
/*
dct64_3dnow.s: Replacement of dct64() with AMD's 3DNow! SIMD operations support
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Syuuhei Kashiyama
Original "license" statement:
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.
*/
#include "mangle.h"
.globl ASM_NAME(dct64_3dnow)
/* .type ASM_NAME(dct64_3dnow),@function */
ASM_NAME(dct64_3dnow):
subl $256,%esp
pushl %ebp
pushl %edi
pushl %esi
pushl %ebx
#undef _EBX_
#define _EBX_ %ecx
GET_GOT
leal 16(%esp),%ebx
movl 284(%esp),%edi
movl 276(%esp),%ebp
movl 280(%esp),%edx
leal 128(%ebx),%esi
/* femms */
/* 1 */
#if defined(PIC) && defined(__APPLE__)
movl GLOBAL_VAR_PTR(pnts),%eax
movl (%eax),%eax
#else
movl GLOBAL_VAR(pnts),%eax
#endif
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 */
#if defined(PIC) && defined(__APPLE__)
movl GLOBAL_VAR_PTR(pnts),%eax
movl 4(%eax),%eax
#else
movl 4+GLOBAL_VAR(pnts),%eax
#endif
/* 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 */
#if defined(PIC) && defined(__APPLE__)
movl GLOBAL_VAR_PTR(pnts),%eax
movl 8(%eax),%eax
#else
movl 8+GLOBAL_VAR(pnts),%eax
#endif
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 */
#if defined(PIC) && defined(__APPLE__)
movl GLOBAL_VAR_PTR(pnts),%eax
movl 12(%eax),%eax
#else
movl 12+GLOBAL_VAR(pnts),%eax
#endif
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
#if defined(PIC) && defined(__APPLE__)
movl GLOBAL_VAR_PTR(pnts),%eax
movl 16(%eax),%eax
#else
movl 16+GLOBAL_VAR(pnts),%eax
#endif
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
#if defined(PIC) && defined(__APPLE__)
.section __IMPORT,__pointers,non_lazy_symbol_pointers
L_pnts:
.indirect_symbol ASM_NAME(pnts)
.long 0
#endif
NONEXEC_STACK

View File

@ -0,0 +1,735 @@
/*
dct64_3dnowext: extended 3DNow optimized DCT64
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
Transformed back into standalone asm, with help of
gcc -S -DHAVE_CONFIG_H -I. -march=k6-3 -O3 -Wall -pedantic -fno-strict-aliasing -DREAL_IS_FLOAT -c -o dct64_3dnowext.{S,c}
MPlayer comment follows.
*/
/*
* This code was taken from http://www.mpg123.org
* See ChangeLog of mpg123-0.59s-pre.1 for detail
* Applied to mplayer by Nick Kurshev <nickols_k@mail.ru>
* Partial 3dnowex-DSP! optimization by Nick Kurshev
*
* TODO: optimize scalar 3dnow! code
* Warning: Phases 7 & 8 are not tested
*/
#include "mangle.h"
.data
ALIGN4
/* .type plus_1f, @object
.size plus_1f, 4 */
plus_1f:
.long 1065353216
ALIGN8
/* .type x_plus_minus_3dnow, @object
.size x_plus_minus_3dnow, 8 */
x_plus_minus_3dnow:
.long 0
.long -2147483648
.text
ALIGN32
.globl ASM_NAME(dct64_3dnowext)
/* .type ASM_NAME(dct64_3dnowext), @function */
ASM_NAME(dct64_3dnowext):
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %esi
pushl %ebx
subl $260, %esp
GET_GOT
#if defined(OPT_X86) && defined(PIC)
movl _EBX_, (%esp) /* save PIC register */
#endif
/* APP */
movl 16(%ebp),%eax
leal 128+-268(%ebp),%edx
movl 8(%ebp),%esi
movl 12(%ebp),%edi
#if defined(PIC) && defined(__APPLE__)
movl GLOBAL_VAR_PTR(costab_mmxsse),%ebx
#else
leal GLOBAL_VAR(costab_mmxsse),%ebx
#endif
leal -268(%ebp),%ecx
movq (%eax), %mm0
movq 8(%eax), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 120(%eax), %mm1
pswapd 112(%eax), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, (%edx)
movq %mm4, 8(%edx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul (%ebx), %mm3
pfmul 8(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 120(%edx)
movq %mm7, 112(%edx)
movq 16(%eax), %mm0
movq 24(%eax), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 104(%eax), %mm1
pswapd 96(%eax), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 16(%edx)
movq %mm4, 24(%edx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul 16(%ebx), %mm3
pfmul 24(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 104(%edx)
movq %mm7, 96(%edx)
movq 32(%eax), %mm0
movq 40(%eax), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 88(%eax), %mm1
pswapd 80(%eax), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 32(%edx)
movq %mm4, 40(%edx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul 32(%ebx), %mm3
pfmul 40(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 88(%edx)
movq %mm7, 80(%edx)
movq 48(%eax), %mm0
movq 56(%eax), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 72(%eax), %mm1
pswapd 64(%eax), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 48(%edx)
movq %mm4, 56(%edx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul 48(%ebx), %mm3
pfmul 56(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 72(%edx)
movq %mm7, 64(%edx)
movq (%edx), %mm0
movq 8(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 56(%edx), %mm1
pswapd 48(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, (%ecx)
movq %mm4, 8(%ecx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul 64(%ebx), %mm3
pfmul 72(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 56(%ecx)
movq %mm7, 48(%ecx)
movq 16(%edx), %mm0
movq 24(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 40(%edx), %mm1
pswapd 32(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 16(%ecx)
movq %mm4, 24(%ecx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul 80(%ebx), %mm3
pfmul 88(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 40(%ecx)
movq %mm7, 32(%ecx)
movq 64(%edx), %mm0
movq 72(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 120(%edx), %mm1
pswapd 112(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 64(%ecx)
movq %mm4, 72(%ecx)
pfsubr %mm1, %mm3
pfsubr %mm5, %mm7
pfmul 64(%ebx), %mm3
pfmul 72(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 120(%ecx)
movq %mm7, 112(%ecx)
movq 80(%edx), %mm0
movq 88(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 104(%edx), %mm1
pswapd 96(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 80(%ecx)
movq %mm4, 88(%ecx)
pfsubr %mm1, %mm3
pfsubr %mm5, %mm7
pfmul 80(%ebx), %mm3
pfmul 88(%ebx), %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 104(%ecx)
movq %mm7, 96(%ecx)
movq 96(%ebx), %mm2
movq 104(%ebx), %mm6
movq (%ecx), %mm0
movq 8(%ecx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 24(%ecx), %mm1
pswapd 16(%ecx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, (%edx)
movq %mm4, 8(%edx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm6, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 24(%edx)
movq %mm7, 16(%edx)
movq 32(%ecx), %mm0
movq 40(%ecx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 56(%ecx), %mm1
pswapd 48(%ecx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 32(%edx)
movq %mm4, 40(%edx)
pfsubr %mm1, %mm3
pfsubr %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm6, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 56(%edx)
movq %mm7, 48(%edx)
movq 64(%ecx), %mm0
movq 72(%ecx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 88(%ecx), %mm1
pswapd 80(%ecx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 64(%edx)
movq %mm4, 72(%edx)
pfsub %mm1, %mm3
pfsub %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm6, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 88(%edx)
movq %mm7, 80(%edx)
movq 96(%ecx), %mm0
movq 104(%ecx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 120(%ecx), %mm1
pswapd 112(%ecx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 96(%edx)
movq %mm4, 104(%edx)
pfsubr %mm1, %mm3
pfsubr %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm6, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 120(%edx)
movq %mm7, 112(%edx)
movq 112(%ebx), %mm2
movq (%edx), %mm0
movq 16(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 8(%edx), %mm1
pswapd 24(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, (%ecx)
movq %mm4, 16(%ecx)
pfsub %mm1, %mm3
pfsubr %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm2, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 8(%ecx)
movq %mm7, 24(%ecx)
movq 32(%edx), %mm0
movq 48(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 40(%edx), %mm1
pswapd 56(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 32(%ecx)
movq %mm4, 48(%ecx)
pfsub %mm1, %mm3
pfsubr %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm2, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 40(%ecx)
movq %mm7, 56(%ecx)
movq 64(%edx), %mm0
movq 80(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 72(%edx), %mm1
pswapd 88(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 64(%ecx)
movq %mm4, 80(%ecx)
pfsub %mm1, %mm3
pfsubr %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm2, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 72(%ecx)
movq %mm7, 88(%ecx)
movq 96(%edx), %mm0
movq 112(%edx), %mm4
movq %mm0, %mm3
movq %mm4, %mm7
pswapd 104(%edx), %mm1
pswapd 120(%edx), %mm5
pfadd %mm1, %mm0
pfadd %mm5, %mm4
movq %mm0, 96(%ecx)
movq %mm4, 112(%ecx)
pfsub %mm1, %mm3
pfsubr %mm5, %mm7
pfmul %mm2, %mm3
pfmul %mm2, %mm7
pswapd %mm3, %mm3
pswapd %mm7, %mm7
movq %mm3, 104(%ecx)
movq %mm7, 120(%ecx)
#if defined(OPT_X86) && defined(PIC)
#undef _EBX_
#define _EBX_ %eax
movl (%esp), _EBX_
#endif
movd LOCAL_VAR(plus_1f), %mm6
punpckldq 120(%ebx), %mm6
movq LOCAL_VAR(x_plus_minus_3dnow), %mm7
movq 32(%ecx), %mm0
movq 64(%ecx), %mm2
movq %mm0, %mm1
movq %mm2, %mm3
pxor %mm7, %mm1
pxor %mm7, %mm3
pfacc %mm1, %mm0
pfacc %mm3, %mm2
pfmul %mm6, %mm0
pfmul %mm6, %mm2
movq %mm0, 32(%edx)
movq %mm2, 64(%edx)
movd 44(%ecx), %mm0
movd 40(%ecx), %mm2
movd 120(%ebx), %mm3
punpckldq 76(%ecx), %mm0
punpckldq 72(%ecx), %mm2
punpckldq %mm3, %mm3
movq %mm0, %mm4
movq %mm2, %mm5
pfsub %mm2, %mm0
pfmul %mm3, %mm0
movq %mm0, %mm1
pfadd %mm5, %mm0
pfadd %mm4, %mm0
movq %mm0, %mm2
punpckldq %mm1, %mm0
punpckhdq %mm1, %mm2
movq %mm0, 40(%edx)
movq %mm2, 72(%edx)
movd 48(%ecx), %mm3
movd 60(%ecx), %mm2
pfsub 52(%ecx), %mm3
pfsub 56(%ecx), %mm2
pfmul 120(%ebx), %mm3
pfmul 120(%ebx), %mm2
movq %mm2, %mm1
pfadd 56(%ecx), %mm1
pfadd 60(%ecx), %mm1
movq %mm1, %mm0
pfadd 48(%ecx), %mm0
pfadd 52(%ecx), %mm0
pfadd %mm3, %mm1
punpckldq %mm2, %mm1
pfadd %mm3, %mm2
punpckldq %mm2, %mm0
movq %mm1, 56(%edx)
movq %mm0, 48(%edx)
movd 92(%ecx), %mm1
pfsub 88(%ecx), %mm1
pfmul 120(%ebx), %mm1
movd %mm1, 92(%edx)
pfadd 92(%ecx), %mm1
pfadd 88(%ecx), %mm1
movq %mm1, %mm0
pfadd 80(%ecx), %mm0
pfadd 84(%ecx), %mm0
movd %mm0, 80(%edx)
movd 80(%ecx), %mm0
pfsub 84(%ecx), %mm0
pfmul 120(%ebx), %mm0
pfadd %mm0, %mm1
pfadd 92(%edx), %mm0
punpckldq %mm1, %mm0
movq %mm0, 84(%edx)
movq 96(%ecx), %mm0
movq %mm0, %mm1
pxor %mm7, %mm1
pfacc %mm1, %mm0
pfmul %mm6, %mm0
movq %mm0, 96(%edx)
movd 108(%ecx), %mm0
pfsub 104(%ecx), %mm0
pfmul 120(%ebx), %mm0
movd %mm0, 108(%edx)
pfadd 104(%ecx), %mm0
pfadd 108(%ecx), %mm0
movd %mm0, 104(%edx)
movd 124(%ecx), %mm1
pfsub 120(%ecx), %mm1
pfmul 120(%ebx), %mm1
movd %mm1, 124(%edx)
pfadd 120(%ecx), %mm1
pfadd 124(%ecx), %mm1
movq %mm1, %mm0
pfadd 112(%ecx), %mm0
pfadd 116(%ecx), %mm0
movd %mm0, 112(%edx)
movd 112(%ecx), %mm0
pfsub 116(%ecx), %mm0
pfmul 120(%ebx), %mm0
pfadd %mm0,%mm1
pfadd 124(%edx), %mm0
punpckldq %mm1, %mm0
movq %mm0, 116(%edx)
jnz .L01
movd (%ecx), %mm0
pfadd 4(%ecx), %mm0
movd %mm0, 1024(%esi)
movd (%ecx), %mm0
pfsub 4(%ecx), %mm0
pfmul 120(%ebx), %mm0
movd %mm0, (%esi)
movd %mm0, (%edi)
movd 12(%ecx), %mm0
pfsub 8(%ecx), %mm0
pfmul 120(%ebx), %mm0
movd %mm0, 512(%edi)
pfadd 12(%ecx), %mm0
pfadd 8(%ecx), %mm0
movd %mm0, 512(%esi)
movd 16(%ecx), %mm0
pfsub 20(%ecx), %mm0
pfmul 120(%ebx), %mm0
movq %mm0, %mm3
movd 28(%ecx), %mm0
pfsub 24(%ecx), %mm0
pfmul 120(%ebx), %mm0
movd %mm0, 768(%edi)
movq %mm0, %mm2
pfadd 24(%ecx), %mm0
pfadd 28(%ecx), %mm0
movq %mm0, %mm1
pfadd 16(%ecx), %mm0
pfadd 20(%ecx), %mm0
movd %mm0, 768(%esi)
pfadd %mm3, %mm1
movd %mm1, 256(%esi)
pfadd %mm3, %mm2
movd %mm2, 256(%edi)
movq 32(%edx), %mm0
movq 48(%edx), %mm1
pfadd 48(%edx), %mm0
pfadd 40(%edx), %mm1
movd %mm0, 896(%esi)
movd %mm1, 640(%esi)
psrlq $32, %mm0
psrlq $32, %mm1
movd %mm0, 128(%edi)
movd %mm1, 384(%edi)
movd 40(%edx), %mm0
pfadd 56(%edx), %mm0
movd %mm0, 384(%esi)
movd 56(%edx), %mm0
pfadd 36(%edx), %mm0
movd %mm0, 128(%esi)
movd 60(%edx), %mm0
movd %mm0, 896(%edi)
pfadd 44(%edx), %mm0
movd %mm0, 640(%edi)
movq 96(%edx), %mm0
movq 112(%edx), %mm2
movq 104(%edx), %mm4
pfadd 112(%edx), %mm0
pfadd 104(%edx), %mm2
pfadd 120(%edx), %mm4
movq %mm0, %mm1
movq %mm2, %mm3
movq %mm4, %mm5
pfadd 64(%edx), %mm0
pfadd 80(%edx), %mm2
pfadd 72(%edx), %mm4
movd %mm0, 960(%esi)
movd %mm2, 704(%esi)
movd %mm4, 448(%esi)
psrlq $32, %mm0
psrlq $32, %mm2
psrlq $32, %mm4
movd %mm0, 64(%edi)
movd %mm2, 320(%edi)
movd %mm4, 576(%edi)
pfadd 80(%edx), %mm1
pfadd 72(%edx), %mm3
pfadd 88(%edx), %mm5
movd %mm1, 832(%esi)
movd %mm3, 576(%esi)
movd %mm5, 320(%esi)
psrlq $32, %mm1
psrlq $32, %mm3
psrlq $32, %mm5
movd %mm1, 192(%edi)
movd %mm3, 448(%edi)
movd %mm5, 704(%edi)
movd 120(%edx), %mm0
pfadd 100(%edx), %mm0
movq %mm0, %mm1
pfadd 88(%edx), %mm0
movd %mm0, 192(%esi)
pfadd 68(%edx), %mm1
movd %mm1, 64(%esi)
movd 124(%edx), %mm0
movd %mm0, 960(%edi)
pfadd 92(%edx), %mm0
movd %mm0, 832(%edi)
jmp .L_bye
.L01:
movq (%ecx), %mm0
movq %mm0, %mm1
pxor %mm7, %mm1
pfacc %mm1, %mm0
pfmul %mm6, %mm0
pf2iw %mm0, %mm0
movd %mm0, %eax
movw %ax, 512(%esi)
psrlq $32, %mm0
movd %mm0, %eax
movw %ax, (%esi)
movd 12(%ecx), %mm0
pfsub 8(%ecx), %mm0
pfmul 120(%ebx), %mm0
pf2iw %mm0, %mm7
movd %mm7, %eax
movw %ax, 256(%edi)
pfadd 12(%ecx), %mm0
pfadd 8(%ecx), %mm0
pf2iw %mm0, %mm0
movd %mm0, %eax
movw %ax, 256(%esi)
movd 16(%ecx), %mm3
pfsub 20(%ecx), %mm3
pfmul 120(%ebx), %mm3
movq %mm3, %mm2
movd 28(%ecx), %mm2
pfsub 24(%ecx), %mm2
pfmul 120(%ebx), %mm2
movq %mm2, %mm1
pf2iw %mm2, %mm7
movd %mm7, %eax
movw %ax, 384(%edi)
pfadd 24(%ecx), %mm1
pfadd 28(%ecx), %mm1
movq %mm1, %mm0
pfadd 16(%ecx), %mm0
pfadd 20(%ecx), %mm0
pf2iw %mm0, %mm0
movd %mm0, %eax
movw %ax, 384(%esi)
pfadd %mm3, %mm1
pf2iw %mm1, %mm1
movd %mm1, %eax
movw %ax, 128(%esi)
pfadd %mm3, %mm2
pf2iw %mm2, %mm2
movd %mm2, %eax
movw %ax, 128(%edi)
movq 32(%edx), %mm0
movq 48(%edx), %mm1
pfadd 48(%edx), %mm0
pfadd 40(%edx), %mm1
pf2iw %mm0, %mm0
pf2iw %mm1, %mm1
movd %mm0, %eax
movd %mm1, %ecx
movw %ax, 448(%esi)
movw %cx, 320(%esi)
psrlq $32, %mm0
psrlq $32, %mm1
movd %mm0, %eax
movd %mm1, %ecx
movw %ax, 64(%edi)
movw %cx, 192(%edi)
movd 40(%edx), %mm3
movd 56(%edx), %mm4
movd 60(%edx), %mm0
movd 44(%edx), %mm2
movd 120(%edx), %mm5
punpckldq %mm4, %mm3
punpckldq 124(%edx), %mm0
pfadd 100(%edx), %mm5
punpckldq 36(%edx), %mm4
punpckldq 92(%edx), %mm2
movq %mm5, %mm6
pfadd %mm4, %mm3
pf2iw %mm0, %mm1
pf2iw %mm3, %mm3
pfadd 88(%edx), %mm5
movd %mm1, %eax
movd %mm3, %ecx
movw %ax, 448(%edi)
movw %cx, 192(%esi)
pf2iw %mm5, %mm5
psrlq $32, %mm1
psrlq $32, %mm3
movd %mm5, %ebx
movd %mm1, %eax
movd %mm3, %ecx
movw %bx, 96(%esi)
movw %ax, 480(%edi)
movw %cx, 64(%esi)
pfadd %mm2, %mm0
pf2iw %mm0, %mm0
movd %mm0, %eax
pfadd 68(%edx), %mm6
movw %ax, 320(%edi)
psrlq $32, %mm0
pf2iw %mm6, %mm6
movd %mm0, %eax
movd %mm6, %ebx
movw %ax, 416(%edi)
movw %bx, 32(%esi)
movq 96(%edx), %mm0
movq 112(%edx), %mm2
movq 104(%edx), %mm4
pfadd %mm2, %mm0
pfadd %mm4, %mm2
pfadd 120(%edx), %mm4
movq %mm0, %mm1
movq %mm2, %mm3
movq %mm4, %mm5
pfadd 64(%edx), %mm0
pfadd 80(%edx), %mm2
pfadd 72(%edx), %mm4
pf2iw %mm0, %mm0
pf2iw %mm2, %mm2
pf2iw %mm4, %mm4
movd %mm0, %eax
movd %mm2, %ecx
movd %mm4, %ebx
movw %ax, 480(%esi)
movw %cx, 352(%esi)
movw %bx, 224(%esi)
psrlq $32, %mm0
psrlq $32, %mm2
psrlq $32, %mm4
movd %mm0, %eax
movd %mm2, %ecx
movd %mm4, %ebx
movw %ax, 32(%edi)
movw %cx, 160(%edi)
movw %bx, 288(%edi)
pfadd 80(%edx), %mm1
pfadd 72(%edx), %mm3
pfadd 88(%edx), %mm5
pf2iw %mm1, %mm1
pf2iw %mm3, %mm3
pf2iw %mm5, %mm5
movd %mm1, %eax
movd %mm3, %ecx
movd %mm5, %ebx
movw %ax, 416(%esi)
movw %cx, 288(%esi)
movw %bx, 160(%esi)
psrlq $32, %mm1
psrlq $32, %mm3
psrlq $32, %mm5
movd %mm1, %eax
movd %mm3, %ecx
movd %mm5, %ebx
movw %ax, 96(%edi)
movw %cx, 224(%edi)
movw %bx, 352(%edi)
movsw
.L_bye:
femms
/* NO_APP */
addl $260, %esp
popl %ebx
popl %esi
popl %edi
leave
ret
/* .size ASM_NAME(dct64_3dnowext), .-ASM_NAME(dct64_3dnowext) */
#if defined(PIC) && defined(__APPLE__)
.section __IMPORT,__pointers,non_lazy_symbol_pointers
L_costab_mmxsse:
.indirect_symbol ASM_NAME(costab_mmxsse)
.long 0
#endif
NONEXEC_STACK

View File

@ -0,0 +1,315 @@
/*
dct64_altivec.c: Discrete Cosine Tansform (DCT) for Altivec
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
altivec optimization by tmkk
*/
/*
* 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 "mpg123lib_intern.h"
#ifndef __APPLE__
#include <altivec.h>
#endif
void dct64_altivec(real *out0,real *out1,real *samples)
{
ALIGNED(16) real bufs[32];
{
register real *b1,*costab;
vector unsigned char vinvert,vperm1,vperm2,vperm3,vperm4;
vector float v1,v2,v3,v4,v5,v6,v7,v8;
vector float vbs1,vbs2,vbs3,vbs4,vbs5,vbs6,vbs7,vbs8;
vector float vbs9,vbs10,vbs11,vbs12,vbs13,vbs14,vbs15,vbs16;
vector float vzero;
b1 = samples;
costab = pnts[0];
vzero = vec_xor(vzero,vzero);
#ifdef __APPLE__
vinvert = (vector unsigned char)(12,13,14,15,8,9,10,11,4,5,6,7,0,1,2,3);
#else
vinvert = (vector unsigned char){12,13,14,15,8,9,10,11,4,5,6,7,0,1,2,3};
#endif
vperm1 = vec_lvsl(0,b1);
vperm2 = vec_perm(vperm1,vperm1,vinvert);
v1 = vec_ld(0,b1);
v2 = vec_ld(16,b1);
v3 = vec_ld(112,b1);
v4 = vec_ld(127,b1);
v5 = vec_perm(v1,v2,vperm1); /* b1[0,1,2,3] */
v6 = vec_perm(v3,v4,vperm2); /* b1[31,30,29,28] */
vbs1 = vec_add(v5,v6);
vbs8 = vec_sub(v5,v6);
v1 = vec_ld(32,b1);
v4 = vec_ld(96,b1);
v5 = vec_perm(v2,v1,vperm1); /* b1[4,5,6,7] */
v6 = vec_perm(v4,v3,vperm2); /* b1[27,26,25,24] */
vbs2 = vec_add(v5,v6);
vbs7 = vec_sub(v5,v6);
v2 = vec_ld(48,b1);
v3 = vec_ld(80,b1);
v5 = vec_perm(v1,v2,vperm1); /* b1[8,9,10,11] */
v6 = vec_perm(v3,v4,vperm2); /* b1[23,22,21,20] */
vbs3 = vec_add(v5,v6);
vbs6 = vec_sub(v5,v6);
v1 = vec_ld(64,b1);
v5 = vec_perm(v2,v1,vperm1); /* b1[12,13,14,15] */
v6 = vec_perm(v1,v3,vperm2); /* b1[19,18,17,16] */
vbs4 = vec_add(v5,v6);
vbs5 = vec_sub(v5,v6);
v1 = vec_ld(0,costab);
vbs8 = vec_madd(vbs8,v1,vzero);
v2 = vec_ld(16,costab);
vbs7 = vec_madd(vbs7,v2,vzero);
v3 = vec_ld(32,costab);
vbs6 = vec_madd(vbs6,v3,vzero);
v4 = vec_ld(48,costab);
vbs5 = vec_madd(vbs5,v4,vzero);
vbs6 = vec_perm(vbs6,vbs6,vinvert);
vbs5 = vec_perm(vbs5,vbs5,vinvert);
costab = pnts[1];
v1 = vec_perm(vbs4,vbs4,vinvert);
vbs9 = vec_add(vbs1,v1);
v3 = vec_sub(vbs1,v1);
v5 = vec_ld(0,costab);
v2 = vec_perm(vbs3,vbs3,vinvert);
vbs10 = vec_add(vbs2,v2);
v4 = vec_sub(vbs2,v2);
v6 = vec_ld(16,costab);
vbs12 = vec_madd(v3,v5,vzero);
vbs11 = vec_madd(v4,v6,vzero);
v7 = vec_sub(vbs7,vbs6);
v8 = vec_sub(vbs8,vbs5);
vbs13 = vec_add(vbs5,vbs8);
vbs14 = vec_add(vbs6,vbs7);
vbs15 = vec_madd(v7,v6,vzero);
vbs16 = vec_madd(v8,v5,vzero);
costab = pnts[2];
v1 = vec_perm(vbs10,vbs10,vinvert);
v5 = vec_perm(vbs14,vbs14,vinvert);
vbs1 = vec_add(v1,vbs9);
vbs5 = vec_add(v5,vbs13);
v2 = vec_sub(vbs9,v1);
v6 = vec_sub(vbs13,v5);
v3 = vec_ld(0,costab);
vbs11 = vec_perm(vbs11,vbs11,vinvert);
vbs15 = vec_perm(vbs15,vbs15,vinvert);
vbs3 = vec_add(vbs11,vbs12);
vbs7 = vec_add(vbs15,vbs16);
v4 = vec_sub(vbs12,vbs11);
v7 = vec_sub(vbs16,vbs15);
vbs2 = vec_madd(v2,v3,vzero);
vbs4 = vec_madd(v4,v3,vzero);
vbs6 = vec_madd(v6,v3,vzero);
vbs8 = vec_madd(v7,v3,vzero);
vbs2 = vec_perm(vbs2,vbs2,vinvert);
vbs4 = vec_perm(vbs4,vbs4,vinvert);
vbs6 = vec_perm(vbs6,vbs6,vinvert);
vbs8 = vec_perm(vbs8,vbs8,vinvert);
costab = pnts[3];
#ifdef __APPLE__
vperm1 = (vector unsigned char)(0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23);
vperm2 = (vector unsigned char)(12,13,14,15,8,9,10,11,28,29,30,31,24,25,26,27);
vperm3 = (vector unsigned char)(0,1,2,3,4,5,6,7,20,21,22,23,16,17,18,19);
#else
vperm1 = (vector unsigned char){0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23};
vperm2 = (vector unsigned char){12,13,14,15,8,9,10,11,28,29,30,31,24,25,26,27};
vperm3 = (vector unsigned char){0,1,2,3,4,5,6,7,20,21,22,23,16,17,18,19};
#endif
vperm4 = vec_add(vperm3,vec_splat_u8(8));
v1 = vec_ld(0,costab);
v2 = vec_splat(v1,0);
v3 = vec_splat(v1,1);
v1 = vec_mergeh(v2,v3);
v2 = vec_perm(vbs1,vbs3,vperm1);
v3 = vec_perm(vbs2,vbs4,vperm1);
v4 = vec_perm(vbs1,vbs3,vperm2);
v5 = vec_perm(vbs2,vbs4,vperm2);
v6 = vec_sub(v2,v4);
v7 = vec_sub(v3,v5);
v2 = vec_add(v2,v4);
v3 = vec_add(v3,v5);
v4 = vec_madd(v6,v1,vzero);
v5 = vec_nmsub(v7,v1,vzero);
vbs9 = vec_perm(v2,v4,vperm3);
vbs11 = vec_perm(v2,v4,vperm4);
vbs10 = vec_perm(v3,v5,vperm3);
vbs12 = vec_perm(v3,v5,vperm4);
v2 = vec_perm(vbs5,vbs7,vperm1);
v3 = vec_perm(vbs6,vbs8,vperm1);
v4 = vec_perm(vbs5,vbs7,vperm2);
v5 = vec_perm(vbs6,vbs8,vperm2);
v6 = vec_sub(v2,v4);
v7 = vec_sub(v3,v5);
v2 = vec_add(v2,v4);
v3 = vec_add(v3,v5);
v4 = vec_madd(v6,v1,vzero);
v5 = vec_nmsub(v7,v1,vzero);
vbs13 = vec_perm(v2,v4,vperm3);
vbs15 = vec_perm(v2,v4,vperm4);
vbs14 = vec_perm(v3,v5,vperm3);
vbs16 = vec_perm(v3,v5,vperm4);
costab = pnts[4];
v1 = vec_lde(0,costab);
#ifdef __APPLE__
v2 = (vector float)(1.0f,-1.0f,1.0f,-1.0f);
#else
v2 = (vector float){1.0f,-1.0f,1.0f,-1.0f};
#endif
v3 = vec_splat(v1,0);
v1 = vec_madd(v2,v3,vzero);
v2 = vec_mergeh(vbs9,vbs10);
v3 = vec_mergel(vbs9,vbs10);
v4 = vec_mergeh(vbs11,vbs12);
v5 = vec_mergel(vbs11,vbs12);
v6 = vec_mergeh(v2,v3);
v7 = vec_mergel(v2,v3);
v2 = vec_mergeh(v4,v5);
v3 = vec_mergel(v4,v5);
v4 = vec_sub(v6,v7);
v5 = vec_sub(v2,v3);
v6 = vec_add(v6,v7);
v7 = vec_add(v2,v3);
v2 = vec_madd(v4,v1,vzero);
v3 = vec_madd(v5,v1,vzero);
vbs1 = vec_mergeh(v6,v2);
vbs2 = vec_mergel(v6,v2);
vbs3 = vec_mergeh(v7,v3);
vbs4 = vec_mergel(v7,v3);
v2 = vec_mergeh(vbs13,vbs14);
v3 = vec_mergel(vbs13,vbs14);
v4 = vec_mergeh(vbs15,vbs16);
v5 = vec_mergel(vbs15,vbs16);
v6 = vec_mergeh(v2,v3);
v7 = vec_mergel(v2,v3);
v2 = vec_mergeh(v4,v5);
v3 = vec_mergel(v4,v5);
v4 = vec_sub(v6,v7);
v5 = vec_sub(v2,v3);
v6 = vec_add(v6,v7);
v7 = vec_add(v2,v3);
v2 = vec_madd(v4,v1,vzero);
v3 = vec_madd(v5,v1,vzero);
vbs5 = vec_mergeh(v6,v2);
vbs6 = vec_mergel(v6,v2);
vbs7 = vec_mergeh(v7,v3);
vbs8 = vec_mergel(v7,v3);
vec_st(vbs1,0,bufs);
vec_st(vbs2,16,bufs);
vec_st(vbs3,32,bufs);
vec_st(vbs4,48,bufs);
vec_st(vbs5,64,bufs);
vec_st(vbs6,80,bufs);
vec_st(vbs7,96,bufs);
vec_st(vbs8,112,bufs);
}
{
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];
}

View File

@ -0,0 +1,324 @@
/*
dct36_sse: AVX optimized dct64 for x86-64
copyright 1995-2013 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#define samples %rdx
#define costab %rcx
#define out0 %rdi
#define out1 %rsi
/*
void dct64_avx(short *out0, short *out1, real *samples);
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN32
costab_avx:
.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
.long 0
.text
ALIGN16
.globl ASM_NAME(dct64_avx)
ASM_NAME(dct64_avx):
#ifdef IS_MSABI
push %rbp
mov %rsp, %rbp
sub $112, %rsp
movaps %xmm6, (%rsp)
movaps %xmm7, 16(%rsp)
movaps %xmm8, 32(%rsp)
movaps %xmm9, 48(%rsp)
movaps %xmm10, 64(%rsp)
movaps %xmm11, 80(%rsp)
movaps %xmm12, 96(%rsp)
push %rdi
push %rsi
mov %rcx, %rdi
mov %rdx, %rsi
mov %r8, %rdx
#endif
leaq costab_avx(%rip), costab
vmovups (samples), %ymm0 # input[0,1,2,3,4,5,6,7]
vmovups 32(samples), %ymm1 # input[8,9,10,11,12,13,14,15]
vperm2f128 $0x23, 64(samples), %ymm2, %ymm2
vperm2f128 $0x23, 96(samples), %ymm3, %ymm3
vshufps $0x1b, %ymm2, %ymm2, %ymm2 # input[23,22,21,20,19,18,17,16]
vshufps $0x1b, %ymm3, %ymm3, %ymm3 # input[31,30,29,28,27,26,25,24]
vsubps %ymm2, %ymm1, %ymm6
vsubps %ymm3, %ymm0, %ymm7
vaddps %ymm0, %ymm3, %ymm4 # bufs[0,1,2,3,4,5,6,7]
vaddps %ymm1, %ymm2, %ymm5 # bufs[8,9,10,11,12,13,14,15]
vmulps (costab), %ymm7, %ymm7 # bufs[31,30,29,28,27,26,25,24] cos64[0,1,2,3,4,5,6,7]
vmulps 32(costab), %ymm6, %ymm6 # bufs[23,22,21,20,19,18,17,16] cos64[8,9,10,11,12,13,14,15]
vmovaps 64(costab), %ymm8 # cos32[0,1,2,3,4,5,6,7]
vshufps $0x1b, %ymm5, %ymm5, %ymm5
vshufps $0x1b, %ymm6, %ymm6, %ymm6
vperm2f128 $0x01, %ymm5, %ymm5, %ymm5 # bufs[15,14,13,12,11,10,9,8]
vperm2f128 $0x01, %ymm6, %ymm6, %ymm6 # bufs[16,17,18,19,20,21,22,23]
vsubps %ymm5, %ymm4, %ymm1
vsubps %ymm6, %ymm7, %ymm3
vaddps %ymm5, %ymm4, %ymm0 # bufs[32,33,34,35,36,37,38,39]
vaddps %ymm6, %ymm7, %ymm2 # bufs[48,49,50,51,52,53,54,55]
vmulps %ymm1, %ymm8, %ymm1 # bufs[47,46,45,44,43,42,41,40]
vmulps %ymm3, %ymm8, %ymm3 # bufs[63,62,61,60,59,58,57,56]
vmovaps 96(costab), %ymm8 # cos16[0,1,2,3]:cos8[0,1]:cos4[0]:-
vperm2f128 $0x00, %ymm8, %ymm8, %ymm9 # cos16[0,1,2,3,0,1,2,3]
vperm2f128 $0x20, %ymm1, %ymm0, %ymm4 # bufs[32,33,34,35,47,46,45,44]
vperm2f128 $0x31, %ymm1, %ymm0, %ymm5
vshufps $0x1b, %ymm5, %ymm5, %ymm5 # bufs[39,38,37,36,40,41,42,43]
vperm2f128 $0x20, %ymm3, %ymm2, %ymm6 # bufs[48,49,50,51,63,62,61,60]
vperm2f128 $0x31, %ymm3, %ymm2, %ymm7
vshufps $0x1b, %ymm7, %ymm7, %ymm7 # bufs[55,54,53,52,56,57,58,59]
vsubps %ymm5, %ymm4, %ymm1
vsubps %ymm7, %ymm6, %ymm3
vaddps %ymm5, %ymm4, %ymm0 # bufs[0,1,2,3,8,9,10,11]
vaddps %ymm7, %ymm6, %ymm2 # bufs[16,17,18,19,24,25,26,27]
vmulps %ymm1, %ymm9, %ymm1 # bufs[7,6,5,4,15,14,13,12]
vmulps %ymm3, %ymm9, %ymm3 # bufs[23,22,21,20,31,30,29,28]
vperm2f128 $0x11, %ymm8, %ymm8, %ymm8 # cos8[0,1]:cos4[0]:-:cos8[0,1]:cos4[0]:-
vmovddup %ymm8, %ymm9 # cos8[0,1,0,1,0,1,0,1]
vunpcklps %ymm1, %ymm0, %ymm4 # bufs[0,7,1,6,8,15,9,14]
vunpckhps %ymm1, %ymm0, %ymm5 # bufs[2,5,3,4,10,13,11,12]
vunpcklps %ymm3, %ymm2, %ymm6 # bufs[16,23,17,22,24,31,25,30]
vunpckhps %ymm3, %ymm2, %ymm7 # bufs[18,21,19,20,26,29,27,28]
vshufps $0xd8, %ymm4, %ymm4, %ymm4 # bufs[0,1,7,6,8,9,15,14]
vshufps $0x72, %ymm5, %ymm5, %ymm5 # bufs[3,2,4,5,11,10,12,13]
vshufps $0xd8, %ymm6, %ymm6, %ymm6 # bufs[16,17,23,22,24,25,31,30]
vshufps $0x72, %ymm7, %ymm7, %ymm7 # bufs[19,18,20,21,27,26,28,29]
vsubps %ymm5, %ymm4, %ymm1
vsubps %ymm7, %ymm6, %ymm3
vaddps %ymm5, %ymm4, %ymm0 # bufs[32,33,36,37,40,41,44,45]
vaddps %ymm7, %ymm6, %ymm2 # bufs[48,49,52,53,56,57,60,61]
vmulps %ymm1, %ymm9, %ymm1 # bufs[35,34,39,38,43,42,47,46]
vmulps %ymm3, %ymm9, %ymm3 # bufs[51,50,55,54,59,58,63,62]
vpermilps $0xaa, %ymm8, %ymm8 # cos4[0,0,0,0,0,0,0,0]
vshufps $0xd8, %ymm0, %ymm0, %ymm0 # bufs[32,36,33,37,40,44,41,45]
vshufps $0xd8, %ymm1, %ymm1, %ymm1 # bufs[35,39,34,38,43,47,42,46]
vshufps $0xd8, %ymm2, %ymm2, %ymm2 # bufs[48,52,49,53,56,60,57,61]
vshufps $0xd8, %ymm3, %ymm3, %ymm3 # bufs[51,55,50,54,59,63,58,62]
vunpcklps %ymm1, %ymm0, %ymm4 # bufs[32,35,36,39,40,43,44,47]
vunpckhps %ymm1, %ymm0, %ymm5 # bufs[33,34,37,38,41,42,45,46]
vunpcklps %ymm3, %ymm2, %ymm6 # bufs[48,51,52,55,56,59,60,63]
vunpckhps %ymm3, %ymm2, %ymm7 # bufs[49,50,53,54,57,58,61,62]
vsubps %ymm5, %ymm4, %ymm1
vsubps %ymm7, %ymm6, %ymm3
vaddps %ymm5, %ymm4, %ymm0 # bufs[0,2,4,6,8,10,12,14]
vaddps %ymm7, %ymm6, %ymm2 # bufs[16,18,20,22,24,26,28,30]
vmulps %ymm1, %ymm8, %ymm1 # bufs[1,3,5,7,9,11,13,15]
vmulps %ymm3, %ymm8, %ymm3 # bufs[17,19,21,23,25,27,29,31]
vxorps %ymm8, %ymm8, %ymm8
vblendps $0xaa, %ymm1, %ymm8, %ymm5
vblendps $0xaa, %ymm3, %ymm8, %ymm6
vaddps %ymm5, %ymm0, %ymm0
vaddps %ymm6, %ymm2, %ymm2
vunpcklps %ymm1, %ymm0, %ymm4 # bufs[0,1,2,3,8,9,10,11]
vunpckhps %ymm1, %ymm0, %ymm5 # bufs[4,5,6,7,12,13,14,15]
vunpcklps %ymm3, %ymm2, %ymm6 # bufs[16,17,18,19,24,25,26,27]
vunpckhps %ymm3, %ymm2, %ymm7 # bufs[20,21,22,23,28,29,30,31]
vextractf128 $0x1, %ymm4, %xmm0 # bufs[8,9,10,11]
vextractf128 $0x1, %ymm5, %xmm1 # bufs[12,13,14,15]
vextractf128 $0x1, %ymm6, %xmm2 # bufs[24,25,26,27]
vextractf128 $0x1, %ymm7, %xmm3 # bufs[28,29,30,31]
vshufps $0x1e, %xmm5, %xmm5, %xmm9 # bufs[6,7,5,4]
vshufps $0x1e, %xmm1, %xmm1, %xmm10 # bufs[14,15,13,12]
vshufps $0x1e, %xmm7, %xmm7, %xmm11 # bufs[22,23,21,20]
vshufps $0x1e, %xmm3, %xmm3, %xmm12 # bufs[30,31,29,28]
vblendps $0x7, %xmm9, %xmm8, %xmm9 # bufs[6,7,5,-]
vblendps $0x7, %xmm10, %xmm8, %xmm10 # bufs[14,15,13,-]
vblendps $0x7, %xmm11, %xmm8, %xmm11 # bufs[22,23,21,-]
vblendps $0x7, %xmm12, %xmm8, %xmm12 # bufs[30,31,29,-]
vaddps %xmm5, %xmm9, %xmm5
vaddps %xmm1, %xmm10, %xmm1
vaddps %xmm7, %xmm11, %xmm7
vaddps %xmm3, %xmm12, %xmm3
prefetcht0 512(out0)
vshufps $0x1e, %xmm0, %xmm0, %xmm9 # bufs[10,11,9,8]
vshufps $0x1e, %xmm2, %xmm2, %xmm10 # bufs[26,27,25,24]
vaddps %xmm1, %xmm0, %xmm0
vaddps %xmm3, %xmm2, %xmm2
vblendps $0x7, %xmm9, %xmm8, %xmm9 # bufs[10,11,9,-]
vblendps $0x7, %xmm10, %xmm8, %xmm10 # bufs[26,27,25,-]
vaddps %xmm1, %xmm9, %xmm1
vaddps %xmm3, %xmm10, %xmm3
vzeroupper
prefetcht0 512(out1)
cvtps2dq %xmm4, %xmm4
cvtps2dq %xmm0, %xmm0
cvtps2dq %xmm5, %xmm5
cvtps2dq %xmm1, %xmm1
packssdw %xmm5, %xmm4
packssdw %xmm1, %xmm0
movq %xmm4, %rcx
pshufd $0x4e, %xmm4, %xmm5
movq %xmm0, %rdx
pshufd $0x4e, %xmm0, %xmm1
movq %xmm5, %r8
movq %xmm1, %r9
addq $512, out0
movq $-64, %rax
movw %cx, (out0)
movw %dx, (out0,%rax,1)
movw %r8w, (out0,%rax,2)
movw %r9w, -64(out0,%rax,2)
leaq (out0,%rax,4), out0
shr $16, %rcx
shr $16, %rdx
shr $16, %r8
shr $16, %r9
movw %cx, (out0,%rax,4)
negq %rax
movw %cx, (out1)
movw %dx, (out1,%rax,1)
movw %r8w, (out1,%rax,2)
movw %r9w, 64(out1,%rax,2)
leaq (out1,%rax,4), out1
shr $16, %rcx
shr $16, %rdx
shr $16, %r8
shr $16, %r9
negq %rax
movw %cx, (out0)
movw %dx, (out0,%rax,1)
movw %r8w, (out0,%rax,2)
movw %r9w, -64(out0,%rax,2)
shr $16, %rcx
shr $16, %rdx
shr $16, %r8
shr $16, %r9
negq %rax
movw %cx, (out1)
movw %dx, (out1,%rax,1)
movw %r8w, (out1,%rax,2)
movw %r9w, 64(out1,%rax,2)
leaq -32(out0,%rax,4), out0
negq %rax
leaq 32(out1,%rax,4), out1
vshufps $0x1e, %xmm6, %xmm6, %xmm0
vblendps $0x7, %xmm0, %xmm8, %xmm0
addps %xmm2, %xmm6
addps %xmm7, %xmm2
addps %xmm3, %xmm7
addps %xmm0, %xmm3
cvtps2dq %xmm6, %xmm6
cvtps2dq %xmm2, %xmm2
cvtps2dq %xmm7, %xmm7
cvtps2dq %xmm3, %xmm3
packssdw %xmm7, %xmm6
packssdw %xmm3, %xmm2
movq %xmm6, %rcx
pshufd $0x4e, %xmm6, %xmm7
movq %xmm2, %rdx
pshufd $0x4e, %xmm2, %xmm3
movq %xmm7, %r8
movq %xmm3, %r9
movw %cx, (out0)
movw %dx, (out0,%rax,1)
movw %r8w, (out0,%rax,2)
movw %r9w, -64(out0,%rax,2)
leaq (out0,%rax,4), out0
shr $16, %rcx
shr $16, %rdx
shr $16, %r8
shr $16, %r9
negq %rax
movw %cx, (out1)
movw %dx, (out1,%rax,1)
movw %r8w, (out1,%rax,2)
movw %r9w, 64(out1,%rax,2)
leaq (out1,%rax,4), out1
shr $16, %rcx
shr $16, %rdx
shr $16, %r8
shr $16, %r9
negq %rax
movw %cx, (out0)
movw %dx, (out0,%rax,1)
movw %r8w, (out0,%rax,2)
movw %r9w, -64(out0,%rax,2)
shr $16, %rcx
shr $16, %rdx
shr $16, %r8
shr $16, %r9
negq %rax
movw %cx, (out1)
movw %dx, (out1,%rax,1)
movw %r8w, (out1,%rax,2)
movw %r9w, 64(out1,%rax,2)
#ifdef IS_MSABI
pop %rsi
pop %rdi
movaps (%rsp), %xmm6
movaps 16(%rsp), %xmm7
movaps 32(%rsp), %xmm8
movaps 48(%rsp), %xmm9
movaps 64(%rsp), %xmm10
movaps 80(%rsp), %xmm11
movaps 96(%rsp), %xmm12
mov %rbp, %rsp
pop %rbp
#endif
ret
NONEXEC_STACK

View File

@ -0,0 +1,294 @@
/*
dct64_x86_64_float: SSE optimized dct64 for x86-64 (float output version)
copyright 1995-2013 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#define samples %rdx
#define costab %rcx
#define out0 %rdi
#define out1 %rsi
/*
void dct64_real_avx(real *out0, real *out1, real *samples);
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN32
costab_avx:
.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
.long 0
.text
ALIGN16
.globl ASM_NAME(dct64_real_avx)
ASM_NAME(dct64_real_avx):
#ifdef IS_MSABI
push %rbp
mov %rsp, %rbp
sub $112, %rsp
movaps %xmm6, (%rsp)
movaps %xmm7, 16(%rsp)
movaps %xmm8, 32(%rsp)
movaps %xmm9, 48(%rsp)
movaps %xmm10, 64(%rsp)
movaps %xmm11, 80(%rsp)
movaps %xmm12, 96(%rsp)
push %rdi
push %rsi
mov %rcx, %rdi
mov %rdx, %rsi
mov %r8, %rdx
#endif
leaq costab_avx(%rip), costab
vmovups (samples), %ymm0 # input[0,1,2,3,4,5,6,7]
vmovups 32(samples), %ymm1 # input[8,9,10,11,12,13,14,15]
vperm2f128 $0x23, 64(samples), %ymm2, %ymm2
vperm2f128 $0x23, 96(samples), %ymm3, %ymm3
vshufps $0x1b, %ymm2, %ymm2, %ymm2 # input[23,22,21,20,19,18,17,16]
vshufps $0x1b, %ymm3, %ymm3, %ymm3 # input[31,30,29,28,27,26,25,24]
vsubps %ymm2, %ymm1, %ymm6
vsubps %ymm3, %ymm0, %ymm7
vaddps %ymm0, %ymm3, %ymm4 # bufs[0,1,2,3,4,5,6,7]
vaddps %ymm1, %ymm2, %ymm5 # bufs[8,9,10,11,12,13,14,15]
vmulps (costab), %ymm7, %ymm7 # bufs[31,30,29,28,27,26,25,24] cos64[0,1,2,3,4,5,6,7]
vmulps 32(costab), %ymm6, %ymm6 # bufs[23,22,21,20,19,18,17,16] cos64[8,9,10,11,12,13,14,15]
vmovaps 64(costab), %ymm8 # cos32[0,1,2,3,4,5,6,7]
vshufps $0x1b, %ymm5, %ymm5, %ymm5
vshufps $0x1b, %ymm6, %ymm6, %ymm6
vperm2f128 $0x01, %ymm5, %ymm5, %ymm5 # bufs[15,14,13,12,11,10,9,8]
vperm2f128 $0x01, %ymm6, %ymm6, %ymm6 # bufs[16,17,18,19,20,21,22,23]
vsubps %ymm5, %ymm4, %ymm1
vsubps %ymm6, %ymm7, %ymm3
vaddps %ymm5, %ymm4, %ymm0 # bufs[32,33,34,35,36,37,38,39]
vaddps %ymm6, %ymm7, %ymm2 # bufs[48,49,50,51,52,53,54,55]
vmulps %ymm1, %ymm8, %ymm1 # bufs[47,46,45,44,43,42,41,40]
vmulps %ymm3, %ymm8, %ymm3 # bufs[63,62,61,60,59,58,57,56]
vmovaps 96(costab), %ymm8 # cos16[0,1,2,3]:cos8[0,1]:cos4[0]:-
vperm2f128 $0x00, %ymm8, %ymm8, %ymm9 # cos16[0,1,2,3,0,1,2,3]
vperm2f128 $0x20, %ymm1, %ymm0, %ymm4 # bufs[32,33,34,35,47,46,45,44]
vperm2f128 $0x31, %ymm1, %ymm0, %ymm5
vshufps $0x1b, %ymm5, %ymm5, %ymm5 # bufs[39,38,37,36,40,41,42,43]
vperm2f128 $0x20, %ymm3, %ymm2, %ymm6 # bufs[48,49,50,51,63,62,61,60]
vperm2f128 $0x31, %ymm3, %ymm2, %ymm7
vshufps $0x1b, %ymm7, %ymm7, %ymm7 # bufs[55,54,53,52,56,57,58,59]
vsubps %ymm5, %ymm4, %ymm1
vsubps %ymm7, %ymm6, %ymm3
vaddps %ymm5, %ymm4, %ymm0 # bufs[0,1,2,3,8,9,10,11]
vaddps %ymm7, %ymm6, %ymm2 # bufs[16,17,18,19,24,25,26,27]
vmulps %ymm1, %ymm9, %ymm1 # bufs[7,6,5,4,15,14,13,12]
vmulps %ymm3, %ymm9, %ymm3 # bufs[23,22,21,20,31,30,29,28]
vperm2f128 $0x11, %ymm8, %ymm8, %ymm8 # cos8[0,1]:cos4[0]:-:cos8[0,1]:cos4[0]:-
vmovddup %ymm8, %ymm9 # cos8[0,1,0,1,0,1,0,1]
vunpcklps %ymm1, %ymm0, %ymm4 # bufs[0,7,1,6,8,15,9,14]
vunpckhps %ymm1, %ymm0, %ymm5 # bufs[2,5,3,4,10,13,11,12]
vunpcklps %ymm3, %ymm2, %ymm6 # bufs[16,23,17,22,24,31,25,30]
vunpckhps %ymm3, %ymm2, %ymm7 # bufs[18,21,19,20,26,29,27,28]
vshufps $0xd8, %ymm4, %ymm4, %ymm4 # bufs[0,1,7,6,8,9,15,14]
vshufps $0x72, %ymm5, %ymm5, %ymm5 # bufs[3,2,4,5,11,10,12,13]
vshufps $0xd8, %ymm6, %ymm6, %ymm6 # bufs[16,17,23,22,24,25,31,30]
vshufps $0x72, %ymm7, %ymm7, %ymm7 # bufs[19,18,20,21,27,26,28,29]
vsubps %ymm5, %ymm4, %ymm1
vsubps %ymm7, %ymm6, %ymm3
vaddps %ymm5, %ymm4, %ymm0 # bufs[32,33,36,37,40,41,44,45]
vaddps %ymm7, %ymm6, %ymm2 # bufs[48,49,52,53,56,57,60,61]
vmulps %ymm1, %ymm9, %ymm1 # bufs[35,34,39,38,43,42,47,46]
vmulps %ymm3, %ymm9, %ymm3 # bufs[51,50,55,54,59,58,63,62]
vpermilps $0xaa, %ymm8, %ymm8 # cos4[0,0,0,0,0,0,0,0]
vshufps $0xd8, %ymm0, %ymm0, %ymm0 # bufs[32,36,33,37,40,44,41,45]
vshufps $0xd8, %ymm1, %ymm1, %ymm1 # bufs[35,39,34,38,43,47,42,46]
vshufps $0xd8, %ymm2, %ymm2, %ymm2 # bufs[48,52,49,53,56,60,57,61]
vshufps $0xd8, %ymm3, %ymm3, %ymm3 # bufs[51,55,50,54,59,63,58,62]
vunpcklps %ymm1, %ymm0, %ymm4 # bufs[32,35,36,39,40,43,44,47]
vunpckhps %ymm1, %ymm0, %ymm5 # bufs[33,34,37,38,41,42,45,46]
vunpcklps %ymm3, %ymm2, %ymm6 # bufs[48,51,52,55,56,59,60,63]
vunpckhps %ymm3, %ymm2, %ymm7 # bufs[49,50,53,54,57,58,61,62]
vsubps %ymm5, %ymm4, %ymm1
vsubps %ymm7, %ymm6, %ymm3
vaddps %ymm5, %ymm4, %ymm0 # bufs[0,2,4,6,8,10,12,14]
vaddps %ymm7, %ymm6, %ymm2 # bufs[16,18,20,22,24,26,28,30]
vmulps %ymm1, %ymm8, %ymm1 # bufs[1,3,5,7,9,11,13,15]
vmulps %ymm3, %ymm8, %ymm3 # bufs[17,19,21,23,25,27,29,31]
vxorps %ymm8, %ymm8, %ymm8
vblendps $0xaa, %ymm1, %ymm8, %ymm5
vblendps $0xaa, %ymm3, %ymm8, %ymm6
vaddps %ymm5, %ymm0, %ymm0
vaddps %ymm6, %ymm2, %ymm2
vunpcklps %ymm1, %ymm0, %ymm4 # bufs[0,1,2,3,8,9,10,11]
vunpckhps %ymm1, %ymm0, %ymm5 # bufs[4,5,6,7,12,13,14,15]
vunpcklps %ymm3, %ymm2, %ymm6 # bufs[16,17,18,19,24,25,26,27]
vunpckhps %ymm3, %ymm2, %ymm7 # bufs[20,21,22,23,28,29,30,31]
vextractf128 $0x1, %ymm4, %xmm0 # bufs[8,9,10,11]
vextractf128 $0x1, %ymm5, %xmm1 # bufs[12,13,14,15]
vextractf128 $0x1, %ymm6, %xmm2 # bufs[24,25,26,27]
vextractf128 $0x1, %ymm7, %xmm3 # bufs[28,29,30,31]
vshufps $0x1e, %xmm5, %xmm5, %xmm9 # bufs[6,7,5,4]
vshufps $0x1e, %xmm1, %xmm1, %xmm10 # bufs[14,15,13,12]
vshufps $0x1e, %xmm7, %xmm7, %xmm11 # bufs[22,23,21,20]
vshufps $0x1e, %xmm3, %xmm3, %xmm12 # bufs[30,31,29,28]
vblendps $0x7, %xmm9, %xmm8, %xmm9 # bufs[6,7,5,-]
vblendps $0x7, %xmm10, %xmm8, %xmm10 # bufs[14,15,13,-]
vblendps $0x7, %xmm11, %xmm8, %xmm11 # bufs[22,23,21,-]
vblendps $0x7, %xmm12, %xmm8, %xmm12 # bufs[30,31,29,-]
vaddps %xmm5, %xmm9, %xmm5
vaddps %xmm1, %xmm10, %xmm1
vaddps %xmm7, %xmm11, %xmm7
vaddps %xmm3, %xmm12, %xmm3
prefetcht0 1024(out0)
vshufps $0x1e, %xmm0, %xmm0, %xmm9 # bufs[10,11,9,8]
vshufps $0x1e, %xmm2, %xmm2, %xmm10 # bufs[26,27,25,24]
vaddps %xmm1, %xmm0, %xmm0
vaddps %xmm3, %xmm2, %xmm2
vblendps $0x7, %xmm9, %xmm8, %xmm9 # bufs[10,11,9,-]
vblendps $0x7, %xmm10, %xmm8, %xmm10 # bufs[26,27,25,-]
vaddps %xmm1, %xmm9, %xmm1
vaddps %xmm3, %xmm10, %xmm3
vzeroupper
prefetcht0 1024(out1)
addq $1024, out0
movq $-128, %rax
movss %xmm4, (out0)
movss %xmm0, (out0,%rax,1)
movss %xmm5, (out0,%rax,2)
movss %xmm1, -128(out0,%rax,2)
leaq (out0,%rax,4), out0
movhlps %xmm4, %xmm9
movhlps %xmm0, %xmm10
movhlps %xmm5, %xmm11
movhlps %xmm1, %xmm12
vmovss %xmm9, (out0)
vmovss %xmm10, (out0,%rax,1)
vmovss %xmm11, (out0,%rax,2)
vmovss %xmm12, -128(out0,%rax,2)
leaq (out0,%rax,4), out0
negq %rax
shufps $0xb1, %xmm4, %xmm4
shufps $0xb1, %xmm0, %xmm0
shufps $0xb1, %xmm5, %xmm5
shufps $0xb1, %xmm1, %xmm1
movss %xmm4, (out0)
movss %xmm4, (out1)
leaq (out1,%rax,1), out1
movss %xmm0, (out1)
movss %xmm5, (out1,%rax,1)
movss %xmm1, (out1,%rax,2)
leaq (out1,%rax,4), out1
movhlps %xmm4, %xmm4
movhlps %xmm0, %xmm0
movhlps %xmm5, %xmm5
movhlps %xmm1, %xmm1
movss %xmm4, -128(out1)
movss %xmm0, (out1)
movss %xmm5, (out1,%rax,1)
movss %xmm1, (out1,%rax,2)
leaq -64(out0,%rax,8), out0
negq %rax
vshufps $0x1e, %xmm6, %xmm6, %xmm0
vblendps $0x7, %xmm0, %xmm8, %xmm0
addps %xmm2, %xmm6
addps %xmm7, %xmm2
addps %xmm3, %xmm7
addps %xmm0, %xmm3
movss %xmm6, (out0)
movss %xmm2, (out0,%rax,1)
movss %xmm7, (out0,%rax,2)
movss %xmm3, -128(out0,%rax,2)
leaq (out0,%rax,4), out0
movhlps %xmm6, %xmm0
movhlps %xmm2, %xmm1
movhlps %xmm7, %xmm4
movhlps %xmm3, %xmm5
movss %xmm0, (out0)
movss %xmm1, (out0,%rax,1)
movss %xmm4, (out0,%rax,2)
movss %xmm5, -128(out0,%rax,2)
leaq 64(out1,%rax,4), out1
negq %rax
shufps $0xb1, %xmm6, %xmm6
shufps $0xb1, %xmm2, %xmm2
shufps $0xb1, %xmm7, %xmm7
shufps $0xb1, %xmm3, %xmm3
movss %xmm6, -128(out1)
movss %xmm2, (out1)
movss %xmm7, (out1,%rax,1)
movss %xmm3, (out1,%rax,2)
leaq (out1,%rax,4), out1
movhlps %xmm6, %xmm6
movhlps %xmm2, %xmm2
movhlps %xmm7, %xmm7
movhlps %xmm3, %xmm3
movss %xmm6, -128(out1)
movss %xmm2, (out1)
movss %xmm7, (out1,%rax,1)
movss %xmm3, (out1,%rax,2)
#ifdef IS_MSABI
pop %rsi
pop %rdi
movaps (%rsp), %xmm6
movaps 16(%rsp), %xmm7
movaps 32(%rsp), %xmm8
movaps 48(%rsp), %xmm9
movaps 64(%rsp), %xmm10
movaps 80(%rsp), %xmm11
movaps 96(%rsp), %xmm12
mov %rbp, %rsp
pop %rbp
#endif
ret
NONEXEC_STACK

View File

@ -0,0 +1,336 @@
/*
dct64_i386.c: DCT64, a C variant for i386
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
/*
* Discrete Cosine Tansform (DCT) for subband synthesis
* optimized for machines with no auto-increment.
* The performance is highly compiler dependend. Maybe
* the dct64.c version for 'normal' processor may be faster
* even for Intel processors.
*/
#include "mpg123lib_intern.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] = REAL_MUL(samples[0x00] - samples[0x1F], costab[0x0]);
b1[0x1E] = REAL_MUL(samples[0x01] - samples[0x1E], costab[0x1]);
b1[0x02] = samples[0x02] + samples[0x1D];
b1[0x03] = samples[0x03] + samples[0x1C];
b1[0x1D] = REAL_MUL(samples[0x02] - samples[0x1D], costab[0x2]);
b1[0x1C] = REAL_MUL(samples[0x03] - samples[0x1C], costab[0x3]);
b1[0x04] = samples[0x04] + samples[0x1B];
b1[0x05] = samples[0x05] + samples[0x1A];
b1[0x1B] = REAL_MUL(samples[0x04] - samples[0x1B], costab[0x4]);
b1[0x1A] = REAL_MUL(samples[0x05] - samples[0x1A], costab[0x5]);
b1[0x06] = samples[0x06] + samples[0x19];
b1[0x07] = samples[0x07] + samples[0x18];
b1[0x19] = REAL_MUL(samples[0x06] - samples[0x19], costab[0x6]);
b1[0x18] = REAL_MUL(samples[0x07] - samples[0x18], costab[0x7]);
b1[0x08] = samples[0x08] + samples[0x17];
b1[0x09] = samples[0x09] + samples[0x16];
b1[0x17] = REAL_MUL(samples[0x08] - samples[0x17], costab[0x8]);
b1[0x16] = REAL_MUL(samples[0x09] - samples[0x16], costab[0x9]);
b1[0x0A] = samples[0x0A] + samples[0x15];
b1[0x0B] = samples[0x0B] + samples[0x14];
b1[0x15] = REAL_MUL(samples[0x0A] - samples[0x15], costab[0xA]);
b1[0x14] = REAL_MUL(samples[0x0B] - samples[0x14], costab[0xB]);
b1[0x0C] = samples[0x0C] + samples[0x13];
b1[0x0D] = samples[0x0D] + samples[0x12];
b1[0x13] = REAL_MUL(samples[0x0C] - samples[0x13], costab[0xC]);
b1[0x12] = REAL_MUL(samples[0x0D] - samples[0x12], costab[0xD]);
b1[0x0E] = samples[0x0E] + samples[0x11];
b1[0x0F] = samples[0x0F] + samples[0x10];
b1[0x11] = REAL_MUL(samples[0x0E] - samples[0x11], costab[0xE]);
b1[0x10] = REAL_MUL(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] = REAL_MUL(b1[0x00] - b1[0x0F], costab[0]);
b2[0x0E] = REAL_MUL(b1[0x01] - b1[0x0E], costab[1]);
b2[0x02] = b1[0x02] + b1[0x0D];
b2[0x03] = b1[0x03] + b1[0x0C];
b2[0x0D] = REAL_MUL(b1[0x02] - b1[0x0D], costab[2]);
b2[0x0C] = REAL_MUL(b1[0x03] - b1[0x0C], costab[3]);
b2[0x04] = b1[0x04] + b1[0x0B];
b2[0x05] = b1[0x05] + b1[0x0A];
b2[0x0B] = REAL_MUL(b1[0x04] - b1[0x0B], costab[4]);
b2[0x0A] = REAL_MUL(b1[0x05] - b1[0x0A], costab[5]);
b2[0x06] = b1[0x06] + b1[0x09];
b2[0x07] = b1[0x07] + b1[0x08];
b2[0x09] = REAL_MUL(b1[0x06] - b1[0x09], costab[6]);
b2[0x08] = REAL_MUL(b1[0x07] - b1[0x08], costab[7]);
/* */
b2[0x10] = b1[0x10] + b1[0x1F];
b2[0x11] = b1[0x11] + b1[0x1E];
b2[0x1F] = REAL_MUL(b1[0x1F] - b1[0x10], costab[0]);
b2[0x1E] = REAL_MUL(b1[0x1E] - b1[0x11], costab[1]);
b2[0x12] = b1[0x12] + b1[0x1D];
b2[0x13] = b1[0x13] + b1[0x1C];
b2[0x1D] = REAL_MUL(b1[0x1D] - b1[0x12], costab[2]);
b2[0x1C] = REAL_MUL(b1[0x1C] - b1[0x13], costab[3]);
b2[0x14] = b1[0x14] + b1[0x1B];
b2[0x15] = b1[0x15] + b1[0x1A];
b2[0x1B] = REAL_MUL(b1[0x1B] - b1[0x14], costab[4]);
b2[0x1A] = REAL_MUL(b1[0x1A] - b1[0x15], costab[5]);
b2[0x16] = b1[0x16] + b1[0x19];
b2[0x17] = b1[0x17] + b1[0x18];
b2[0x19] = REAL_MUL(b1[0x19] - b1[0x16], costab[6]);
b2[0x18] = REAL_MUL(b1[0x18] - b1[0x17], costab[7]);
}
{
register real *costab = pnts[2];
b1[0x00] = b2[0x00] + b2[0x07];
b1[0x07] = REAL_MUL(b2[0x00] - b2[0x07], costab[0]);
b1[0x01] = b2[0x01] + b2[0x06];
b1[0x06] = REAL_MUL(b2[0x01] - b2[0x06], costab[1]);
b1[0x02] = b2[0x02] + b2[0x05];
b1[0x05] = REAL_MUL(b2[0x02] - b2[0x05], costab[2]);
b1[0x03] = b2[0x03] + b2[0x04];
b1[0x04] = REAL_MUL(b2[0x03] - b2[0x04], costab[3]);
b1[0x08] = b2[0x08] + b2[0x0F];
b1[0x0F] = REAL_MUL(b2[0x0F] - b2[0x08], costab[0]);
b1[0x09] = b2[0x09] + b2[0x0E];
b1[0x0E] = REAL_MUL(b2[0x0E] - b2[0x09], costab[1]);
b1[0x0A] = b2[0x0A] + b2[0x0D];
b1[0x0D] = REAL_MUL(b2[0x0D] - b2[0x0A], costab[2]);
b1[0x0B] = b2[0x0B] + b2[0x0C];
b1[0x0C] = REAL_MUL(b2[0x0C] - b2[0x0B], costab[3]);
b1[0x10] = b2[0x10] + b2[0x17];
b1[0x17] = REAL_MUL(b2[0x10] - b2[0x17], costab[0]);
b1[0x11] = b2[0x11] + b2[0x16];
b1[0x16] = REAL_MUL(b2[0x11] - b2[0x16], costab[1]);
b1[0x12] = b2[0x12] + b2[0x15];
b1[0x15] = REAL_MUL(b2[0x12] - b2[0x15], costab[2]);
b1[0x13] = b2[0x13] + b2[0x14];
b1[0x14] = REAL_MUL(b2[0x13] - b2[0x14], costab[3]);
b1[0x18] = b2[0x18] + b2[0x1F];
b1[0x1F] = REAL_MUL(b2[0x1F] - b2[0x18], costab[0]);
b1[0x19] = b2[0x19] + b2[0x1E];
b1[0x1E] = REAL_MUL(b2[0x1E] - b2[0x19], costab[1]);
b1[0x1A] = b2[0x1A] + b2[0x1D];
b1[0x1D] = REAL_MUL(b2[0x1D] - b2[0x1A], costab[2]);
b1[0x1B] = b2[0x1B] + b2[0x1C];
b1[0x1C] = REAL_MUL(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] = REAL_MUL(b1[0x00] - b1[0x03], cos0);
b2[0x01] = b1[0x01] + b1[0x02];
b2[0x02] = REAL_MUL(b1[0x01] - b1[0x02], cos1);
b2[0x04] = b1[0x04] + b1[0x07];
b2[0x07] = REAL_MUL(b1[0x07] - b1[0x04], cos0);
b2[0x05] = b1[0x05] + b1[0x06];
b2[0x06] = REAL_MUL(b1[0x06] - b1[0x05], cos1);
b2[0x08] = b1[0x08] + b1[0x0B];
b2[0x0B] = REAL_MUL(b1[0x08] - b1[0x0B], cos0);
b2[0x09] = b1[0x09] + b1[0x0A];
b2[0x0A] = REAL_MUL(b1[0x09] - b1[0x0A], cos1);
b2[0x0C] = b1[0x0C] + b1[0x0F];
b2[0x0F] = REAL_MUL(b1[0x0F] - b1[0x0C], cos0);
b2[0x0D] = b1[0x0D] + b1[0x0E];
b2[0x0E] = REAL_MUL(b1[0x0E] - b1[0x0D], cos1);
b2[0x10] = b1[0x10] + b1[0x13];
b2[0x13] = REAL_MUL(b1[0x10] - b1[0x13], cos0);
b2[0x11] = b1[0x11] + b1[0x12];
b2[0x12] = REAL_MUL(b1[0x11] - b1[0x12], cos1);
b2[0x14] = b1[0x14] + b1[0x17];
b2[0x17] = REAL_MUL(b1[0x17] - b1[0x14], cos0);
b2[0x15] = b1[0x15] + b1[0x16];
b2[0x16] = REAL_MUL(b1[0x16] - b1[0x15], cos1);
b2[0x18] = b1[0x18] + b1[0x1B];
b2[0x1B] = REAL_MUL(b1[0x18] - b1[0x1B], cos0);
b2[0x19] = b1[0x19] + b1[0x1A];
b2[0x1A] = REAL_MUL(b1[0x19] - b1[0x1A], cos1);
b2[0x1C] = b1[0x1C] + b1[0x1F];
b2[0x1F] = REAL_MUL(b1[0x1F] - b1[0x1C], cos0);
b2[0x1D] = b1[0x1D] + b1[0x1E];
b2[0x1E] = REAL_MUL(b1[0x1E] - b1[0x1D], cos1);
}
{
register real const cos0 = pnts[4][0];
b1[0x00] = b2[0x00] + b2[0x01];
b1[0x01] = REAL_MUL(b2[0x00] - b2[0x01], cos0);
b1[0x02] = b2[0x02] + b2[0x03];
b1[0x03] = REAL_MUL(b2[0x03] - b2[0x02], cos0);
b1[0x02] += b1[0x03];
b1[0x04] = b2[0x04] + b2[0x05];
b1[0x05] = REAL_MUL(b2[0x04] - b2[0x05], cos0);
b1[0x06] = b2[0x06] + b2[0x07];
b1[0x07] = REAL_MUL(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] = REAL_MUL(b2[0x08] - b2[0x09], cos0);
b1[0x0A] = b2[0x0A] + b2[0x0B];
b1[0x0B] = REAL_MUL(b2[0x0B] - b2[0x0A], cos0);
b1[0x0A] += b1[0x0B];
b1[0x0C] = b2[0x0C] + b2[0x0D];
b1[0x0D] = REAL_MUL(b2[0x0C] - b2[0x0D], cos0);
b1[0x0E] = b2[0x0E] + b2[0x0F];
b1[0x0F] = REAL_MUL(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] = REAL_MUL(b2[0x10] - b2[0x11], cos0);
b1[0x12] = b2[0x12] + b2[0x13];
b1[0x13] = REAL_MUL(b2[0x13] - b2[0x12], cos0);
b1[0x12] += b1[0x13];
b1[0x14] = b2[0x14] + b2[0x15];
b1[0x15] = REAL_MUL(b2[0x14] - b2[0x15], cos0);
b1[0x16] = b2[0x16] + b2[0x17];
b1[0x17] = REAL_MUL(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] = REAL_MUL(b2[0x18] - b2[0x19], cos0);
b1[0x1A] = b2[0x1A] + b2[0x1B];
b1[0x1B] = REAL_MUL(b2[0x1B] - b2[0x1A], cos0);
b1[0x1A] += b1[0x1B];
b1[0x1C] = b2[0x1C] + b2[0x1D];
b1[0x1D] = REAL_MUL(b2[0x1C] - b2[0x1D], cos0);
b1[0x1E] = b2[0x1E] + b2[0x1F];
b1[0x1F] = REAL_MUL(b2[0x1F] - b2[0x1E], cos0);
b1[0x1E] += b1[0x1F];
b1[0x1C] += b1[0x1E];
b1[0x1E] += b1[0x1D];
b1[0x1D] += b1[0x1F];
}
out0[0x10*16] = REAL_SCALE_DCT64(b1[0x00]);
out0[0x10*12] = REAL_SCALE_DCT64(b1[0x04]);
out0[0x10* 8] = REAL_SCALE_DCT64(b1[0x02]);
out0[0x10* 4] = REAL_SCALE_DCT64(b1[0x06]);
out0[0x10* 0] = REAL_SCALE_DCT64(b1[0x01]);
out1[0x10* 0] = REAL_SCALE_DCT64(b1[0x01]);
out1[0x10* 4] = REAL_SCALE_DCT64(b1[0x05]);
out1[0x10* 8] = REAL_SCALE_DCT64(b1[0x03]);
out1[0x10*12] = REAL_SCALE_DCT64(b1[0x07]);
#if 1
out0[0x10*14] = REAL_SCALE_DCT64(b1[0x08] + b1[0x0C]);
out0[0x10*10] = REAL_SCALE_DCT64(b1[0x0C] + b1[0x0a]);
out0[0x10* 6] = REAL_SCALE_DCT64(b1[0x0A] + b1[0x0E]);
out0[0x10* 2] = REAL_SCALE_DCT64(b1[0x0E] + b1[0x09]);
out1[0x10* 2] = REAL_SCALE_DCT64(b1[0x09] + b1[0x0D]);
out1[0x10* 6] = REAL_SCALE_DCT64(b1[0x0D] + b1[0x0B]);
out1[0x10*10] = REAL_SCALE_DCT64(b1[0x0B] + b1[0x0F]);
out1[0x10*14] = REAL_SCALE_DCT64(b1[0x0F]);
#else
b1[0x08] += b1[0x0C];
out0[0x10*14] = REAL_SCALE_DCT64(b1[0x08]);
b1[0x0C] += b1[0x0a];
out0[0x10*10] = REAL_SCALE_DCT64(b1[0x0C]);
b1[0x0A] += b1[0x0E];
out0[0x10* 6] = REAL_SCALE_DCT64(b1[0x0A]);
b1[0x0E] += b1[0x09];
out0[0x10* 2] = REAL_SCALE_DCT64(b1[0x0E]);
b1[0x09] += b1[0x0D];
out1[0x10* 2] = REAL_SCALE_DCT64(b1[0x09]);
b1[0x0D] += b1[0x0B];
out1[0x10* 6] = REAL_SCALE_DCT64(b1[0x0D]);
b1[0x0B] += b1[0x0F];
out1[0x10*10] = REAL_SCALE_DCT64(b1[0x0B]);
out1[0x10*14] = REAL_SCALE_DCT64(b1[0x0F]);
#endif
{
real tmp;
tmp = b1[0x18] + b1[0x1C];
out0[0x10*15] = REAL_SCALE_DCT64(tmp + b1[0x10]);
out0[0x10*13] = REAL_SCALE_DCT64(tmp + b1[0x14]);
tmp = b1[0x1C] + b1[0x1A];
out0[0x10*11] = REAL_SCALE_DCT64(tmp + b1[0x14]);
out0[0x10* 9] = REAL_SCALE_DCT64(tmp + b1[0x12]);
tmp = b1[0x1A] + b1[0x1E];
out0[0x10* 7] = REAL_SCALE_DCT64(tmp + b1[0x12]);
out0[0x10* 5] = REAL_SCALE_DCT64(tmp + b1[0x16]);
tmp = b1[0x1E] + b1[0x19];
out0[0x10* 3] = REAL_SCALE_DCT64(tmp + b1[0x16]);
out0[0x10* 1] = REAL_SCALE_DCT64(tmp + b1[0x11]);
tmp = b1[0x19] + b1[0x1D];
out1[0x10* 1] = REAL_SCALE_DCT64(tmp + b1[0x11]);
out1[0x10* 3] = REAL_SCALE_DCT64(tmp + b1[0x15]);
tmp = b1[0x1D] + b1[0x1B];
out1[0x10* 5] = REAL_SCALE_DCT64(tmp + b1[0x15]);
out1[0x10* 7] = REAL_SCALE_DCT64(tmp + b1[0x13]);
tmp = b1[0x1B] + b1[0x1F];
out1[0x10* 9] = REAL_SCALE_DCT64(tmp + b1[0x13]);
out1[0x10*11] = REAL_SCALE_DCT64(tmp + b1[0x17]);
out1[0x10*13] = REAL_SCALE_DCT64(b1[0x17] + b1[0x1F]);
out1[0x10*15] = REAL_SCALE_DCT64(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_i386(real *a,real *b,real *c)
{
real bufs[0x40];
dct64_1(a,b,bufs,bufs+0x20,c);
}

View File

@ -0,0 +1,342 @@
/*
dct64_i486.c: DCT64, a plain C variant for i486
copyright 1998-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Fabrice Bellard
*/
/* 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.
*/
#include "mpg123lib_intern.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 MULL(a,b) (((long long)(a)*(long long)(b)) >> 15)
#define MUL(a,b) \
(\
((!(b & 0x3F)) ? (((a)*(b >> 6)) >> 9) :\
((!(b & 0x1F)) ? (((a)*(b >> 5)) >> 10) :\
((!(b & 0x0F)) ? (((a)*(b >> 4)) >> 11) :\
((!(b & 0x07)) ? (((a)*(b >> 3)) >> 12) :\
((!(b & 0x03)) ? (((a)*(b >> 2)) >> 13) :\
((!(b & 0x01)) ? (((a)*(b >> 1)) >> 14) :\
(((a)*(b )) >> 15))))))))
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_i486(int *a,int *b,real *samples)
{
int bufs[64];
int i;
#ifdef REAL_IS_FIXED
#define TOINT(a) ((a) * 32768 / (int)REAL_FACTOR)
for(i=0;i<32;i++) {
bufs[i]=TOINT(samples[i]);
}
#else
int *p = bufs;
register double const scale = ((65536.0 * 32) + 1) * 65536.0;
for(i=0;i<32;i++) {
*((double *) (p++)) = scale + *samples++; /* beware on bufs overrun: 8B store from x87 */
}
#endif
dct64_1_486(a,b,bufs+32,bufs);
}

View File

@ -0,0 +1,825 @@
/*
dct64_mmx.s: MMX optimized DCT64
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by the mysterious higway (apparently)
*/
#include "mangle.h"
.text
ALIGN32
.globl ASM_NAME(dct64_mmx)
ASM_NAME(dct64_mmx):
xorl %ecx,%ecx
.globl ASM_NAME(dct64_MMX)
ASM_NAME(dct64_MMX):
pushl %ebx
pushl %esi
pushl %edi
subl $256,%esp
GET_GOT
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)
#if defined(PIC) && defined(__APPLE__)
movl GLOBAL_VAR_PTR(costab_mmxsse),%ebx
#else
leal GLOBAL_VAR(costab_mmxsse),%ebx
#endif
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)
fistps 512(%esi)
flds (%ecx)
fsubs 4(%ecx)
fmuls 120(%ebx)
fistps (%esi)
flds 12(%ecx)
fsubs 8(%ecx)
fmuls 120(%ebx)
fists 256(%edi)
fadds 12(%ecx)
fadds 8(%ecx)
fistps 256(%esi)
flds 16(%ecx)
fsubs 20(%ecx)
fmuls 120(%ebx)
flds 28(%ecx)
fsubs 24(%ecx)
fmuls 120(%ebx)
fists 384(%edi)
fld %st(0)
fadds 24(%ecx)
fadds 28(%ecx)
fld %st(0)
fadds 16(%ecx)
fadds 20(%ecx)
fistps 384(%esi)
fadd %st(2)
fistps 128(%esi)
faddp %st(1)
fistps 128(%edi)
flds 32(%edx)
fadds 48(%edx)
fistps 448(%esi)
flds 48(%edx)
fadds 40(%edx)
fistps 320(%esi)
flds 40(%edx)
fadds 56(%edx)
fistps 192(%esi)
flds 56(%edx)
fadds 36(%edx)
fistps 64(%esi)
flds 36(%edx)
fadds 52(%edx)
fistps 64(%edi)
flds 52(%edx)
fadds 44(%edx)
fistps 192(%edi)
flds 60(%edx)
fists 448(%edi)
fadds 44(%edx)
fistps 320(%edi)
flds 96(%edx)
fadds 112(%edx)
fld %st(0)
fadds 64(%edx)
fistps 480(%esi)
fadds 80(%edx)
fistps 416(%esi)
flds 112(%edx)
fadds 104(%edx)
fld %st(0)
fadds 80(%edx)
fistps 352(%esi)
fadds 72(%edx)
fistps 288(%esi)
flds 104(%edx)
fadds 120(%edx)
fld %st(0)
fadds 72(%edx)
fistps 224(%esi)
fadds 88(%edx)
fistps 160(%esi)
flds 120(%edx)
fadds 100(%edx)
fld %st(0)
fadds 88(%edx)
fistps 96(%esi)
fadds 68(%edx)
fistps 32(%esi)
flds 100(%edx)
fadds 116(%edx)
fld %st(0)
fadds 68(%edx)
fistps 32(%edi)
fadds 84(%edx)
fistps 96(%edi)
flds 116(%edx)
fadds 108(%edx)
fld %st(0)
fadds 84(%edx)
fistps 160(%edi)
fadds 76(%edx)
fistps 224(%edi)
flds 108(%edx)
fadds 124(%edx)
fld %st(0)
fadds 76(%edx)
fistps 288(%edi)
fadds 92(%edx)
fistps 352(%edi)
flds 124(%edx)
fists 480(%edi)
fadds 92(%edx)
fistps 416(%edi)
movsw
addl $256,%esp
popl %edi
popl %esi
popl %ebx
ret
#if defined(PIC) && defined(__APPLE__)
.section __IMPORT,__pointers,non_lazy_symbol_pointers
L_costab_mmxsse:
.indirect_symbol ASM_NAME(costab_mmxsse)
.long 0
#endif
NONEXEC_STACK

View File

@ -0,0 +1,310 @@
/*
dct64_neon: ARM NEON optimized dct64
copyright 1995-2010 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#ifndef _M_ARM
.code 32
#endif
#ifndef __APPLE__
.fpu neon
#endif
.text
ALIGN16
costab_arm:
.word 1056974725
.word 1057056395
.word 1057223771
.word 1057485416
.word 1057855544
.word 1058356026
.word 1059019886
.word 1059897405
.word 1061067246
.word 1062657950
.word 1064892987
.word 1066774581
.word 1069414683
.word 1073984175
.word 1079645762
.word 1092815430
.word 1057005197
.word 1057342072
.word 1058087743
.word 1059427869
.word 1061799040
.word 1065862217
.word 1071413542
.word 1084439708
.word 1057128951
.word 1058664893
.word 1063675095
.word 1076102863
.word 1057655764
.word 1067924853
.word 1060439283
.word 1060439283
ALIGN4
GLOBAL_SYMBOL ASM_NAME(dct64_neon)
#ifdef __ELF__
.type ASM_NAME(dct64_neon), %function
#endif
ASM_NAME(dct64_neon):
vpush {q4-q7}
adr r3, costab_arm
vld1.32 {q0, q1}, [r2]!
vld1.32 {q2, q3}, [r2]!
vld1.32 {q4, q5}, [r2]!
vld1.32 {q6, q7}, [r2]
vld1.32 {q12, q13}, [r3, :128]!
vld1.32 {q14, q15}, [r3, :128]!
vrev64.32 q4, q4
vrev64.32 q5, q5
vrev64.32 q6, q6
vrev64.32 q7, q7
vswp d8, d9
vswp d10, d11
vswp d12, d13
vswp d14, d15
vsub.f32 q8, q0, q7
vsub.f32 q9, q1, q6
vsub.f32 q10, q2, q5
vsub.f32 q11, q3, q4
vadd.f32 q0, q0, q7
vadd.f32 q1, q1, q6
vadd.f32 q2, q2, q5
vadd.f32 q3, q3, q4
vmul.f32 q4, q8, q12
vmul.f32 q5, q9, q13
vmul.f32 q6, q10, q14
vmul.f32 q7, q11, q15
vld1.32 {q12, q13}, [r3, :128]!
vld1.32 {q14, q15}, [r3, :128]
vrev64.32 q2, q2
vrev64.32 q3, q3
vrev64.32 q6, q6
vrev64.32 q7, q7
vswp d4, d5
vswp d6, d7
vswp d12, d13
vswp d14, d15
vsub.f32 q8, q0, q3
vsub.f32 q9, q1, q2
vsub.f32 q10, q4, q7
vsub.f32 q11, q5, q6
vadd.f32 q0, q0, q3
vadd.f32 q1, q1, q2
vadd.f32 q4, q4, q7
vadd.f32 q5, q5, q6
vmul.f32 q2, q8, q12
vmul.f32 q3, q9, q13
vmul.f32 q6, q10, q12
vmul.f32 q7, q11, q13
vrev64.32 q1, q1
vrev64.32 q3, q3
vrev64.32 q5, q5
vrev64.32 q7, q7
vswp d2, d3
vswp d6, d7
vswp d10, d11
vswp d14, d15
vsub.f32 q8, q0, q1
vsub.f32 q9, q2, q3
vsub.f32 q10, q4, q5
vsub.f32 q11, q6, q7
vadd.f32 q0, q0, q1
vadd.f32 q2, q2, q3
vadd.f32 q4, q4, q5
vadd.f32 q6, q6, q7
vmul.f32 q1, q8, q14
vmul.f32 q3, q9, q14
vmul.f32 q5, q10, q14
vmul.f32 q7, q11, q14
vdup.32 q12, d31[0]
vmov d31, d30
vswp d1, d2
vswp d5, d6
vswp d9, d10
vswp d13, d14
vrev64.32 q1, q1
vrev64.32 q3, q3
vrev64.32 q5, q5
vrev64.32 q7, q7
vsub.f32 q8, q0, q1
vsub.f32 q9, q2, q3
vsub.f32 q10, q4, q5
vsub.f32 q11, q6, q7
vadd.f32 q0, q0, q1
vadd.f32 q2, q2, q3
vadd.f32 q4, q4, q5
vadd.f32 q6, q6, q7
vmul.f32 q1, q8, q15
vmul.f32 q3, q9, q15
vmul.f32 q5, q10, q15
vmul.f32 q7, q11, q15
vtrn.32 q0, q1
vtrn.32 q2, q3
vtrn.32 q4, q5
vtrn.32 q6, q7
vsub.f32 q8, q0, q1
vsub.f32 q9, q2, q3
vsub.f32 q10, q4, q5
vsub.f32 q11, q6, q7
vadd.f32 q0, q0, q1
vadd.f32 q2, q2, q3
vadd.f32 q4, q4, q5
vadd.f32 q6, q6, q7
vmul.f32 q1, q8, q12
vmul.f32 q3, q9, q12
vmul.f32 q5, q10, q12
vmul.f32 q7, q11, q12
vtrn.32 q0, q1
vtrn.32 q2, q3
vtrn.32 q4, q5
vtrn.32 q6, q7
vswp d1, d2
vswp d5, d6
vswp d9, d10
vswp d13, d14
vshr.u64 d16, d1, #32
vshr.u64 d17, d3, #32
vshr.u64 d18, d5, #32
vshr.u64 d19, d7, #32
vadd.f32 d1, d1, d16
vadd.f32 d3, d3, d17
vadd.f32 d5, d5, d18
vadd.f32 d7, d7, d19
vshr.u64 d20, d9, #32
vshr.u64 d21, d11, #32
vshr.u64 d22, d13, #32
vshr.u64 d23, d15, #32
vadd.f32 d9, d9, d20
vadd.f32 d11, d11, d21
vadd.f32 d13, d13, d22
vadd.f32 d15, d15, d23
vshr.u64 d16, d2, #32
vshr.u64 d18, d6, #32
vshr.u64 d20, d10, #32
vshr.u64 d22, d14, #32
vext.8 q8, q1, q8, #8
vext.8 q9, q3, q9, #8
vext.8 q10, q5, q10, #8
vext.8 q11, q7, q11, #8
vadd.f32 q1, q1, q8
vadd.f32 q3, q3, q9
vadd.f32 q5, q5, q10
vadd.f32 q7, q7, q11
vshr.u64 d16, d4, #32
vshr.u64 d18, d12, #32
vext.8 q8, q2, q8, #8
vext.8 q9, q6, q9, #8
vadd.f32 q2, q2, q3
vadd.f32 q6, q6, q7
vadd.f32 q3, q3, q8
vadd.f32 q7, q7, q9
vrev64.32 q8, q4
vshr.u64 d19, d9, #32
vext.8 d17, d17, d16, #4
vswp d9, d10
vswp d13, d14
vtrn.32 q4, q5
vtrn.32 q6, q7
vmov d16, d9
vmov d18, d11
vadd.f32 q4, q6
vadd.f32 q5, q7
vadd.f32 q6, q8
vadd.f32 q7, q9
vmov.i32 q8, #0x4b000000
vorr.i32 q8, #0x00400000
vadd.f32 q0, q0, q8
vadd.f32 q1, q1, q8
vadd.f32 q2, q2, q8
vadd.f32 q3, q3, q8
vadd.f32 q4, q4, q8
vadd.f32 q5, q5, q8
vadd.f32 q6, q6, q8
vadd.f32 q7, q7, q8
vshl.i32 q0, q0, #10
vshl.i32 q1, q1, #10
vshl.i32 q2, q2, #10
vshl.i32 q3, q3, #10
vshl.i32 q4, q4, #10
vshl.i32 q5, q5, #10
vshl.i32 q6, q6, #10
vshl.i32 q7, q7, #10
vqshrn.s32 d0, q0, #10
vqshrn.s32 d2, q1, #10
vqshrn.s32 d4, q2, #10
vqshrn.s32 d6, q3, #10
vqshrn.s32 d8, q4, #10
vqshrn.s32 d10, q5, #10
vqshrn.s32 d12, q6, #10
vqshrn.s32 d14, q7, #10
mov r3, #32
vst1.16 {d0[1]}, [r0, :16], r3
vst1.16 {d12[3]}, [r0, :16], r3
vst1.16 {d6[2]}, [r0, :16], r3
vst1.16 {d8[3]}, [r0, :16], r3
vst1.16 {d2[2]}, [r0, :16], r3
vst1.16 {d12[1]}, [r0, :16], r3
vst1.16 {d4[2]}, [r0, :16], r3
vst1.16 {d8[1]}, [r0, :16], r3
vst1.16 {d0[2]}, [r0, :16], r3
vst1.16 {d12[2]}, [r0, :16], r3
vst1.16 {d6[0]}, [r0, :16], r3
vst1.16 {d8[2]}, [r0, :16], r3
vst1.16 {d2[0]}, [r0, :16], r3
vst1.16 {d12[0]}, [r0, :16], r3
vst1.16 {d4[0]}, [r0, :16], r3
vst1.16 {d8[0]}, [r0, :16], r3
vst1.16 {d0[0]}, [r0, :16]
vst1.16 {d0[1]}, [r1, :16], r3
vst1.16 {d10[0]}, [r1, :16], r3
vst1.16 {d4[1]}, [r1, :16], r3
vst1.16 {d14[0]}, [r1, :16], r3
vst1.16 {d2[1]}, [r1, :16], r3
vst1.16 {d10[2]}, [r1, :16], r3
vst1.16 {d6[1]}, [r1, :16], r3
vst1.16 {d14[2]}, [r1, :16], r3
vst1.16 {d0[3]}, [r1, :16], r3
vst1.16 {d10[1]}, [r1, :16], r3
vst1.16 {d4[3]}, [r1, :16], r3
vst1.16 {d14[1]}, [r1, :16], r3
vst1.16 {d2[3]}, [r1, :16], r3
vst1.16 {d10[3]}, [r1, :16], r3
vst1.16 {d6[3]}, [r1, :16], r3
vst1.16 {d14[3]}, [r1, :16]
vpop {q4-q7}
bx lr
NONEXEC_STACK

View File

@ -0,0 +1,299 @@
/*
dct64_neon64: NEON optimized dct64 for AArch64
copyright 1995-2014 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN16
costab_neon_aarch64:
.word 1056974725
.word 1057056395
.word 1057223771
.word 1057485416
.word 1057855544
.word 1058356026
.word 1059019886
.word 1059897405
.word 1061067246
.word 1062657950
.word 1064892987
.word 1066774581
.word 1069414683
.word 1073984175
.word 1079645762
.word 1092815430
.word 1057005197
.word 1057342072
.word 1058087743
.word 1059427869
.word 1061799040
.word 1065862217
.word 1071413542
.word 1084439708
.word 1057128951
.word 1058664893
.word 1063675095
.word 1076102863
.word 1057655764
.word 1067924853
.word 1060439283
.word 1060439283
.text
ALIGN4
.globl ASM_NAME(dct64_neon64)
#ifdef __ELF__
.type ASM_NAME(dct64_neon64), %function
#endif
ASM_NAME(dct64_neon64):
add x3, x2, #64
adrp x4, AARCH64_PCREL_HI(costab_neon_aarch64)
add x4, x4, AARCH64_PCREL_LO(costab_neon_aarch64)
ld1 {v0.4s, v1.4s, v2.4s, v3.4s}, [x2]
ld1 {v16.4s, v17.4s, v18.4s, v19.4s}, [x3]
ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [x4], #64
rev64 v19.4s, v19.4s
rev64 v18.4s, v18.4s
rev64 v17.4s, v17.4s
rev64 v16.4s, v16.4s
ext v4.16b, v19.16b, v19.16b, #8
ext v5.16b, v18.16b, v18.16b, #8
ext v6.16b, v17.16b, v17.16b, #8
ext v7.16b, v16.16b, v16.16b, #8
fsub v16.4s, v3.4s, v7.4s
fsub v17.4s, v2.4s, v6.4s
fsub v18.4s, v1.4s, v5.4s
fsub v19.4s, v0.4s, v4.4s
fadd v0.4s, v0.4s, v4.4s /* bs[0,1,2,3] */
fadd v1.4s, v1.4s, v5.4s /* bs[4,5,6,7] */
fadd v2.4s, v2.4s, v6.4s /* bs[8,9,10,11] */
fadd v3.4s, v3.4s, v7.4s /* bs[12,13,14,15] */
fmul v16.4s, v16.4s, v23.4s /* bs[19,18,17,16] */
fmul v17.4s, v17.4s, v22.4s /* bs[23,22,21,20] */
fmul v18.4s, v18.4s, v21.4s /* bs[27,26,25,24] */
fmul v19.4s, v19.4s, v20.4s /* bs[31,30,29,28] */
ld1 {v20.4s, v21.4s}, [x4], #32
rev64 v22.4s, v3.4s
rev64 v23.4s, v2.4s
rev64 v24.4s, v16.4s
rev64 v25.4s, v17.4s
ext v4.16b, v22.16b, v22.16b, #8 /* bs[15,14,13,12] */
ext v5.16b, v23.16b, v23.16b, #8 /* bs[11,10,9,8] */
ext v6.16b, v24.16b, v24.16b, #8 /* bs[16,17,18,19] */
ext v7.16b, v25.16b, v25.16b, #8 /* bs[20,21,22,23] */
fsub v26.4s, v1.4s, v5.4s
fsub v27.4s, v0.4s, v4.4s
fsub v28.4s, v18.4s, v7.4s
fsub v29.4s, v19.4s, v6.4s
fadd v4.4s, v0.4s, v4.4s /* bs[32,33,34,35] */
fadd v5.4s, v1.4s, v5.4s /* bs[36,37,38,39] */
fadd v6.4s, v6.4s, v19.4s /* bs[48,49,50,51] */
fadd v7.4s, v7.4s, v18.4s /* bs[52,53,54,55] */
fmul v26.4s, v26.4s, v21.4s /* bs[43,42,41,40] */
fmul v27.4s, v27.4s, v20.4s /* bs[47,46,45,44] */
fmul v28.4s, v28.4s, v21.4s /* bs[59,58,57,56] */
fmul v29.4s, v29.4s, v20.4s /* bs[63,62,61,60] */
ld1 {v20.4s}, [x4], #16
rev64 v16.4s, v5.4s
rev64 v17.4s, v26.4s
rev64 v18.4s, v7.4s
rev64 v19.4s, v28.4s
ext v0.16b, v16.16b, v16.16b, #8 /* bs[39,38,37,36] */
ext v1.16b, v17.16b, v17.16b, #8 /* bs[40,41,42,43] */
ext v2.16b, v18.16b, v18.16b, #8 /* bs[55,54,53,52] */
ext v3.16b, v19.16b, v19.16b, #8 /* bs[56,57,58,59] */
fsub v16.4s, v4.4s, v0.4s
fsub v17.4s, v27.4s, v1.4s
fsub v18.4s, v6.4s, v2.4s
fsub v19.4s, v29.4s, v3.4s
fadd v0.4s, v4.4s, v0.4s /* bs[0,1,2,3] */
fadd v1.4s, v1.4s, v27.4s /* bs[8,9,10,11] */
fadd v2.4s, v6.4s, v2.4s /* bs[16,17,18,19] */
fadd v3.4s, v3.4s, v29.4s /* bs[24,25,26,27] */
fmul v16.4s, v16.4s, v20.4s /* bs[7,6,5,4] */
fmul v17.4s, v17.4s, v20.4s /* bs[15,14,13,12] */
fmul v18.4s, v18.4s, v20.4s /* bs[23,22,21,20] */
fmul v19.4s, v19.4s, v20.4s /* bs[31,30,29,28] */
ld1 {v28.4s}, [x4]
zip1 v4.2d, v0.2d, v16.2d /* bs[0,1,7,6] */
zip2 v5.2d, v0.2d, v16.2d /* bs[2,3,5,4] */
zip1 v6.2d, v1.2d, v17.2d /* bs[8,9,15,14] */
zip2 v7.2d, v1.2d, v17.2d /* bs[10,11,13,12] */
zip1 v20.2d, v2.2d, v18.2d /* bs[16,17,23,22] */
zip2 v21.2d, v2.2d, v18.2d /* bs[18,19,21,20] */
zip1 v22.2d, v3.2d, v19.2d /* bs[24,25,31,30] */
zip2 v23.2d, v3.2d, v19.2d /* bs[26,27,29,28] */
rev64 v5.4s, v5.4s /* bs[3,2,4,5] */
rev64 v7.4s, v7.4s /* bs[11,10,12,13] */
rev64 v21.4s, v21.4s /* bs[19,18,20,21] */
rev64 v23.4s, v23.4s /* bs[27,26,28,29] */
AARCH64_DUP_2D(v29, v28, 0)
AARCH64_DUP_4S(v28, v28, 2)
fsub v16.4s, v4.4s, v5.4s
fsub v17.4s, v6.4s, v7.4s
fsub v18.4s, v20.4s, v21.4s
fsub v19.4s, v22.4s, v23.4s
fadd v0.4s, v4.4s, v5.4s /* bs[32,33,36,37] */
fadd v1.4s, v6.4s, v7.4s /* bs[40,41,44,45] */
fadd v2.4s, v20.4s, v21.4s /* bs[48,49,52,53] */
fadd v3.4s, v22.4s, v23.4s /* bs[56,57,60,61] */
fmul v16.4s, v16.4s, v29.4s /* bs[35,34,39,38] */
fmul v17.4s, v17.4s, v29.4s /* bs[43,42,47,46] */
fmul v18.4s, v18.4s, v29.4s /* bs[51,50,55,54] */
fmul v19.4s, v19.4s, v29.4s /* bs[59,58,63,62] */
uzp1 v4.4s, v0.4s, v16.4s /* bs[32,36,35,39] */
uzp2 v5.4s, v0.4s, v16.4s /* bs[33,37,34,38] */
uzp1 v6.4s, v1.4s, v17.4s /* bs[40,44,43,47] */
uzp2 v7.4s, v1.4s, v17.4s /* bs[41,45,42,46] */
uzp1 v20.4s, v2.4s, v18.4s /* bs[48,52,51,55] */
uzp2 v21.4s, v2.4s, v18.4s /* bs[49,53,50,54] */
uzp1 v22.4s, v3.4s, v19.4s /* bs[56,60,59,63] */
uzp2 v23.4s, v3.4s, v19.4s /* bs[57,61,58,62] */
fsub v16.4s, v4.4s, v5.4s
fsub v17.4s, v6.4s, v7.4s
fsub v18.4s, v20.4s, v21.4s
fsub v19.4s, v22.4s, v23.4s
fadd v0.4s, v4.4s, v5.4s /* bs[0,4,2,6] */
fadd v1.4s, v6.4s, v7.4s /* bs[8,12,10,14] */
fadd v2.4s, v20.4s, v21.4s /* bs[16,20,18,22] */
fadd v3.4s, v22.4s, v23.4s /* bs[24,28,26,30] */
fmul v16.4s, v16.4s, v28.4s /* bs[1,5,3,7] */
fmul v17.4s, v17.4s, v28.4s /* bs[9,13,11,15] */
fmul v18.4s, v18.4s, v28.4s /* bs[17,21,19,23] */
fmul v19.4s, v19.4s, v28.4s /* bs[25,29,27,31] */
zip2 v4.2d, v0.2d, v1.2d /* bs[2,6,10,14] */
zip2 v5.2d, v16.2d, v17.2d /* bs[3,7,11,15] */
zip2 v6.2d, v2.2d, v3.2d /* bs[18,22,26,30] */
zip2 v7.2d, v18.2d, v19.2d /* bs[19,23,27,31] */
fadd v4.4s, v4.4s, v5.4s /* bs[2,6,10,14] */
fadd v6.4s, v6.4s, v7.4s /* bs[18,22,26,30] */
ins v0.d[1], v4.d[0] /* bs[0,4,2,6] */
ins v1.d[1], v4.d[1] /* bs[8,12,10,14] */
ins v2.d[1], v6.d[0] /* bs[16,20,18,22] */
ins v3.d[1], v6.d[1] /* bs[24,28,26,30] */
eor v31.16b, v31.16b, v31.16b
zip1 v4.4s, v0.4s, v16.4s /* bs[0,1,4,5] */
zip2 v5.4s, v0.4s, v16.4s /* bs[2,3,6,7] */
zip1 v6.4s, v1.4s, v17.4s /* bs[8,9,12,13] */
zip2 v7.4s, v1.4s, v17.4s /* bs[10,11,14,15] */
zip1 v20.4s, v2.4s, v18.4s /* bs[16,17,20,21] */
zip2 v21.4s, v2.4s, v18.4s /* bs[18,19,22,23] */
zip1 v22.4s, v3.4s, v19.4s /* bs[24,25,28,29] */
zip2 v23.4s, v3.4s, v19.4s /* bs[26,27,30,31] */
zip1 v0.2d, v4.2d, v5.2d /* bs[0,1,2,3] */
zip2 v1.2d, v4.2d, v5.2d /* bs[4,5,6,7] */
zip1 v2.2d, v6.2d, v7.2d /* bs[8,9,10,11] */
zip2 v3.2d, v6.2d, v7.2d /* bs[12,13,14,15] */
rev64 v16.4s, v4.4s
rev64 v17.4s, v6.4s
zip1 v24.2d, v7.2d, v17.2d
zip2 v16.2d, v5.2d, v16.2d
zip2 v17.2d, v7.2d, v17.2d
zip1 v4.2d, v20.2d, v21.2d /* bs[16,17,18,19] */
zip2 v5.2d, v20.2d, v21.2d /* bs[20,21,22,23] */
zip1 v6.2d, v22.2d, v23.2d /* bs[24,25,26,27] */
zip2 v7.2d, v22.2d, v23.2d /* bs[28,29,30,31] */
rev64 v18.4s, v20.4s
rev64 v19.4s, v22.4s
zip1 v25.2d, v23.2d, v19.2d
zip1 v26.2d, v21.2d, v18.2d
zip2 v18.2d, v21.2d, v18.2d
zip2 v19.2d, v23.2d, v19.2d
ins v16.s[3], v31.s[0] /* bs[6,7,5,-] */
ins v17.s[3], v31.s[0] /* bs[14,15,13,-] */
ins v18.s[3], v31.s[0] /* bs[22,23,21,-] */
ins v19.s[3], v31.s[0] /* bs[30,31,29,-] */
ins v24.s[3], v31.s[0] /* bs[10,11,9,-] */
ins v25.s[3], v31.s[0] /* bs[26,27,25,-] */
ins v26.s[3], v31.s[0] /* bs[18,19,17,-] */
fadd v1.4s, v1.4s, v16.4s
fadd v3.4s, v3.4s, v17.4s
fadd v5.4s, v5.4s, v18.4s
fadd v7.4s, v7.4s, v19.4s
fadd v2.4s, v2.4s, v3.4s
fadd v3.4s, v3.4s, v24.4s
fadd v6.4s, v6.4s, v7.4s
fadd v7.4s, v7.4s, v25.4s
fadd v4.4s, v4.4s, v6.4s
fadd v6.4s, v6.4s, v5.4s
fadd v5.4s, v5.4s, v7.4s
fadd v7.4s, v7.4s, v26.4s
fcvtns v0.4s, v0.4s
fcvtns v1.4s, v1.4s
fcvtns v2.4s, v2.4s
fcvtns v3.4s, v3.4s
fcvtns v4.4s, v4.4s
fcvtns v5.4s, v5.4s
fcvtns v6.4s, v6.4s
fcvtns v7.4s, v7.4s
sqxtn v0.4h, v0.4s
sqxtn v1.4h, v1.4s
sqxtn v2.4h, v2.4s
sqxtn v3.4h, v3.4s
sqxtn v4.4h, v4.4s
sqxtn v5.4h, v5.4s
sqxtn v6.4h, v6.4s
sqxtn v7.4h, v7.4s
mov x3, #32
st1 {v0.h}[1], [x0], x3
st1 {v7.h}[2], [x0], x3
st1 {v3.h}[2], [x0], x3
st1 {v5.h}[2], [x0], x3
st1 {v1.h}[2], [x0], x3
st1 {v6.h}[2], [x0], x3
st1 {v2.h}[2], [x0], x3
st1 {v4.h}[2], [x0], x3
st1 {v0.h}[2], [x0], x3
st1 {v7.h}[0], [x0], x3
st1 {v3.h}[0], [x0], x3
st1 {v5.h}[0], [x0], x3
st1 {v1.h}[0], [x0], x3
st1 {v6.h}[0], [x0], x3
st1 {v2.h}[0], [x0], x3
st1 {v4.h}[0], [x0], x3
st1 {v0.h}[0], [x0]
st1 {v0.h}[1], [x1], x3
st1 {v4.h}[1], [x1], x3
st1 {v2.h}[1], [x1], x3
st1 {v6.h}[1], [x1], x3
st1 {v1.h}[1], [x1], x3
st1 {v5.h}[1], [x1], x3
st1 {v3.h}[1], [x1], x3
st1 {v7.h}[1], [x1], x3
st1 {v0.h}[3], [x1], x3
st1 {v4.h}[3], [x1], x3
st1 {v2.h}[3], [x1], x3
st1 {v6.h}[3], [x1], x3
st1 {v1.h}[3], [x1], x3
st1 {v5.h}[3], [x1], x3
st1 {v3.h}[3], [x1], x3
st1 {v7.h}[3], [x1]
ret
NONEXEC_STACK

View File

@ -0,0 +1,282 @@
/*
dct64_neon64_float: NEON optimized dct64 for AArch64 (float output version)
copyright 1995-2014 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN16
costab_neon_aarch64:
.word 1056974725
.word 1057056395
.word 1057223771
.word 1057485416
.word 1057855544
.word 1058356026
.word 1059019886
.word 1059897405
.word 1061067246
.word 1062657950
.word 1064892987
.word 1066774581
.word 1069414683
.word 1073984175
.word 1079645762
.word 1092815430
.word 1057005197
.word 1057342072
.word 1058087743
.word 1059427869
.word 1061799040
.word 1065862217
.word 1071413542
.word 1084439708
.word 1057128951
.word 1058664893
.word 1063675095
.word 1076102863
.word 1057655764
.word 1067924853
.word 1060439283
.word 1060439283
.text
ALIGN4
.globl ASM_NAME(dct64_real_neon64)
#ifdef __ELF__
.type ASM_NAME(dct64_real_neon64), %function
#endif
ASM_NAME(dct64_real_neon64):
add x3, x2, #64
adrp x4, AARCH64_PCREL_HI(costab_neon_aarch64)
add x4, x4, AARCH64_PCREL_LO(costab_neon_aarch64)
ld1 {v0.4s,v1.4s,v2.4s,v3.4s}, [x2]
ld1 {v16.4s,v17.4s,v18.4s,v19.4s}, [x3]
ld1 {v20.4s,v21.4s,v22.4s,v23.4s}, [x4], #64
rev64 v19.4s, v19.4s
rev64 v18.4s, v18.4s
rev64 v17.4s, v17.4s
rev64 v16.4s, v16.4s
ext v4.16b, v19.16b, v19.16b, #8
ext v5.16b, v18.16b, v18.16b, #8
ext v6.16b, v17.16b, v17.16b, #8
ext v7.16b, v16.16b, v16.16b, #8
fsub v16.4s, v3.4s, v7.4s
fsub v17.4s, v2.4s, v6.4s
fsub v18.4s, v1.4s, v5.4s
fsub v19.4s, v0.4s, v4.4s
fadd v0.4s, v0.4s, v4.4s /* bs[0,1,2,3] */
fadd v1.4s, v1.4s, v5.4s /* bs[4,5,6,7] */
fadd v2.4s, v2.4s, v6.4s /* bs[8,9,10,11] */
fadd v3.4s, v3.4s, v7.4s /* bs[12,13,14,15] */
fmul v16.4s, v16.4s, v23.4s /* bs[19,18,17,16] */
fmul v17.4s, v17.4s, v22.4s /* bs[23,22,21,20] */
fmul v18.4s, v18.4s, v21.4s /* bs[27,26,25,24] */
fmul v19.4s, v19.4s, v20.4s /* bs[31,30,29,28] */
ld1 {v20.4s, v21.4s}, [x4], #32
rev64 v22.4s, v3.4s
rev64 v23.4s, v2.4s
rev64 v24.4s, v16.4s
rev64 v25.4s, v17.4s
ext v4.16b, v22.16b, v22.16b, #8 /* bs[15,14,13,12] */
ext v5.16b, v23.16b, v23.16b, #8 /* bs[11,10,9,8] */
ext v6.16b, v24.16b, v24.16b, #8 /* bs[16,17,18,19] */
ext v7.16b, v25.16b, v25.16b, #8 /* bs[20,21,22,23] */
fsub v26.4s, v1.4s, v5.4s
fsub v27.4s, v0.4s, v4.4s
fsub v28.4s, v18.4s, v7.4s
fsub v29.4s, v19.4s, v6.4s
fadd v4.4s, v0.4s, v4.4s /* bs[32,33,34,35] */
fadd v5.4s, v1.4s, v5.4s /* bs[36,37,38,39] */
fadd v6.4s, v6.4s, v19.4s /* bs[48,49,50,51] */
fadd v7.4s, v7.4s, v18.4s /* bs[52,53,54,55] */
fmul v26.4s, v26.4s, v21.4s /* bs[43,42,41,40] */
fmul v27.4s, v27.4s, v20.4s /* bs[47,46,45,44] */
fmul v28.4s, v28.4s, v21.4s /* bs[59,58,57,56] */
fmul v29.4s, v29.4s, v20.4s /* bs[63,62,61,60] */
ld1 {v20.4s}, [x4], #16
rev64 v16.4s, v5.4s
rev64 v17.4s, v26.4s
rev64 v18.4s, v7.4s
rev64 v19.4s, v28.4s
ext v0.16b, v16.16b, v16.16b, #8 /* bs[39,38,37,36] */
ext v1.16b, v17.16b, v17.16b, #8 /* bs[40,41,42,43] */
ext v2.16b, v18.16b, v18.16b, #8 /* bs[55,54,53,52] */
ext v3.16b, v19.16b, v19.16b, #8 /* bs[56,57,58,59] */
fsub v16.4s, v4.4s, v0.4s
fsub v17.4s, v27.4s, v1.4s
fsub v18.4s, v6.4s, v2.4s
fsub v19.4s, v29.4s, v3.4s
fadd v0.4s, v4.4s, v0.4s /* bs[0,1,2,3] */
fadd v1.4s, v1.4s, v27.4s /* bs[8,9,10,11] */
fadd v2.4s, v6.4s, v2.4s /* bs[16,17,18,19] */
fadd v3.4s, v3.4s, v29.4s /* bs[24,25,26,27] */
fmul v16.4s, v16.4s, v20.4s /* bs[7,6,5,4] */
fmul v17.4s, v17.4s, v20.4s /* bs[15,14,13,12] */
fmul v18.4s, v18.4s, v20.4s /* bs[23,22,21,20] */
fmul v19.4s, v19.4s, v20.4s /* bs[31,30,29,28] */
ld1 {v28.4s}, [x4]
zip1 v4.2d, v0.2d, v16.2d /* bs[0,1,7,6] */
zip2 v5.2d, v0.2d, v16.2d /* bs[2,3,5,4] */
zip1 v6.2d, v1.2d, v17.2d /* bs[8,9,15,14] */
zip2 v7.2d, v1.2d, v17.2d /* bs[10,11,13,12] */
zip1 v20.2d, v2.2d, v18.2d /* bs[16,17,23,22] */
zip2 v21.2d, v2.2d, v18.2d /* bs[18,19,21,20] */
zip1 v22.2d, v3.2d, v19.2d /* bs[24,25,31,30] */
zip2 v23.2d, v3.2d, v19.2d /* bs[26,27,29,28] */
rev64 v5.4s, v5.4s /* bs[3,2,4,5] */
rev64 v7.4s, v7.4s /* bs[11,10,12,13] */
rev64 v21.4s, v21.4s /* bs[19,18,20,21] */
rev64 v23.4s, v23.4s /* bs[27,26,28,29] */
AARCH64_DUP_2D(v29, v28, 0)
AARCH64_DUP_4S(v28, v28, 2)
fsub v16.4s, v4.4s, v5.4s
fsub v17.4s, v6.4s, v7.4s
fsub v18.4s, v20.4s, v21.4s
fsub v19.4s, v22.4s, v23.4s
fadd v0.4s, v4.4s, v5.4s /* bs[32,33,36,37] */
fadd v1.4s, v6.4s, v7.4s /* bs[40,41,44,45] */
fadd v2.4s, v20.4s, v21.4s /* bs[48,49,52,53] */
fadd v3.4s, v22.4s, v23.4s /* bs[56,57,60,61] */
fmul v16.4s, v16.4s, v29.4s /* bs[35,34,39,38] */
fmul v17.4s, v17.4s, v29.4s /* bs[43,42,47,46] */
fmul v18.4s, v18.4s, v29.4s /* bs[51,50,55,54] */
fmul v19.4s, v19.4s, v29.4s /* bs[59,58,63,62] */
uzp1 v4.4s, v0.4s, v16.4s /* bs[32,36,35,39] */
uzp2 v5.4s, v0.4s, v16.4s /* bs[33,37,34,38] */
uzp1 v6.4s, v1.4s, v17.4s /* bs[40,44,43,47] */
uzp2 v7.4s, v1.4s, v17.4s /* bs[41,45,42,46] */
uzp1 v20.4s, v2.4s, v18.4s /* bs[48,52,51,55] */
uzp2 v21.4s, v2.4s, v18.4s /* bs[49,53,50,54] */
uzp1 v22.4s, v3.4s, v19.4s /* bs[56,60,59,63] */
uzp2 v23.4s, v3.4s, v19.4s /* bs[57,61,58,62] */
fsub v16.4s, v4.4s, v5.4s
fsub v17.4s, v6.4s, v7.4s
fsub v18.4s, v20.4s, v21.4s
fsub v19.4s, v22.4s, v23.4s
fadd v0.4s, v4.4s, v5.4s /* bs[0,4,2,6] */
fadd v1.4s, v6.4s, v7.4s /* bs[8,12,10,14] */
fadd v2.4s, v20.4s, v21.4s /* bs[16,20,18,22] */
fadd v3.4s, v22.4s, v23.4s /* bs[24,28,26,30] */
fmul v16.4s, v16.4s, v28.4s /* bs[1,5,3,7] */
fmul v17.4s, v17.4s, v28.4s /* bs[9,13,11,15] */
fmul v18.4s, v18.4s, v28.4s /* bs[17,21,19,23] */
fmul v19.4s, v19.4s, v28.4s /* bs[25,29,27,31] */
zip2 v4.2d, v0.2d, v1.2d /* bs[2,6,10,14] */
zip2 v5.2d, v16.2d, v17.2d /* bs[3,7,11,15] */
zip2 v6.2d, v2.2d, v3.2d /* bs[18,22,26,30] */
zip2 v7.2d, v18.2d, v19.2d /* bs[19,23,27,31] */
fadd v4.4s, v4.4s, v5.4s /* bs[2,6,10,14] */
fadd v6.4s, v6.4s, v7.4s /* bs[18,22,26,30] */
ins v0.d[1], v4.d[0] /* bs[0,4,2,6] */
ins v1.d[1], v4.d[1] /* bs[8,12,10,14] */
ins v2.d[1], v6.d[0] /* bs[16,20,18,22] */
ins v3.d[1], v6.d[1] /* bs[24,28,26,30] */
eor v31.16b, v31.16b, v31.16b
zip1 v4.4s, v0.4s, v16.4s /* bs[0,1,4,5] */
zip2 v5.4s, v0.4s, v16.4s /* bs[2,3,6,7] */
zip1 v6.4s, v1.4s, v17.4s /* bs[8,9,12,13] */
zip2 v7.4s, v1.4s, v17.4s /* bs[10,11,14,15] */
zip1 v20.4s, v2.4s, v18.4s /* bs[16,17,20,21] */
zip2 v21.4s, v2.4s, v18.4s /* bs[18,19,22,23] */
zip1 v22.4s, v3.4s, v19.4s /* bs[24,25,28,29] */
zip2 v23.4s, v3.4s, v19.4s /* bs[26,27,30,31] */
zip1 v0.2d, v4.2d, v5.2d /* bs[0,1,2,3] */
zip2 v1.2d, v4.2d, v5.2d /* bs[4,5,6,7] */
zip1 v2.2d, v6.2d, v7.2d /* bs[8,9,10,11] */
zip2 v3.2d, v6.2d, v7.2d /* bs[12,13,14,15] */
rev64 v16.4s, v4.4s
rev64 v17.4s, v6.4s
zip1 v24.2d, v7.2d, v17.2d
zip2 v16.2d, v5.2d, v16.2d
zip2 v17.2d, v7.2d, v17.2d
zip1 v4.2d, v20.2d, v21.2d /* bs[16,17,18,19] */
zip2 v5.2d, v20.2d, v21.2d /* bs[20,21,22,23] */
zip1 v6.2d, v22.2d, v23.2d /* bs[24,25,26,27] */
zip2 v7.2d, v22.2d, v23.2d /* bs[28,29,30,31] */
rev64 v18.4s, v20.4s
rev64 v19.4s, v22.4s
zip1 v25.2d, v23.2d, v19.2d
zip1 v26.2d, v21.2d, v18.2d
zip2 v18.2d, v21.2d, v18.2d
zip2 v19.2d, v23.2d, v19.2d
ins v16.s[3], v31.s[0] /* bs[6,7,5,-] */
ins v17.s[3], v31.s[0] /* bs[14,15,13,-] */
ins v18.s[3], v31.s[0] /* bs[22,23,21,-] */
ins v19.s[3], v31.s[0] /* bs[30,31,29,-] */
ins v24.s[3], v31.s[0] /* bs[10,11,9,-] */
ins v25.s[3], v31.s[0] /* bs[26,27,25,-] */
ins v26.s[3], v31.s[0] /* bs[18,19,17,-] */
fadd v1.4s, v1.4s, v16.4s
fadd v3.4s, v3.4s, v17.4s
fadd v5.4s, v5.4s, v18.4s
fadd v7.4s, v7.4s, v19.4s
fadd v2.4s, v2.4s, v3.4s
fadd v3.4s, v3.4s, v24.4s
fadd v6.4s, v6.4s, v7.4s
fadd v7.4s, v7.4s, v25.4s
fadd v4.4s, v4.4s, v6.4s
fadd v6.4s, v6.4s, v5.4s
fadd v5.4s, v5.4s, v7.4s
fadd v7.4s, v7.4s, v26.4s
mov x3, #64
st1 {v0.s}[1], [x0], x3
st1 {v7.s}[2], [x0], x3
st1 {v3.s}[2], [x0], x3
st1 {v5.s}[2], [x0], x3
st1 {v1.s}[2], [x0], x3
st1 {v6.s}[2], [x0], x3
st1 {v2.s}[2], [x0], x3
st1 {v4.s}[2], [x0], x3
st1 {v0.s}[2], [x0], x3
st1 {v7.s}[0], [x0], x3
st1 {v3.s}[0], [x0], x3
st1 {v5.s}[0], [x0], x3
st1 {v1.s}[0], [x0], x3
st1 {v6.s}[0], [x0], x3
st1 {v2.s}[0], [x0], x3
st1 {v4.s}[0], [x0], x3
st1 {v0.s}[0], [x0]
st1 {v0.s}[1], [x1], x3
st1 {v4.s}[1], [x1], x3
st1 {v2.s}[1], [x1], x3
st1 {v6.s}[1], [x1], x3
st1 {v1.s}[1], [x1], x3
st1 {v5.s}[1], [x1], x3
st1 {v3.s}[1], [x1], x3
st1 {v7.s}[1], [x1], x3
st1 {v0.s}[3], [x1], x3
st1 {v4.s}[3], [x1], x3
st1 {v2.s}[3], [x1], x3
st1 {v6.s}[3], [x1], x3
st1 {v1.s}[3], [x1], x3
st1 {v5.s}[3], [x1], x3
st1 {v3.s}[3], [x1], x3
st1 {v7.s}[3], [x1]
ret
NONEXEC_STACK

View File

@ -0,0 +1,283 @@
/*
dct64_neon_float: ARM NEON optimized dct64 (float output version)
copyright 1995-2010 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#ifndef _M_ARM
.code 32
#endif
#ifndef __APPLE__
.fpu neon
#endif
.text
ALIGN16
costab_arm:
.word 1056974725
.word 1057056395
.word 1057223771
.word 1057485416
.word 1057855544
.word 1058356026
.word 1059019886
.word 1059897405
.word 1061067246
.word 1062657950
.word 1064892987
.word 1066774581
.word 1069414683
.word 1073984175
.word 1079645762
.word 1092815430
.word 1057005197
.word 1057342072
.word 1058087743
.word 1059427869
.word 1061799040
.word 1065862217
.word 1071413542
.word 1084439708
.word 1057128951
.word 1058664893
.word 1063675095
.word 1076102863
.word 1057655764
.word 1067924853
.word 1060439283
.word 1060439283
ALIGN4
GLOBAL_SYMBOL ASM_NAME(dct64_real_neon)
#ifdef __ELF__
.type ASM_NAME(dct64_real_neon), %function
#endif
ASM_NAME(dct64_real_neon):
vpush {q4-q7}
adr r3, costab_arm
vld1.32 {q0, q1}, [r2]!
vld1.32 {q2, q3}, [r2]!
vld1.32 {q4, q5}, [r2]!
vld1.32 {q6, q7}, [r2]
vld1.32 {q12, q13}, [r3, :128]!
vld1.32 {q14, q15}, [r3, :128]!
vrev64.32 q4, q4
vrev64.32 q5, q5
vrev64.32 q6, q6
vrev64.32 q7, q7
vswp d8, d9
vswp d10, d11
vswp d12, d13
vswp d14, d15
vsub.f32 q8, q0, q7
vsub.f32 q9, q1, q6
vsub.f32 q10, q2, q5
vsub.f32 q11, q3, q4
vadd.f32 q0, q0, q7
vadd.f32 q1, q1, q6
vadd.f32 q2, q2, q5
vadd.f32 q3, q3, q4
vmul.f32 q4, q8, q12
vmul.f32 q5, q9, q13
vmul.f32 q6, q10, q14
vmul.f32 q7, q11, q15
vld1.32 {q12, q13}, [r3, :128]!
vld1.32 {q14, q15}, [r3, :128]
vrev64.32 q2, q2
vrev64.32 q3, q3
vrev64.32 q6, q6
vrev64.32 q7, q7
vswp d4, d5
vswp d6, d7
vswp d12, d13
vswp d14, d15
vsub.f32 q8, q0, q3
vsub.f32 q9, q1, q2
vsub.f32 q10, q4, q7
vsub.f32 q11, q5, q6
vadd.f32 q0, q0, q3
vadd.f32 q1, q1, q2
vadd.f32 q4, q4, q7
vadd.f32 q5, q5, q6
vmul.f32 q2, q8, q12
vmul.f32 q3, q9, q13
vmul.f32 q6, q10, q12
vmul.f32 q7, q11, q13
vrev64.32 q1, q1
vrev64.32 q3, q3
vrev64.32 q5, q5
vrev64.32 q7, q7
vswp d2, d3
vswp d6, d7
vswp d10, d11
vswp d14, d15
vsub.f32 q8, q0, q1
vsub.f32 q9, q2, q3
vsub.f32 q10, q4, q5
vsub.f32 q11, q6, q7
vadd.f32 q0, q0, q1
vadd.f32 q2, q2, q3
vadd.f32 q4, q4, q5
vadd.f32 q6, q6, q7
vmul.f32 q1, q8, q14
vmul.f32 q3, q9, q14
vmul.f32 q5, q10, q14
vmul.f32 q7, q11, q14
vdup.32 q12, d31[0]
vmov d31, d30
vswp d1, d2
vswp d5, d6
vswp d9, d10
vswp d13, d14
vrev64.32 q1, q1
vrev64.32 q3, q3
vrev64.32 q5, q5
vrev64.32 q7, q7
vsub.f32 q8, q0, q1
vsub.f32 q9, q2, q3
vsub.f32 q10, q4, q5
vsub.f32 q11, q6, q7
vadd.f32 q0, q0, q1
vadd.f32 q2, q2, q3
vadd.f32 q4, q4, q5
vadd.f32 q6, q6, q7
vmul.f32 q1, q8, q15
vmul.f32 q3, q9, q15
vmul.f32 q5, q10, q15
vmul.f32 q7, q11, q15
vtrn.32 q0, q1
vtrn.32 q2, q3
vtrn.32 q4, q5
vtrn.32 q6, q7
vsub.f32 q8, q0, q1
vsub.f32 q9, q2, q3
vsub.f32 q10, q4, q5
vsub.f32 q11, q6, q7
vadd.f32 q0, q0, q1
vadd.f32 q2, q2, q3
vadd.f32 q4, q4, q5
vadd.f32 q6, q6, q7
vmul.f32 q1, q8, q12
vmul.f32 q3, q9, q12
vmul.f32 q5, q10, q12
vmul.f32 q7, q11, q12
vtrn.32 q0, q1
vtrn.32 q2, q3
vtrn.32 q4, q5
vtrn.32 q6, q7
vswp d1, d2
vswp d5, d6
vswp d9, d10
vswp d13, d14
vshr.u64 d16, d1, #32
vshr.u64 d17, d3, #32
vshr.u64 d18, d5, #32
vshr.u64 d19, d7, #32
vadd.f32 d1, d1, d16
vadd.f32 d3, d3, d17
vadd.f32 d5, d5, d18
vadd.f32 d7, d7, d19
vshr.u64 d20, d9, #32
vshr.u64 d21, d11, #32
vshr.u64 d22, d13, #32
vshr.u64 d23, d15, #32
vadd.f32 d9, d9, d20
vadd.f32 d11, d11, d21
vadd.f32 d13, d13, d22
vadd.f32 d15, d15, d23
vshr.u64 d16, d2, #32
vshr.u64 d18, d6, #32
vshr.u64 d20, d10, #32
vshr.u64 d22, d14, #32
vext.8 q8, q1, q8, #8
vext.8 q9, q3, q9, #8
vext.8 q10, q5, q10, #8
vext.8 q11, q7, q11, #8
vadd.f32 q1, q1, q8
vadd.f32 q3, q3, q9
vadd.f32 q5, q5, q10
vadd.f32 q7, q7, q11
vshr.u64 d16, d4, #32
vshr.u64 d18, d12, #32
vext.8 q8, q2, q8, #8
vext.8 q9, q6, q9, #8
vadd.f32 q2, q2, q3
vadd.f32 q6, q6, q7
vadd.f32 q3, q3, q8
vadd.f32 q7, q7, q9
vrev64.32 q8, q4
vshr.u64 d19, d9, #32
vext.8 d17, d17, d16, #4
vswp d9, d10
vswp d13, d14
vtrn.32 q4, q5
vtrn.32 q6, q7
vmov d16, d9
vmov d18, d11
vadd.f32 q4, q6
vadd.f32 q5, q7
vadd.f32 q6, q8
vadd.f32 q7, q9
mov r3, #64
vst1.32 {d0[1]}, [r0, :32], r3
vst1.32 {d13[1]}, [r0, :32], r3
vst1.32 {d7[0]}, [r0, :32], r3
vst1.32 {d9[1]}, [r0, :32], r3
vst1.32 {d3[0]}, [r0, :32], r3
vst1.32 {d12[1]}, [r0, :32], r3
vst1.32 {d5[0]}, [r0, :32], r3
vst1.32 {d8[1]}, [r0, :32], r3
vst1.32 {d1[0]}, [r0, :32], r3
vst1.32 {d13[0]}, [r0, :32], r3
vst1.32 {d6[0]}, [r0, :32], r3
vst1.32 {d9[0]}, [r0, :32], r3
vst1.32 {d2[0]}, [r0, :32], r3
vst1.32 {d12[0]}, [r0, :32], r3
vst1.32 {d4[0]}, [r0, :32], r3
vst1.32 {d8[0]}, [r0, :32], r3
vst1.32 {d0[0]}, [r0, :32]
vst1.32 {d0[1]}, [r1, :32], r3
vst1.32 {d10[0]}, [r1, :32], r3
vst1.32 {d4[1]}, [r1, :32], r3
vst1.32 {d14[0]}, [r1, :32], r3
vst1.32 {d2[1]}, [r1, :32], r3
vst1.32 {d11[0]}, [r1, :32], r3
vst1.32 {d6[1]}, [r1, :32], r3
vst1.32 {d15[0]}, [r1, :32], r3
vst1.32 {d1[1]}, [r1, :32], r3
vst1.32 {d10[1]}, [r1, :32], r3
vst1.32 {d5[1]}, [r1, :32], r3
vst1.32 {d14[1]}, [r1, :32], r3
vst1.32 {d3[1]}, [r1, :32], r3
vst1.32 {d11[1]}, [r1, :32], r3
vst1.32 {d7[1]}, [r1, :32], r3
vst1.32 {d15[1]}, [r1, :32]
vpop {q4-q7}
bx lr
NONEXEC_STACK

View File

@ -0,0 +1,472 @@
/*
dct64_sse: MMX/SSE optimized dct64
copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#define ARG(n) (8+n*4)(%ebp)
#define TEMP(n) (4+n*16)(%esp)
#define TEMP_BYTE(n) (4+n)(%esp)
/*
void dct64_sse(short *out0, short *out1, real *samples);
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN16
pnpn:
.long 0
.long -2147483648
.long 0
.long -2147483648
ALIGN16
mask:
.long -1
.long -1
.long -1
.long 0
.text
ALIGN16
.globl ASM_NAME(dct64_sse)
ASM_NAME(dct64_sse):
pushl %ebp
movl %esp, %ebp
andl $-16, %esp /* align the stack at 16 bytes */
subl $128, %esp /* reserve space for temporal store */
pushl %ebx
GET_GOT
movl ARG(2), %eax
MOVUAPS (%eax), %xmm7
MOVUAPS 16(%eax), %xmm6
MOVUAPS 112(%eax), %xmm0
MOVUAPS 96(%eax), %xmm1
shufps $0x1b, %xmm0, %xmm0
shufps $0x1b, %xmm1, %xmm1
movaps %xmm7, %xmm4
movaps %xmm6, %xmm5
addps %xmm0, %xmm4
addps %xmm1, %xmm5
subps %xmm0, %xmm7
subps %xmm1, %xmm6
movaps %xmm4, TEMP(0)
movaps %xmm5, TEMP(1)
MOVUAPS 32(%eax), %xmm2
MOVUAPS 48(%eax), %xmm3
MOVUAPS 80(%eax), %xmm0
MOVUAPS 64(%eax), %xmm1
shufps $0x1b, %xmm0, %xmm0
shufps $0x1b, %xmm1, %xmm1
movaps %xmm2, %xmm5
movaps %xmm3, %xmm4
addps %xmm0, %xmm2
addps %xmm1, %xmm3
subps %xmm0, %xmm5
subps %xmm1, %xmm4
#if defined(PIC) && defined(__APPLE__)
mov GLOBAL_VAR_PTR(costab_mmxsse), %ecx
#else
lea GLOBAL_VAR(costab_mmxsse), %ecx
#endif
mulps (%ecx), %xmm7
mulps 16(%ecx), %xmm6
mulps 32(%ecx), %xmm5
mulps 48(%ecx), %xmm4
shufps $0x1b, %xmm2, %xmm2
shufps $0x1b, %xmm3, %xmm3
shufps $0x1b, %xmm4, %xmm4
shufps $0x1b, %xmm5, %xmm5
movaps TEMP(0), %xmm0
movaps TEMP(1), %xmm1
subps %xmm3, %xmm0
subps %xmm2, %xmm1
addps TEMP(0), %xmm3
addps TEMP(1), %xmm2
movaps %xmm3, TEMP(0)
movaps %xmm2, TEMP(1)
movaps %xmm6, %xmm2
movaps %xmm7, %xmm3
subps %xmm5, %xmm6
subps %xmm4, %xmm7
addps %xmm3, %xmm4
addps %xmm2, %xmm5
mulps 64(%ecx), %xmm0
mulps 80(%ecx), %xmm1
mulps 80(%ecx), %xmm6
mulps 64(%ecx), %xmm7
movaps TEMP(0), %xmm2
movaps TEMP(1), %xmm3
shufps $0x1b, %xmm3, %xmm3
shufps $0x1b, %xmm5, %xmm5
shufps $0x1b, %xmm1, %xmm1
shufps $0x1b, %xmm6, %xmm6
movaps %xmm0, TEMP(1)
subps %xmm3, %xmm2
subps %xmm1, %xmm0
addps TEMP(0), %xmm3
addps TEMP(1), %xmm1
movaps %xmm3, TEMP(0)
movaps %xmm1, TEMP(2)
movaps %xmm5, %xmm1
movaps %xmm4, %xmm5
movaps %xmm7, %xmm3
subps %xmm1, %xmm5
subps %xmm6, %xmm7
addps %xmm1, %xmm4
addps %xmm3, %xmm6
mulps 96(%ecx), %xmm2
mulps 96(%ecx), %xmm0
mulps 96(%ecx), %xmm5
mulps 96(%ecx), %xmm7
movaps %xmm2, TEMP(1)
movaps %xmm0, TEMP(3)
movaps %xmm4, %xmm2
movaps %xmm5, %xmm3
shufps $0x44, %xmm6, %xmm2
shufps $0xbb, %xmm7, %xmm5
shufps $0xbb, %xmm6, %xmm4
shufps $0x44, %xmm7, %xmm3
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
subps %xmm4, %xmm2
subps %xmm5, %xmm3
addps %xmm6, %xmm4
addps %xmm7, %xmm5
movaps 112(%ecx), %xmm0
movlhps %xmm0, %xmm0
mulps %xmm0, %xmm2
mulps %xmm0, %xmm3
movaps %xmm0, TEMP(4)
movaps %xmm4, %xmm6
movaps %xmm5, %xmm7
shufps $0x14, %xmm2, %xmm4
shufps $0xbe, %xmm2, %xmm6
shufps $0x14, %xmm3, %xmm5
shufps $0xbe, %xmm3, %xmm7
movaps %xmm5, TEMP(5)
movaps %xmm7, TEMP(7)
movaps TEMP(0), %xmm0
movaps TEMP(1), %xmm1
movaps %xmm0, %xmm2
movaps %xmm1, %xmm3
shufps $0x44, TEMP(2), %xmm2
shufps $0xbb, TEMP(3), %xmm1
shufps $0xbb, TEMP(2), %xmm0
shufps $0x44, TEMP(3), %xmm3
movaps %xmm2, %xmm5
movaps %xmm3, %xmm7
subps %xmm0, %xmm2
subps %xmm1, %xmm3
addps %xmm5, %xmm0
addps %xmm7, %xmm1
mulps TEMP(4), %xmm2
mulps TEMP(4), %xmm3
movaps %xmm0, %xmm5
movaps %xmm1, %xmm7
shufps $0x14, %xmm2, %xmm0
shufps $0xbe, %xmm2, %xmm5
shufps $0x14, %xmm3, %xmm1
shufps $0xbe, %xmm3, %xmm7
movaps %xmm0, TEMP(0)
movaps %xmm1, TEMP(1)
movaps %xmm5, TEMP(2)
movaps %xmm7, TEMP(3)
movss 120(%ecx), %xmm5
shufps $0x00, %xmm5, %xmm5
xorps LOCAL_VAR(pnpn), %xmm5
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps TEMP(5), %xmm4
unpckhps TEMP(5), %xmm0
unpcklps TEMP(7), %xmm6
unpckhps TEMP(7), %xmm1
movaps %xmm4, %xmm2
movaps %xmm6, %xmm3
unpcklps %xmm0, %xmm4
unpckhps %xmm0, %xmm2
unpcklps %xmm1, %xmm6
unpckhps %xmm1, %xmm3
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
subps %xmm2, %xmm0
subps %xmm3, %xmm1
addps %xmm2, %xmm4
addps %xmm3, %xmm6
mulps %xmm5, %xmm0
mulps %xmm5, %xmm1
movaps %xmm5, TEMP(5)
movaps %xmm4, %xmm5
movaps %xmm6, %xmm7
unpcklps %xmm0, %xmm4
unpckhps %xmm0, %xmm5
unpcklps %xmm1, %xmm6
unpckhps %xmm1, %xmm7
movaps TEMP(0), %xmm0
movaps TEMP(2), %xmm2
movaps %xmm4, TEMP(4)
movaps %xmm6, TEMP(6)
movaps %xmm0, %xmm4
movaps %xmm2, %xmm6
unpcklps TEMP(1), %xmm0
unpckhps TEMP(1), %xmm4
unpcklps TEMP(3), %xmm2
unpckhps TEMP(3), %xmm6
movaps %xmm0, %xmm1
movaps %xmm2, %xmm3
unpcklps %xmm4, %xmm0
unpckhps %xmm4, %xmm1
unpcklps %xmm6, %xmm2
unpckhps %xmm6, %xmm3
movaps %xmm0, %xmm4
movaps %xmm2, %xmm6
subps %xmm1, %xmm4
subps %xmm3, %xmm6
addps %xmm1, %xmm0
addps %xmm3, %xmm2
mulps TEMP(5), %xmm4
mulps TEMP(5), %xmm6
movaps %xmm0, %xmm1
movaps %xmm2, %xmm3
unpcklps %xmm4, %xmm0
unpckhps %xmm4, %xmm1
unpcklps %xmm6, %xmm2
unpckhps %xmm6, %xmm3
movaps %xmm0, TEMP(0)
movaps %xmm1, TEMP(1)
movaps %xmm2, TEMP(2)
movaps %xmm3, TEMP(3)
movaps %xmm5, TEMP(5)
movaps %xmm7, TEMP(7)
movss TEMP_BYTE(12), %xmm0
movss TEMP_BYTE(28), %xmm1
movss TEMP_BYTE(44), %xmm2
movss TEMP_BYTE(60), %xmm3
addss TEMP_BYTE(8), %xmm0
addss TEMP_BYTE(24), %xmm1
addss TEMP_BYTE(40), %xmm2
addss TEMP_BYTE(56), %xmm3
movss %xmm0, TEMP_BYTE(8)
movss %xmm1, TEMP_BYTE(24)
movss %xmm2, TEMP_BYTE(40)
movss %xmm3, TEMP_BYTE(56)
movss TEMP_BYTE(76), %xmm0
movss TEMP_BYTE(92), %xmm1
movss TEMP_BYTE(108), %xmm2
movss TEMP_BYTE(124), %xmm3
addss TEMP_BYTE(72), %xmm0
addss TEMP_BYTE(88), %xmm1
addss TEMP_BYTE(104), %xmm2
addss TEMP_BYTE(120), %xmm3
movss %xmm0, TEMP_BYTE(72)
movss %xmm1, TEMP_BYTE(88)
movss %xmm2, TEMP_BYTE(104)
movss %xmm3, TEMP_BYTE(120)
movaps TEMP_BYTE(16), %xmm1
movaps TEMP_BYTE(48), %xmm3
movaps TEMP_BYTE(80), %xmm5
movaps TEMP_BYTE(112), %xmm7
movaps %xmm1, %xmm0
movaps %xmm3, %xmm2
movaps %xmm5, %xmm4
movaps %xmm7, %xmm6
shufps $0x1e, %xmm0, %xmm0
shufps $0x1e, %xmm2, %xmm2
shufps $0x1e, %xmm4, %xmm4
shufps $0x1e, %xmm6, %xmm6
leal LOCAL_VAR(mask), %ecx
andps (%ecx), %xmm0
andps (%ecx), %xmm2
andps (%ecx), %xmm4
andps (%ecx), %xmm6
addps %xmm0, %xmm1
addps %xmm2, %xmm3
addps %xmm4, %xmm5
addps %xmm6, %xmm7
movaps TEMP_BYTE(32), %xmm2
movaps TEMP_BYTE(96), %xmm6
movaps %xmm2, %xmm0
movaps %xmm6, %xmm4
shufps $0x1e, %xmm0, %xmm0
shufps $0x1e, %xmm4, %xmm4
andps (%ecx), %xmm0
andps (%ecx), %xmm4
addps %xmm3, %xmm2
addps %xmm0, %xmm3
addps %xmm7, %xmm6
addps %xmm4, %xmm7
movaps TEMP_BYTE(0), %xmm0
movaps TEMP_BYTE(64), %xmm4
cvtps2pi %xmm0, %mm0
cvtps2pi %xmm1, %mm1
movhlps %xmm0, %xmm0
movhlps %xmm1, %xmm1
cvtps2pi %xmm0, %mm2
cvtps2pi %xmm1, %mm3
packssdw %mm2, %mm0
packssdw %mm3, %mm1
cvtps2pi %xmm2, %mm2
cvtps2pi %xmm3, %mm3
movhlps %xmm2, %xmm2
movhlps %xmm3, %xmm3
cvtps2pi %xmm2, %mm4
cvtps2pi %xmm3, %mm5
packssdw %mm4, %mm2
packssdw %mm5, %mm3
mov %ecx, TEMP_BYTE(0)
movl ARG(0), %ecx
movl ARG(1), %ebx
movd %mm0, %eax
movd %mm1, %edx
movw %ax, 512(%ecx)
movw %dx, 384(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, (%ecx)
movw %ax, (%ebx)
movw %dx, 128(%ebx)
movd %mm2, %eax
movd %mm3, %edx
movw %ax, 448(%ecx)
movw %dx, 320(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, 64(%ebx)
movw %dx, 192(%ebx)
psrlq $32, %mm0
psrlq $32, %mm1
movd %mm0, %eax
movd %mm1, %edx
movw %ax, 256(%ecx)
movw %dx, 128(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, 256(%ebx)
movw %dx, 384(%ebx)
psrlq $32, %mm2
psrlq $32, %mm3
movd %mm2, %eax
movd %mm3, %edx
movw %ax, 192(%ecx)
movw %dx, 64(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, 320(%ebx)
movw %dx, 448(%ebx)
mov TEMP_BYTE(0), %eax
movaps %xmm4, %xmm0
shufps $0x1e, %xmm0, %xmm0
movaps %xmm5, %xmm1
andps (%eax), %xmm0
addps %xmm6, %xmm4
addps %xmm7, %xmm5
addps %xmm1, %xmm6
addps %xmm0, %xmm7
cvtps2pi %xmm4, %mm0
cvtps2pi %xmm5, %mm1
movhlps %xmm4, %xmm4
movhlps %xmm5, %xmm5
cvtps2pi %xmm4, %mm2
cvtps2pi %xmm5, %mm3
packssdw %mm2, %mm0
packssdw %mm3, %mm1
cvtps2pi %xmm6, %mm2
cvtps2pi %xmm7, %mm3
movhlps %xmm6, %xmm6
movhlps %xmm7, %xmm7
cvtps2pi %xmm6, %mm4
cvtps2pi %xmm7, %mm5
packssdw %mm4, %mm2
packssdw %mm5, %mm3
movd %mm0, %eax
movd %mm2, %edx
movw %ax, 480(%ecx)
movw %dx, 416(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, 32(%ebx)
movw %dx, 96(%ebx)
psrlq $32, %mm0
psrlq $32, %mm2
movd %mm0, %eax
movd %mm2, %edx
movw %ax, 224(%ecx)
movw %dx, 160(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, 288(%ebx)
movw %dx, 352(%ebx)
movd %mm1, %eax
movd %mm3, %edx
movw %ax, 352(%ecx)
movw %dx, 288(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, 160(%ebx)
movw %dx, 224(%ebx)
psrlq $32, %mm1
psrlq $32, %mm3
movd %mm1, %eax
movd %mm3, %edx
movw %ax, 96(%ecx)
movw %dx, 32(%ecx)
shrl $16, %eax
shrl $16, %edx
movw %ax, 416(%ebx)
movw %dx, 480(%ebx)
popl %ebx
movl %ebp, %esp
popl %ebp
ret
#if defined(PIC) && defined(__APPLE__)
.section __IMPORT,__pointers,non_lazy_symbol_pointers
L_costab_mmxsse:
.indirect_symbol ASM_NAME(costab_mmxsse)
.long 0
#endif
NONEXEC_STACK

View File

@ -0,0 +1,417 @@
/*
dct64_sse_float: SSE optimized dct64 (float output version)
copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#define ARG(n) (8+n*4)(%ebp)
#define TEMP(n) (4+n*16)(%esp)
#define TEMP_BYTE(n) (4+n)(%esp)
/*
void dct64_real_sse(real *out0, real *out1, real *samples);
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN16
pnpn:
.long 0
.long -2147483648
.long 0
.long -2147483648
ALIGN16
mask:
.long -1
.long -1
.long -1
.long 0
.text
ALIGN16
.globl ASM_NAME(dct64_real_sse)
ASM_NAME(dct64_real_sse):
pushl %ebp
movl %esp, %ebp
andl $-16, %esp /* align the stack at 16 bytes */
subl $128, %esp /* reserve space for temporal store */
pushl %ebx
GET_GOT
movl ARG(2), %eax
MOVUAPS (%eax), %xmm7
MOVUAPS 16(%eax), %xmm6
MOVUAPS 112(%eax), %xmm0
MOVUAPS 96(%eax), %xmm1
shufps $0x1b, %xmm0, %xmm0
shufps $0x1b, %xmm1, %xmm1
movaps %xmm7, %xmm4
movaps %xmm6, %xmm5
addps %xmm0, %xmm4
addps %xmm1, %xmm5
subps %xmm0, %xmm7
subps %xmm1, %xmm6
movaps %xmm4, TEMP(0)
movaps %xmm5, TEMP(1)
MOVUAPS 32(%eax), %xmm2
MOVUAPS 48(%eax), %xmm3
MOVUAPS 80(%eax), %xmm0
MOVUAPS 64(%eax), %xmm1
shufps $0x1b, %xmm0, %xmm0
shufps $0x1b, %xmm1, %xmm1
movaps %xmm2, %xmm5
movaps %xmm3, %xmm4
addps %xmm0, %xmm2
addps %xmm1, %xmm3
subps %xmm0, %xmm5
subps %xmm1, %xmm4
#if defined(PIC) && defined(__APPLE__)
mov GLOBAL_VAR_PTR(costab_mmxsse), %eax
#else
lea GLOBAL_VAR(costab_mmxsse), %eax
#endif
mulps (%eax), %xmm7
mulps 16(%eax), %xmm6
mulps 32(%eax), %xmm5
mulps 48(%eax), %xmm4
shufps $0x1b, %xmm2, %xmm2
shufps $0x1b, %xmm3, %xmm3
shufps $0x1b, %xmm4, %xmm4
shufps $0x1b, %xmm5, %xmm5
movaps TEMP(0), %xmm0
movaps TEMP(1), %xmm1
subps %xmm3, %xmm0
subps %xmm2, %xmm1
addps TEMP(0), %xmm3
addps TEMP(1), %xmm2
movaps %xmm3, TEMP(0)
movaps %xmm2, TEMP(1)
movaps %xmm6, %xmm2
movaps %xmm7, %xmm3
subps %xmm5, %xmm6
subps %xmm4, %xmm7
addps %xmm3, %xmm4
addps %xmm2, %xmm5
mulps 64(%eax), %xmm0
mulps 80(%eax), %xmm1
mulps 80(%eax), %xmm6
mulps 64(%eax), %xmm7
movaps TEMP(0), %xmm2
movaps TEMP(1), %xmm3
shufps $0x1b, %xmm3, %xmm3
shufps $0x1b, %xmm5, %xmm5
shufps $0x1b, %xmm1, %xmm1
shufps $0x1b, %xmm6, %xmm6
movaps %xmm0, TEMP(1)
subps %xmm3, %xmm2
subps %xmm1, %xmm0
addps TEMP(0), %xmm3
addps TEMP(1), %xmm1
movaps %xmm3, TEMP(0)
movaps %xmm1, TEMP(2)
movaps %xmm5, %xmm1
movaps %xmm4, %xmm5
movaps %xmm7, %xmm3
subps %xmm1, %xmm5
subps %xmm6, %xmm7
addps %xmm1, %xmm4
addps %xmm3, %xmm6
mulps 96(%eax), %xmm2
mulps 96(%eax), %xmm0
mulps 96(%eax), %xmm5
mulps 96(%eax), %xmm7
movaps %xmm2, TEMP(1)
movaps %xmm0, TEMP(3)
movaps %xmm4, %xmm2
movaps %xmm5, %xmm3
shufps $0x44, %xmm6, %xmm2
shufps $0xbb, %xmm7, %xmm5
shufps $0xbb, %xmm6, %xmm4
shufps $0x44, %xmm7, %xmm3
movaps %xmm2, %xmm6
movaps %xmm3, %xmm7
subps %xmm4, %xmm2
subps %xmm5, %xmm3
addps %xmm6, %xmm4
addps %xmm7, %xmm5
movaps 112(%eax), %xmm0
movlhps %xmm0, %xmm0
mulps %xmm0, %xmm2
mulps %xmm0, %xmm3
movaps %xmm0, TEMP(4)
movaps %xmm4, %xmm6
movaps %xmm5, %xmm7
shufps $0x14, %xmm2, %xmm4
shufps $0xbe, %xmm2, %xmm6
shufps $0x14, %xmm3, %xmm5
shufps $0xbe, %xmm3, %xmm7
movaps %xmm5, TEMP(5)
movaps %xmm7, TEMP(7)
movaps TEMP(0), %xmm0
movaps TEMP(1), %xmm1
movaps %xmm0, %xmm2
movaps %xmm1, %xmm3
shufps $0x44, TEMP(2), %xmm2
shufps $0xbb, TEMP(3), %xmm1
shufps $0xbb, TEMP(2), %xmm0
shufps $0x44, TEMP(3), %xmm3
movaps %xmm2, %xmm5
movaps %xmm3, %xmm7
subps %xmm0, %xmm2
subps %xmm1, %xmm3
addps %xmm5, %xmm0
addps %xmm7, %xmm1
mulps TEMP(4), %xmm2
mulps TEMP(4), %xmm3
movaps %xmm0, %xmm5
movaps %xmm1, %xmm7
shufps $0x14, %xmm2, %xmm0
shufps $0xbe, %xmm2, %xmm5
shufps $0x14, %xmm3, %xmm1
shufps $0xbe, %xmm3, %xmm7
movaps %xmm0, TEMP(0)
movaps %xmm1, TEMP(1)
movaps %xmm5, TEMP(2)
movaps %xmm7, TEMP(3)
movss 120(%eax), %xmm5
shufps $0x00, %xmm5, %xmm5
xorps LOCAL_VAR(pnpn), %xmm5
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
unpcklps TEMP(5), %xmm4
unpckhps TEMP(5), %xmm0
unpcklps TEMP(7), %xmm6
unpckhps TEMP(7), %xmm1
movaps %xmm4, %xmm2
movaps %xmm6, %xmm3
unpcklps %xmm0, %xmm4
unpckhps %xmm0, %xmm2
unpcklps %xmm1, %xmm6
unpckhps %xmm1, %xmm3
movaps %xmm4, %xmm0
movaps %xmm6, %xmm1
subps %xmm2, %xmm0
subps %xmm3, %xmm1
addps %xmm2, %xmm4
addps %xmm3, %xmm6
mulps %xmm5, %xmm0
mulps %xmm5, %xmm1
movaps %xmm5, TEMP(5)
movaps %xmm4, %xmm5
movaps %xmm6, %xmm7
unpcklps %xmm0, %xmm4
unpckhps %xmm0, %xmm5
unpcklps %xmm1, %xmm6
unpckhps %xmm1, %xmm7
movaps TEMP(0), %xmm0
movaps TEMP(2), %xmm2
movaps %xmm4, TEMP(4)
movaps %xmm6, TEMP(6)
movaps %xmm0, %xmm4
movaps %xmm2, %xmm6
unpcklps TEMP(1), %xmm0
unpckhps TEMP(1), %xmm4
unpcklps TEMP(3), %xmm2
unpckhps TEMP(3), %xmm6
movaps %xmm0, %xmm1
movaps %xmm2, %xmm3
unpcklps %xmm4, %xmm0
unpckhps %xmm4, %xmm1
unpcklps %xmm6, %xmm2
unpckhps %xmm6, %xmm3
movaps %xmm0, %xmm4
movaps %xmm2, %xmm6
subps %xmm1, %xmm4
subps %xmm3, %xmm6
addps %xmm1, %xmm0
addps %xmm3, %xmm2
mulps TEMP(5), %xmm4
mulps TEMP(5), %xmm6
movaps %xmm0, %xmm1
movaps %xmm2, %xmm3
unpcklps %xmm4, %xmm0
unpckhps %xmm4, %xmm1
unpcklps %xmm6, %xmm2
unpckhps %xmm6, %xmm3
movaps %xmm0, TEMP(0)
movaps %xmm1, TEMP(1)
movaps %xmm2, TEMP(2)
movaps %xmm3, TEMP(3)
movaps %xmm5, TEMP(5)
movaps %xmm7, TEMP(7)
movss TEMP_BYTE(12), %xmm0
movss TEMP_BYTE(28), %xmm1
movss TEMP_BYTE(44), %xmm2
movss TEMP_BYTE(60), %xmm3
addss TEMP_BYTE(8), %xmm0
addss TEMP_BYTE(24), %xmm1
addss TEMP_BYTE(40), %xmm2
addss TEMP_BYTE(56), %xmm3
movss %xmm0, TEMP_BYTE(8)
movss %xmm1, TEMP_BYTE(24)
movss %xmm2, TEMP_BYTE(40)
movss %xmm3, TEMP_BYTE(56)
movss TEMP_BYTE(76), %xmm0
movss TEMP_BYTE(92), %xmm1
movss TEMP_BYTE(108), %xmm2
movss TEMP_BYTE(124), %xmm3
addss TEMP_BYTE(72), %xmm0
addss TEMP_BYTE(88), %xmm1
addss TEMP_BYTE(104), %xmm2
addss TEMP_BYTE(120), %xmm3
movss %xmm0, TEMP_BYTE(72)
movss %xmm1, TEMP_BYTE(88)
movss %xmm2, TEMP_BYTE(104)
movss %xmm3, TEMP_BYTE(120)
movaps TEMP_BYTE(16), %xmm1
movaps TEMP_BYTE(48), %xmm3
movaps TEMP_BYTE(80), %xmm5
movaps TEMP_BYTE(112), %xmm7
movaps %xmm1, %xmm0
movaps %xmm3, %xmm2
movaps %xmm5, %xmm4
movaps %xmm7, %xmm6
shufps $0x1e, %xmm0, %xmm0
shufps $0x1e, %xmm2, %xmm2
shufps $0x1e, %xmm4, %xmm4
shufps $0x1e, %xmm6, %xmm6
lea LOCAL_VAR(mask), %eax
andps (%eax), %xmm0
andps (%eax), %xmm2
andps (%eax), %xmm4
andps (%eax), %xmm6
addps %xmm0, %xmm1
addps %xmm2, %xmm3
addps %xmm4, %xmm5
addps %xmm6, %xmm7
movaps TEMP_BYTE(32), %xmm2
movaps TEMP_BYTE(96), %xmm6
movaps %xmm2, %xmm0
movaps %xmm6, %xmm4
shufps $0x1e, %xmm0, %xmm0
shufps $0x1e, %xmm4, %xmm4
andps (%eax), %xmm0
andps (%eax), %xmm4
addps %xmm3, %xmm2
addps %xmm0, %xmm3
addps %xmm7, %xmm6
addps %xmm4, %xmm7
movaps TEMP_BYTE(0), %xmm0
movaps TEMP_BYTE(64), %xmm4
movl ARG(0), %ecx
movl ARG(1), %ebx
movss %xmm0, 1024(%ecx)
movss %xmm2, 896(%ecx)
movss %xmm1, 768(%ecx)
movss %xmm3, 640(%ecx)
shufps $0xe1, %xmm0, %xmm0
shufps $0xe1, %xmm2, %xmm2
shufps $0xe1, %xmm1, %xmm1
shufps $0xe1, %xmm3, %xmm3
movss %xmm0, (%ecx)
movss %xmm0, (%ebx)
movss %xmm2, 128(%ebx)
movss %xmm1, 256(%ebx)
movss %xmm3, 384(%ebx)
movhlps %xmm0, %xmm0
movhlps %xmm2, %xmm2
movhlps %xmm1, %xmm1
movhlps %xmm3, %xmm3
movss %xmm0, 512(%ecx)
movss %xmm2, 384(%ecx)
movss %xmm1, 256(%ecx)
movss %xmm3, 128(%ecx)
shufps $0xe1, %xmm0, %xmm0
shufps $0xe1, %xmm2, %xmm2
shufps $0xe1, %xmm1, %xmm1
shufps $0xe1, %xmm3, %xmm3
movss %xmm0, 512(%ebx)
movss %xmm2, 640(%ebx)
movss %xmm1, 768(%ebx)
movss %xmm3, 896(%ebx)
movaps %xmm4, %xmm0
shufps $0x1e, %xmm0, %xmm0
movaps %xmm5, %xmm1
andps (%eax), %xmm0
addps %xmm6, %xmm4
addps %xmm7, %xmm5
addps %xmm1, %xmm6
addps %xmm0, %xmm7
movss %xmm4, 960(%ecx)
movss %xmm6, 832(%ecx)
movss %xmm5, 704(%ecx)
movss %xmm7, 576(%ecx)
movhlps %xmm4, %xmm0
movhlps %xmm6, %xmm1
movhlps %xmm5, %xmm2
movhlps %xmm7, %xmm3
movss %xmm0, 448(%ecx)
movss %xmm1, 320(%ecx)
movss %xmm2, 192(%ecx)
movss %xmm3, 64(%ecx)
shufps $0xe1, %xmm4, %xmm4
shufps $0xe1, %xmm6, %xmm6
shufps $0xe1, %xmm5, %xmm5
shufps $0xe1, %xmm7, %xmm7
movss %xmm4, 64(%ebx)
movss %xmm6, 192(%ebx)
movss %xmm5, 320(%ebx)
movss %xmm7, 448(%ebx)
shufps $0xe1, %xmm0, %xmm0
shufps $0xe1, %xmm1, %xmm1
shufps $0xe1, %xmm2, %xmm2
shufps $0xe1, %xmm3, %xmm3
movss %xmm0, 576(%ebx)
movss %xmm1, 704(%ebx)
movss %xmm2, 832(%ebx)
movss %xmm3, 960(%ebx)
popl %ebx
movl %ebp, %esp
popl %ebp
ret
#if defined(PIC) && defined(__APPLE__)
.section __IMPORT,__pointers,non_lazy_symbol_pointers
L_costab_mmxsse:
.indirect_symbol ASM_NAME(costab_mmxsse)
.long 0
#endif
NONEXEC_STACK

View File

@ -0,0 +1,464 @@
/*
dct64_x86_64: SSE optimized dct64 for x86-64
copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#ifdef IS_MSABI
/* short *out0 */
#define ARG0 %r9
/* short *out1 */
#define ARG1 %rdx
/* real *samples */
#define ARG2 %r8
#else
/* short *out0 */
#define ARG0 %rdi
/* short *out1 */
#define ARG1 %rsi
/* real *samples */
#define ARG2 %rdx
#endif
/*
void dct64_x86_64(short *out0, short *out1, real *samples);
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN32
ASM_NAME(costab_x86_64):
.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
.long 0
.text
ALIGN16
.globl ASM_NAME(dct64_x86_64)
ASM_NAME(dct64_x86_64):
#ifdef IS_MSABI /* should save xmm6-15 */
movq %rcx, ARG0
subq $168, %rsp /* stack alignment + 10 xmm registers */
movaps %xmm6, (%rsp)
movaps %xmm7, 16(%rsp)
movaps %xmm8, 32(%rsp)
movaps %xmm9, 48(%rsp)
movaps %xmm10, 64(%rsp)
movaps %xmm11, 80(%rsp)
movaps %xmm12, 96(%rsp)
movaps %xmm13, 112(%rsp)
movaps %xmm14, 128(%rsp)
movaps %xmm15, 144(%rsp)
#endif
leaq ASM_NAME(costab_x86_64)(%rip), %rcx
MOVUAPS (ARG2), %xmm15
MOVUAPS 16(ARG2), %xmm14
MOVUAPS 112(ARG2), %xmm0
MOVUAPS 96(ARG2), %xmm1
shufps $0x1b, %xmm0, %xmm0
shufps $0x1b, %xmm1, %xmm1
movaps %xmm15, %xmm8
movaps %xmm14, %xmm9
addps %xmm0, %xmm8
addps %xmm1, %xmm9
subps %xmm0, %xmm15
subps %xmm1, %xmm14
MOVUAPS 32(ARG2), %xmm13
MOVUAPS 48(ARG2), %xmm12
MOVUAPS 80(ARG2), %xmm0
MOVUAPS 64(ARG2), %xmm1
shufps $0x1b, %xmm0, %xmm0
shufps $0x1b, %xmm1, %xmm1
movaps %xmm13, %xmm10
movaps %xmm12, %xmm11
addps %xmm0, %xmm10
addps %xmm1, %xmm11
subps %xmm0, %xmm13
subps %xmm1, %xmm12
movaps (%rcx), %xmm0
movaps 16(%rcx), %xmm1
movaps 32(%rcx), %xmm2
movaps 48(%rcx), %xmm3
mulps %xmm0, %xmm15
mulps %xmm1, %xmm14
mulps %xmm2, %xmm13
mulps %xmm3, %xmm12
movaps 64(%rcx), %xmm0
movaps 80(%rcx), %xmm1
pshufd $0x1b, %xmm11, %xmm2
pshufd $0x1b, %xmm10, %xmm3
shufps $0x1b, %xmm13, %xmm13
shufps $0x1b, %xmm12, %xmm12
movaps %xmm8, %xmm11
movaps %xmm9, %xmm10
movaps %xmm14, %xmm4
movaps %xmm15, %xmm5
subps %xmm2, %xmm11
subps %xmm3, %xmm10
subps %xmm13, %xmm14
subps %xmm12, %xmm15
addps %xmm2, %xmm8
addps %xmm3, %xmm9
addps %xmm5, %xmm12
addps %xmm4, %xmm13
mulps %xmm0, %xmm11
mulps %xmm1, %xmm10
mulps %xmm1, %xmm14
mulps %xmm0, %xmm15
movaps 96(%rcx), %xmm0
pshufd $0x1b, %xmm9, %xmm1
pshufd $0x1b, %xmm13, %xmm2
shufps $0x1b, %xmm10, %xmm10
shufps $0x1b, %xmm14, %xmm14
movaps %xmm8, %xmm9
movaps %xmm12, %xmm13
movaps %xmm11, %xmm3
movaps %xmm15, %xmm4
subps %xmm1, %xmm9
subps %xmm2, %xmm13
subps %xmm10, %xmm11
subps %xmm14, %xmm15
addps %xmm1, %xmm8
addps %xmm2, %xmm12
addps %xmm3, %xmm10
addps %xmm4, %xmm14
mulps %xmm0, %xmm9
mulps %xmm0, %xmm13
mulps %xmm0, %xmm11
mulps %xmm0, %xmm15
movaps 112(%rcx), %xmm0
movaps %xmm0, %xmm1
movlhps %xmm1, %xmm1
movaps %xmm8, %xmm2
movaps %xmm9, %xmm3
shufps $0x44, %xmm10, %xmm2
shufps $0xbb, %xmm11, %xmm9
shufps $0xbb, %xmm10, %xmm8
shufps $0x44, %xmm11, %xmm3
movaps %xmm2, %xmm4
movaps %xmm3, %xmm5
subps %xmm8, %xmm2
subps %xmm9, %xmm3
addps %xmm4, %xmm8
addps %xmm5, %xmm9
mulps %xmm1, %xmm2
mulps %xmm1, %xmm3
movaps %xmm8, %xmm10
movaps %xmm9, %xmm11
shufps $0x14, %xmm2, %xmm8
shufps $0xbe, %xmm2, %xmm10
shufps $0x14, %xmm3, %xmm9
shufps $0xbe, %xmm3, %xmm11
movaps %xmm12, %xmm2
movaps %xmm13, %xmm3
shufps $0x44, %xmm14, %xmm2
shufps $0xbb, %xmm15, %xmm13
shufps $0xbb, %xmm14, %xmm12
shufps $0x44, %xmm15, %xmm3
movaps %xmm2, %xmm4
movaps %xmm3, %xmm5
subps %xmm12, %xmm2
subps %xmm13, %xmm3
addps %xmm4, %xmm12
addps %xmm5, %xmm13
mulps %xmm1, %xmm2
mulps %xmm1, %xmm3
movaps %xmm12, %xmm14
movaps %xmm13, %xmm15
shufps $0x14, %xmm2, %xmm12
shufps $0xbe, %xmm2, %xmm14
shufps $0x14, %xmm3, %xmm13
shufps $0xbe, %xmm3, %xmm15
shufps $0xaa, %xmm0, %xmm0
pcmpeqd %xmm1, %xmm1
pslld $31, %xmm1
psllq $32, %xmm1
xorps %xmm1, %xmm0
movaps %xmm8, %xmm1
movaps %xmm10, %xmm2
unpcklps %xmm9, %xmm8
unpckhps %xmm9, %xmm1
unpcklps %xmm11, %xmm10
unpckhps %xmm11, %xmm2
movaps %xmm8, %xmm3
movaps %xmm10, %xmm4
unpcklps %xmm1, %xmm8
unpckhps %xmm1, %xmm3
unpcklps %xmm2, %xmm10
unpckhps %xmm2, %xmm4
movaps %xmm8, %xmm1
movaps %xmm10, %xmm2
subps %xmm3, %xmm1
subps %xmm4, %xmm2
addps %xmm3, %xmm8
addps %xmm4, %xmm10
mulps %xmm0, %xmm1
mulps %xmm0, %xmm2
movaps %xmm8, %xmm9
movaps %xmm10, %xmm11
unpcklps %xmm1, %xmm8
unpckhps %xmm1, %xmm9
unpcklps %xmm2, %xmm10
unpckhps %xmm2, %xmm11
movaps %xmm12, %xmm1
movaps %xmm14, %xmm2
unpcklps %xmm13, %xmm12
unpckhps %xmm13, %xmm1
unpcklps %xmm15, %xmm14
unpckhps %xmm15, %xmm2
movaps %xmm12, %xmm3
movaps %xmm14, %xmm4
unpcklps %xmm1, %xmm12
unpckhps %xmm1, %xmm3
unpcklps %xmm2, %xmm14
unpckhps %xmm2, %xmm4
movaps %xmm12, %xmm1
movaps %xmm14, %xmm2
subps %xmm3, %xmm1
subps %xmm4, %xmm2
addps %xmm3, %xmm12
addps %xmm4, %xmm14
mulps %xmm0, %xmm1
mulps %xmm0, %xmm2
movaps %xmm12, %xmm13
movaps %xmm14, %xmm15
unpcklps %xmm1, %xmm12
unpckhps %xmm1, %xmm13
unpcklps %xmm2, %xmm14
unpckhps %xmm2, %xmm15
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
shufpd $0x2, %xmm8, %xmm0
shufpd $0x2, %xmm9, %xmm1
psrlq $32, %xmm0
psrlq $32, %xmm1
addps %xmm0, %xmm8
addps %xmm1, %xmm9
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
shufpd $0x2, %xmm10, %xmm0
shufpd $0x2, %xmm11, %xmm1
psrlq $32, %xmm0
psrlq $32, %xmm1
addps %xmm0, %xmm10
addps %xmm1, %xmm11
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
shufpd $0x2, %xmm12, %xmm0
shufpd $0x2, %xmm13, %xmm1
psrlq $32, %xmm0
psrlq $32, %xmm1
addps %xmm0, %xmm12
addps %xmm1, %xmm13
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
shufpd $0x2, %xmm14, %xmm0
shufpd $0x2, %xmm15, %xmm1
psrlq $32, %xmm0
psrlq $32, %xmm1
addps %xmm0, %xmm14
addps %xmm1, %xmm15
pshufd $0x78, %xmm9, %xmm0
pshufd $0x78, %xmm11, %xmm1
pshufd $0x78, %xmm13, %xmm2
pshufd $0x78, %xmm15, %xmm3
psrldq $4, %xmm0
psrldq $4, %xmm1
psrldq $4, %xmm2
psrldq $4, %xmm3
addps %xmm0, %xmm9
addps %xmm1, %xmm11
addps %xmm2, %xmm13
addps %xmm3, %xmm15
pshufd $0x78, %xmm10, %xmm0
pshufd $0x78, %xmm14, %xmm1
psrldq $4, %xmm0
psrldq $4, %xmm1
addps %xmm11, %xmm10
addps %xmm15, %xmm14
addps %xmm0, %xmm11
addps %xmm1, %xmm15
cvtps2dq %xmm8, %xmm8
cvtps2dq %xmm9, %xmm9
cvtps2dq %xmm10, %xmm10
cvtps2dq %xmm11, %xmm11
packssdw %xmm10, %xmm8
packssdw %xmm11, %xmm9
movd %xmm8, %eax
movd %xmm9, %ecx
movw %ax, 512(ARG0)
movw %cx, 384(ARG0)
shrl $16, %eax
shrl $16, %ecx
movw %ax, (ARG0)
movw %ax, (ARG1)
movw %cx, 128(ARG1)
movhlps %xmm8, %xmm0
movhlps %xmm9, %xmm1
movd %xmm0, %eax
movd %xmm1, %ecx
movw %ax, 448(ARG0)
movw %cx, 320(ARG0)
shrl $16, %eax
shrl $16, %ecx
movw %ax, 64(ARG1)
movw %cx, 192(ARG1)
pshuflw $0xee, %xmm8, %xmm2
pshuflw $0xee, %xmm9, %xmm3
movd %xmm2, %eax
movd %xmm3, %ecx
movw %ax, 256(ARG0)
movw %cx, 128(ARG0)
shrl $16, %eax
shrl $16, %ecx
movw %ax, 256(ARG1)
movw %cx, 384(ARG1)
pshuflw $0xee, %xmm0, %xmm0
pshuflw $0xee, %xmm1, %xmm1
movd %xmm0, %eax
movd %xmm1, %ecx
movw %ax, 192(ARG0)
movw %cx, 64(ARG0)
shrl $16, %eax
shrl $16, %ecx
movw %ax, 320(ARG1)
movw %cx, 448(ARG1)
movaps %xmm12, %xmm0
movaps %xmm13, %xmm1
movaps %xmm14, %xmm2
movaps %xmm15, %xmm3
shufps $0x1e, %xmm0, %xmm0
pslldq $4, %xmm0
psrldq $4, %xmm0
addps %xmm2, %xmm12
addps %xmm3, %xmm13
addps %xmm1, %xmm14
addps %xmm0, %xmm15
cvtps2dq %xmm12, %xmm12
cvtps2dq %xmm13, %xmm13
cvtps2dq %xmm14, %xmm14
cvtps2dq %xmm15, %xmm15
packssdw %xmm13, %xmm12
packssdw %xmm15, %xmm14
movd %xmm12, %eax
movd %xmm14, %ecx
movw %ax, 480(ARG0)
movw %cx, 416(ARG0)
shrl $16, %eax
shrl $16, %ecx
movw %ax, 32(ARG1)
movw %cx, 96(ARG1)
pshuflw $0xee, %xmm12, %xmm0
pshuflw $0xee, %xmm14, %xmm1
movd %xmm0, %eax
movd %xmm1, %ecx
movw %ax, 224(ARG0)
movw %cx, 160(ARG0)
shrl $16, %eax
shrl $16, %ecx
movw %ax, 288(ARG1)
movw %cx, 352(ARG1)
movhlps %xmm12, %xmm0
movhlps %xmm14, %xmm1
movd %xmm0, %eax
movd %xmm1, %ecx
movw %ax, 352(ARG0)
movw %cx, 288(ARG0)
shrl $16, %eax
shrl $16, %ecx
movw %ax, 160(ARG1)
movw %cx, 224(ARG1)
pshuflw $0xee, %xmm0, %xmm0
pshuflw $0xee, %xmm1, %xmm1
movd %xmm0, %eax
movd %xmm1, %ecx
movw %ax, 96(ARG0)
movw %cx, 32(ARG0)
shrl $16, %eax
shrl $16, %ecx
movw %ax, 416(ARG1)
movw %cx, 480(ARG1)
#ifdef IS_MSABI
movaps (%rsp), %xmm6
movaps 16(%rsp), %xmm7
movaps 32(%rsp), %xmm8
movaps 48(%rsp), %xmm9
movaps 64(%rsp), %xmm10
movaps 80(%rsp), %xmm11
movaps 96(%rsp), %xmm12
movaps 112(%rsp), %xmm13
movaps 128(%rsp), %xmm14
movaps 144(%rsp), %xmm15
addq $168, %rsp
#endif
ret
NONEXEC_STACK

View File

@ -0,0 +1,426 @@
/*
dct64_x86_64_float: SSE optimized dct64 for x86-64 (float output version)
copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
#ifdef IS_MSABI
/* short *out0 */
#define ARG0 %r9
/* short *out1 */
#define ARG1 %rdx
/* real *samples */
#define ARG2 %r8
#else
/* real *out0 */
#define ARG0 %rdi
/* real *out1 */
#define ARG1 %rsi
/* real *samples */
#define ARG2 %rdx
#endif
/*
void dct64_real_x86_64(real *out0, real *out1, real *samples);
*/
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN32
ASM_NAME(costab_x86_64):
.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
.long 0
.text
ALIGN16
.globl ASM_NAME(dct64_real_x86_64)
ASM_NAME(dct64_real_x86_64):
#ifdef IS_MSABI /* should save xmm6-15 */
movq %rcx, ARG0
subq $168, %rsp /* stack alignment + 10 xmm registers */
movaps %xmm6, (%rsp)
movaps %xmm7, 16(%rsp)
movaps %xmm8, 32(%rsp)
movaps %xmm9, 48(%rsp)
movaps %xmm10, 64(%rsp)
movaps %xmm11, 80(%rsp)
movaps %xmm12, 96(%rsp)
movaps %xmm13, 112(%rsp)
movaps %xmm14, 128(%rsp)
movaps %xmm15, 144(%rsp)
#endif
leaq ASM_NAME(costab_x86_64)(%rip), %rcx
MOVUAPS (ARG2), %xmm15
MOVUAPS 16(ARG2), %xmm14
MOVUAPS 112(ARG2), %xmm0
MOVUAPS 96(ARG2), %xmm1
shufps $0x1b, %xmm0, %xmm0
shufps $0x1b, %xmm1, %xmm1
movaps %xmm15, %xmm8
movaps %xmm14, %xmm9
addps %xmm0, %xmm8
addps %xmm1, %xmm9
subps %xmm0, %xmm15
subps %xmm1, %xmm14
MOVUAPS 32(ARG2), %xmm13
MOVUAPS 48(ARG2), %xmm12
MOVUAPS 80(ARG2), %xmm0
MOVUAPS 64(ARG2), %xmm1
shufps $0x1b, %xmm0, %xmm0
shufps $0x1b, %xmm1, %xmm1
movaps %xmm13, %xmm10
movaps %xmm12, %xmm11
addps %xmm0, %xmm10
addps %xmm1, %xmm11
subps %xmm0, %xmm13
subps %xmm1, %xmm12
movaps (%rcx), %xmm0
movaps 16(%rcx), %xmm1
movaps 32(%rcx), %xmm2
movaps 48(%rcx), %xmm3
mulps %xmm0, %xmm15
mulps %xmm1, %xmm14
mulps %xmm2, %xmm13
mulps %xmm3, %xmm12
movaps 64(%rcx), %xmm0
movaps 80(%rcx), %xmm1
pshufd $0x1b, %xmm11, %xmm2
pshufd $0x1b, %xmm10, %xmm3
shufps $0x1b, %xmm13, %xmm13
shufps $0x1b, %xmm12, %xmm12
movaps %xmm8, %xmm11
movaps %xmm9, %xmm10
movaps %xmm14, %xmm4
movaps %xmm15, %xmm5
subps %xmm2, %xmm11
subps %xmm3, %xmm10
subps %xmm13, %xmm14
subps %xmm12, %xmm15
addps %xmm2, %xmm8
addps %xmm3, %xmm9
addps %xmm5, %xmm12
addps %xmm4, %xmm13
mulps %xmm0, %xmm11
mulps %xmm1, %xmm10
mulps %xmm1, %xmm14
mulps %xmm0, %xmm15
movaps 96(%rcx), %xmm0
pshufd $0x1b, %xmm9, %xmm1
pshufd $0x1b, %xmm13, %xmm2
shufps $0x1b, %xmm10, %xmm10
shufps $0x1b, %xmm14, %xmm14
movaps %xmm8, %xmm9
movaps %xmm12, %xmm13
movaps %xmm11, %xmm3
movaps %xmm15, %xmm4
subps %xmm1, %xmm9
subps %xmm2, %xmm13
subps %xmm10, %xmm11
subps %xmm14, %xmm15
addps %xmm1, %xmm8
addps %xmm2, %xmm12
addps %xmm3, %xmm10
addps %xmm4, %xmm14
mulps %xmm0, %xmm9
mulps %xmm0, %xmm13
mulps %xmm0, %xmm11
mulps %xmm0, %xmm15
movaps 112(%rcx), %xmm0
movaps %xmm0, %xmm1
movlhps %xmm1, %xmm1
movaps %xmm8, %xmm2
movaps %xmm9, %xmm3
shufps $0x44, %xmm10, %xmm2
shufps $0xbb, %xmm11, %xmm9
shufps $0xbb, %xmm10, %xmm8
shufps $0x44, %xmm11, %xmm3
movaps %xmm2, %xmm4
movaps %xmm3, %xmm5
subps %xmm8, %xmm2
subps %xmm9, %xmm3
addps %xmm4, %xmm8
addps %xmm5, %xmm9
mulps %xmm1, %xmm2
mulps %xmm1, %xmm3
movaps %xmm8, %xmm10
movaps %xmm9, %xmm11
shufps $0x14, %xmm2, %xmm8
shufps $0xbe, %xmm2, %xmm10
shufps $0x14, %xmm3, %xmm9
shufps $0xbe, %xmm3, %xmm11
movaps %xmm12, %xmm2
movaps %xmm13, %xmm3
shufps $0x44, %xmm14, %xmm2
shufps $0xbb, %xmm15, %xmm13
shufps $0xbb, %xmm14, %xmm12
shufps $0x44, %xmm15, %xmm3
movaps %xmm2, %xmm4
movaps %xmm3, %xmm5
subps %xmm12, %xmm2
subps %xmm13, %xmm3
addps %xmm4, %xmm12
addps %xmm5, %xmm13
mulps %xmm1, %xmm2
mulps %xmm1, %xmm3
movaps %xmm12, %xmm14
movaps %xmm13, %xmm15
shufps $0x14, %xmm2, %xmm12
shufps $0xbe, %xmm2, %xmm14
shufps $0x14, %xmm3, %xmm13
shufps $0xbe, %xmm3, %xmm15
shufps $0xaa, %xmm0, %xmm0
pcmpeqd %xmm1, %xmm1
pslld $31, %xmm1
psllq $32, %xmm1
xorps %xmm1, %xmm0
movaps %xmm8, %xmm1
movaps %xmm10, %xmm2
unpcklps %xmm9, %xmm8
unpckhps %xmm9, %xmm1
unpcklps %xmm11, %xmm10
unpckhps %xmm11, %xmm2
movaps %xmm8, %xmm3
movaps %xmm10, %xmm4
unpcklps %xmm1, %xmm8
unpckhps %xmm1, %xmm3
unpcklps %xmm2, %xmm10
unpckhps %xmm2, %xmm4
movaps %xmm8, %xmm1
movaps %xmm10, %xmm2
subps %xmm3, %xmm1
subps %xmm4, %xmm2
addps %xmm3, %xmm8
addps %xmm4, %xmm10
mulps %xmm0, %xmm1
mulps %xmm0, %xmm2
movaps %xmm8, %xmm9
movaps %xmm10, %xmm11
unpcklps %xmm1, %xmm8
unpckhps %xmm1, %xmm9
unpcklps %xmm2, %xmm10
unpckhps %xmm2, %xmm11
movaps %xmm12, %xmm1
movaps %xmm14, %xmm2
unpcklps %xmm13, %xmm12
unpckhps %xmm13, %xmm1
unpcklps %xmm15, %xmm14
unpckhps %xmm15, %xmm2
movaps %xmm12, %xmm3
movaps %xmm14, %xmm4
unpcklps %xmm1, %xmm12
unpckhps %xmm1, %xmm3
unpcklps %xmm2, %xmm14
unpckhps %xmm2, %xmm4
movaps %xmm12, %xmm1
movaps %xmm14, %xmm2
subps %xmm3, %xmm1
subps %xmm4, %xmm2
addps %xmm3, %xmm12
addps %xmm4, %xmm14
mulps %xmm0, %xmm1
mulps %xmm0, %xmm2
movaps %xmm12, %xmm13
movaps %xmm14, %xmm15
unpcklps %xmm1, %xmm12
unpckhps %xmm1, %xmm13
unpcklps %xmm2, %xmm14
unpckhps %xmm2, %xmm15
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
shufpd $0x2, %xmm8, %xmm0
shufpd $0x2, %xmm9, %xmm1
psrlq $32, %xmm0
psrlq $32, %xmm1
addps %xmm0, %xmm8
addps %xmm1, %xmm9
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
shufpd $0x2, %xmm10, %xmm0
shufpd $0x2, %xmm11, %xmm1
psrlq $32, %xmm0
psrlq $32, %xmm1
addps %xmm0, %xmm10
addps %xmm1, %xmm11
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
shufpd $0x2, %xmm12, %xmm0
shufpd $0x2, %xmm13, %xmm1
psrlq $32, %xmm0
psrlq $32, %xmm1
addps %xmm0, %xmm12
addps %xmm1, %xmm13
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
shufpd $0x2, %xmm14, %xmm0
shufpd $0x2, %xmm15, %xmm1
psrlq $32, %xmm0
psrlq $32, %xmm1
addps %xmm0, %xmm14
addps %xmm1, %xmm15
pshufd $0x78, %xmm9, %xmm0
pshufd $0x78, %xmm11, %xmm1
pshufd $0x78, %xmm13, %xmm2
pshufd $0x78, %xmm15, %xmm3
psrldq $4, %xmm0
psrldq $4, %xmm1
psrldq $4, %xmm2
psrldq $4, %xmm3
addps %xmm0, %xmm9
addps %xmm1, %xmm11
addps %xmm2, %xmm13
addps %xmm3, %xmm15
pshufd $0x78, %xmm10, %xmm0
pshufd $0x78, %xmm14, %xmm1
psrldq $4, %xmm0
psrldq $4, %xmm1
addps %xmm11, %xmm10
addps %xmm15, %xmm14
addps %xmm0, %xmm11
addps %xmm1, %xmm15
movss %xmm8, 1024(ARG0)
movss %xmm10, 896(ARG0)
movss %xmm9, 768(ARG0)
movss %xmm11, 640(ARG0)
movhlps %xmm8, %xmm0
movhlps %xmm10, %xmm1
movhlps %xmm9, %xmm2
movhlps %xmm11, %xmm3
movss %xmm0, 512(ARG0)
movss %xmm1, 384(ARG0)
movss %xmm2, 256(ARG0)
movss %xmm3, 128(ARG0)
pshuflw $0xee, %xmm8, %xmm4
pshuflw $0xee, %xmm10, %xmm5
pshuflw $0xee, %xmm9, %xmm6
pshuflw $0xee, %xmm11, %xmm7
movss %xmm4, (ARG0)
movss %xmm4, (ARG1)
movss %xmm5, 128(ARG1)
movss %xmm6, 256(ARG1)
movss %xmm7, 384(ARG1)
pshuflw $0xee, %xmm0, %xmm0
pshuflw $0xee, %xmm1, %xmm1
pshuflw $0xee, %xmm2, %xmm2
pshuflw $0xee, %xmm3, %xmm3
movss %xmm0, 512(ARG1)
movss %xmm1, 640(ARG1)
movss %xmm2, 768(ARG1)
movss %xmm3, 896(ARG1)
pshufd $0x78, %xmm12, %xmm0
movaps %xmm13, %xmm1
psrldq $4, %xmm0
addps %xmm14, %xmm12
addps %xmm15, %xmm13
addps %xmm1, %xmm14
addps %xmm0, %xmm15
movss %xmm12, 960(ARG0)
movss %xmm14, 832(ARG0)
movss %xmm13, 704(ARG0)
movss %xmm15, 576(ARG0)
movhlps %xmm12, %xmm0
movhlps %xmm14, %xmm1
movhlps %xmm13, %xmm2
movhlps %xmm15, %xmm3
movss %xmm0, 448(ARG0)
movss %xmm1, 320(ARG0)
movss %xmm2, 192(ARG0)
movss %xmm3, 64(ARG0)
pshuflw $0xee, %xmm12, %xmm4
pshuflw $0xee, %xmm14, %xmm5
pshuflw $0xee, %xmm13, %xmm6
pshuflw $0xee, %xmm15, %xmm7
movss %xmm4, 64(ARG1)
movss %xmm5, 192(ARG1)
movss %xmm6, 320(ARG1)
movss %xmm7, 448(ARG1)
pshuflw $0xee, %xmm0, %xmm0
pshuflw $0xee, %xmm1, %xmm1
pshuflw $0xee, %xmm2, %xmm2
pshuflw $0xee, %xmm3, %xmm3
movss %xmm0, 576(ARG1)
movss %xmm1, 704(ARG1)
movss %xmm2, 832(ARG1)
movss %xmm3, 960(ARG1)
#ifdef IS_MSABI
movaps (%rsp), %xmm6
movaps 16(%rsp), %xmm7
movaps 32(%rsp), %xmm8
movaps 48(%rsp), %xmm9
movaps 64(%rsp), %xmm10
movaps 80(%rsp), %xmm11
movaps 96(%rsp), %xmm12
movaps 112(%rsp), %xmm13
movaps 128(%rsp), %xmm14
movaps 144(%rsp), %xmm15
addq $168, %rsp
#endif
ret
NONEXEC_STACK

View File

@ -0,0 +1,178 @@
/*
debug.h:
if DEBUG defined: debugging macro fprintf wrappers
else: macros defined to do nothing
That saves typing #ifdef DEBUG all the time and still preserves
lean code without debugging.
public domain (or LGPL / GPL, if you like that more;-)
generated by debugdef.pl, what was
trivially written by Thomas Orgis <thomas@orgis.org>
*/
#include "config.h"
/*
I could do that with variadic macros available:
#define sdebug(me, s) fprintf(stderr, "[location] " s "\n")
#define debug(me, s, ...) fprintf(stderr, "[location] " s "}n", __VA_ARGS__)
Variadic macros are a C99 feature...
Now just predefining stuff non-variadic for up to 15 arguments.
It's cumbersome to have them all with different names, though...
*/
#ifdef ME
#define DBGPRFX ME": "
#else
#define DBGPRFX ""
#endif
#ifdef DEBUG
#include <stdio.h>
#define debug(s) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__)
#define debug1(s, a) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a)
#define debug2(s, a, b) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b)
#define debug3(s, a, b, c) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c)
#define debug4(s, a, b, c, d) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d)
#define debug5(s, a, b, c, d, e) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e)
#define debug6(s, a, b, c, d, e, f) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f)
#define debug7(s, a, b, c, d, e, f, g) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g)
#define debug8(s, a, b, c, d, e, f, g, h) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
#define debug9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
#define debug10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
#define debug11(s, a, b, c, d, e, f, g, h, i, j, k) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k)
#define debug12(s, a, b, c, d, e, f, g, h, i, j, k, l) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l)
#define debug13(s, a, b, c, d, e, f, g, h, i, j, k, l, m) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m)
#define debug14(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n)
#define debug15(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
#else
#define debug(s)
#define debug1(s, a)
#define debug2(s, a, b)
#define debug3(s, a, b, c)
#define debug4(s, a, b, c, d)
#define debug5(s, a, b, c, d, e)
#define debug6(s, a, b, c, d, e, f)
#define debug7(s, a, b, c, d, e, f, g)
#define debug8(s, a, b, c, d, e, f, g, h)
#define debug9(s, a, b, c, d, e, f, g, h, i)
#define debug10(s, a, b, c, d, e, f, g, h, i, j)
#define debug11(s, a, b, c, d, e, f, g, h, i, j, k)
#define debug12(s, a, b, c, d, e, f, g, h, i, j, k, l)
#define debug13(s, a, b, c, d, e, f, g, h, i, j, k, l, m)
#define debug14(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n)
#define debug15(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
#endif
/* warning macros also here... */
#ifndef NO_WARNING
#define warning(s) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__)
#define warning1(s, a) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a)
#define warning2(s, a, b) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b)
#define warning3(s, a, b, c) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c)
#define warning4(s, a, b, c, d) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d)
#define warning5(s, a, b, c, d, e) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e)
#define warning6(s, a, b, c, d, e, f) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f)
#define warning7(s, a, b, c, d, e, f, g) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g)
#define warning8(s, a, b, c, d, e, f, g, h) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
#define warning9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
#define warning10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
#define warning11(s, a, b, c, d, e, f, g, h, i, j, k) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k)
#define warning12(s, a, b, c, d, e, f, g, h, i, j, k, l) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l)
#define warning13(s, a, b, c, d, e, f, g, h, i, j, k, l, m) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m)
#define warning14(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n)
#define warning15(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
#else
#define warning(s)
#define warning1(s, a)
#define warning2(s, a, b)
#define warning3(s, a, b, c)
#define warning4(s, a, b, c, d)
#define warning5(s, a, b, c, d, e)
#define warning6(s, a, b, c, d, e, f)
#define warning7(s, a, b, c, d, e, f, g)
#define warning8(s, a, b, c, d, e, f, g, h)
#define warning9(s, a, b, c, d, e, f, g, h, i)
#define warning10(s, a, b, c, d, e, f, g, h, i, j)
#define warning11(s, a, b, c, d, e, f, g, h, i, j, k)
#define warning12(s, a, b, c, d, e, f, g, h, i, j, k, l)
#define warning13(s, a, b, c, d, e, f, g, h, i, j, k, l, m)
#define warning14(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n)
#define warning15(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
#endif
/* error macros also here... */
#ifndef NO_ERROR
#define error(s) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__)
#define error1(s, a) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a)
#define error2(s, a, b) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b)
#define error3(s, a, b, c) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c)
#define error4(s, a, b, c, d) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d)
#define error5(s, a, b, c, d, e) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e)
#define error6(s, a, b, c, d, e, f) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f)
#define error7(s, a, b, c, d, e, f, g) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g)
#define error8(s, a, b, c, d, e, f, g, h) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
#define error9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
#define error10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
#define error11(s, a, b, c, d, e, f, g, h, i, j, k) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k)
#define error12(s, a, b, c, d, e, f, g, h, i, j, k, l) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l)
#define error13(s, a, b, c, d, e, f, g, h, i, j, k, l, m) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m)
#define error14(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n)
#define error15(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
#else
#define error(s)
#define error1(s, a)
#define error2(s, a, b)
#define error3(s, a, b, c)
#define error4(s, a, b, c, d)
#define error5(s, a, b, c, d, e)
#define error6(s, a, b, c, d, e, f)
#define error7(s, a, b, c, d, e, f, g)
#define error8(s, a, b, c, d, e, f, g, h)
#define error9(s, a, b, c, d, e, f, g, h, i)
#define error10(s, a, b, c, d, e, f, g, h, i, j)
#define error11(s, a, b, c, d, e, f, g, h, i, j, k)
#define error12(s, a, b, c, d, e, f, g, h, i, j, k, l)
#define error13(s, a, b, c, d, e, f, g, h, i, j, k, l, m)
#define error14(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n)
#define error15(s, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
#endif
/* ereturn macros also here... */
#ifndef NO_ERETURN
#define ereturn(rv, s) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__); return rv; }while(0)
#define ereturn1(rv, s, a) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a); return rv; }while(0)
#define ereturn2(rv, s, a, b) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b); return rv; }while(0)
#define ereturn3(rv, s, a, b, c) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c); return rv; }while(0)
#define ereturn4(rv, s, a, b, c, d) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d); return rv; }while(0)
#define ereturn5(rv, s, a, b, c, d, e) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e); return rv; }while(0)
#define ereturn6(rv, s, a, b, c, d, e, f) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f); return rv; }while(0)
#define ereturn7(rv, s, a, b, c, d, e, f, g) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g); return rv; }while(0)
#define ereturn8(rv, s, a, b, c, d, e, f, g, h) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h); return rv; }while(0)
#define ereturn9(rv, s, a, b, c, d, e, f, g, h, i) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i); return rv; }while(0)
#define ereturn10(rv, s, a, b, c, d, e, f, g, h, i, j) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j); return rv; }while(0)
#define ereturn11(rv, s, a, b, c, d, e, f, g, h, i, j, k) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k); return rv; }while(0)
#define ereturn12(rv, s, a, b, c, d, e, f, g, h, i, j, k, l) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l); return rv; }while(0)
#define ereturn13(rv, s, a, b, c, d, e, f, g, h, i, j, k, l, m) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m); return rv; }while(0)
#define ereturn14(rv, s, a, b, c, d, e, f, g, h, i, j, k, l, m, n) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n); return rv; }while(0)
#define ereturn15(rv, s, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) do{ fprintf(stderr, DBGPRFX"[" __FILE__ ":%i] ereturn: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); return rv; }while(0)
#else
#define ereturn(rv, s) return rv
#define ereturn1(rv, s, a) return rv
#define ereturn2(rv, s, a, b) return rv
#define ereturn3(rv, s, a, b, c) return rv
#define ereturn4(rv, s, a, b, c, d) return rv
#define ereturn5(rv, s, a, b, c, d, e) return rv
#define ereturn6(rv, s, a, b, c, d, e, f) return rv
#define ereturn7(rv, s, a, b, c, d, e, f, g) return rv
#define ereturn8(rv, s, a, b, c, d, e, f, g, h) return rv
#define ereturn9(rv, s, a, b, c, d, e, f, g, h, i) return rv
#define ereturn10(rv, s, a, b, c, d, e, f, g, h, i, j) return rv
#define ereturn11(rv, s, a, b, c, d, e, f, g, h, i, j, k) return rv
#define ereturn12(rv, s, a, b, c, d, e, f, g, h, i, j, k, l) return rv
#define ereturn13(rv, s, a, b, c, d, e, f, g, h, i, j, k, l, m) return rv
#define ereturn14(rv, s, a, b, c, d, e, f, g, h, i, j, k, l, m, n) return rv
#define ereturn15(rv, s, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) return rv
#endif

View File

@ -0,0 +1,285 @@
/*
decode.h: common definitions for decode functions
This file is strongly tied with optimize.h concerning the synth functions.
Perhaps one should restructure that a bit.
copyright 2007-8 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis, taking WRITE_SAMPLE from decode.c
*/
#ifndef MPG123_DECODE_H
#define MPG123_DECODE_H
/* Selection of class of output routines for basic format. */
#ifndef REAL_IS_FIXED
#define OUT_FORMATS 4 /* Basic output formats: 16bit, 8bit, real and s32 */
#else
#define OUT_FORMATS 2 /* Only up to 16bit */
#endif
#define OUT_16 0
#define OUT_8 1
/* Those are defined but not supported for fixed point decoding! */
#define OUT_REAL 2 /* Write a floating point sample (that is, one matching the internal real type). */
#define OUT_S32 3
#ifdef NO_NTOM
#define NTOM_MAX 1
#else
#define NTOM_MAX 8 /* maximum allowed factor for upsampling */
#define NTOM_MAX_FREQ 96000 /* maximum frequency to upsample to / downsample from */
#define NTOM_MUL (32768)
void ntom_set_ntom(mpg123_handle *fr, off_t num);
#endif
/* Let's collect all possible synth functions here, for an overview.
If they are actually defined and used depends on preprocessor machinery.
See synth.c and optimize.h for that, also some special C and assembler files. */
#ifndef NO_16BIT
/* The signed-16bit-producing variants. */
int synth_1to1 (real*, int, mpg123_handle*, int);
int synth_1to1_dither (real*, int, mpg123_handle*, int);
int synth_1to1_i386 (real*, int, mpg123_handle*, int);
int synth_1to1_i586 (real*, int, mpg123_handle*, int);
int synth_1to1_i586_dither(real*, int, mpg123_handle*, int);
int synth_1to1_mmx (real*, int, mpg123_handle*, int);
int synth_1to1_3dnow (real*, int, mpg123_handle*, int);
int synth_1to1_sse (real*, int, mpg123_handle*, int);
int synth_1to1_stereo_sse (real*, real*, mpg123_handle*);
int synth_1to1_3dnowext (real*, int, mpg123_handle*, int);
int synth_1to1_altivec (real*, int, mpg123_handle*, int);
int synth_1to1_stereo_altivec(real*, real*, mpg123_handle*);
int synth_1to1_x86_64 (real*, int, mpg123_handle*, int);
int synth_1to1_stereo_x86_64(real*, real*, mpg123_handle*);
int synth_1to1_avx (real*, int, mpg123_handle*, int);
int synth_1to1_stereo_avx (real*, real*, mpg123_handle*);
int synth_1to1_arm (real*, int, mpg123_handle*, int);
int synth_1to1_neon (real*, int, mpg123_handle*, int);
int synth_1to1_stereo_neon(real*, real*, mpg123_handle*);
int synth_1to1_neon64 (real*, int, mpg123_handle*, int);
int synth_1to1_stereo_neon64(real*, real*, mpg123_handle*);
/* This is different, special usage in layer3.c only.
Hence, the name... and now forget about it.
Never use it outside that special portion of code inside layer3.c! */
int absynth_1to1_i486(real*, int, mpg123_handle*, int);
/* These mono/stereo converters use one of the above for the grunt work. */
int synth_1to1_mono (real*, mpg123_handle*);
int synth_1to1_m2s(real*, mpg123_handle*);
/* Sample rate decimation comes in less flavours. */
#ifndef NO_DOWNSAMPLE
int synth_2to1 (real*, int, mpg123_handle*, int);
int synth_2to1_dither (real*, int, mpg123_handle*, int);
int synth_2to1_i386 (real*, int, mpg123_handle*, int);
int synth_2to1_mono (real*, mpg123_handle*);
int synth_2to1_m2s(real*, mpg123_handle*);
int synth_4to1 (real *,int, mpg123_handle*, int);
int synth_4to1_dither (real *,int, mpg123_handle*, int);
int synth_4to1_i386 (real*, int, mpg123_handle*, int);
int synth_4to1_mono (real*, mpg123_handle*);
int synth_4to1_m2s(real*, mpg123_handle*);
#endif
#ifndef NO_NTOM
/* NtoM is really just one implementation. */
int synth_ntom (real *,int, mpg123_handle*, int);
int synth_ntom_mono (real *, mpg123_handle *);
int synth_ntom_m2s (real *, mpg123_handle *);
#endif
#endif
#ifndef NO_8BIT
/* The 8bit-producing variants. */
/* There are direct 8-bit synths and wrappers over a possibly optimized 16bit one. */
int synth_1to1_8bit (real*, int, mpg123_handle*, int);
int synth_1to1_8bit_i386 (real*, int, mpg123_handle*, int);
#ifndef NO_16BIT
int synth_1to1_8bit_wrap (real*, int, mpg123_handle*, int);
int synth_1to1_8bit_mono (real*, mpg123_handle*);
#endif
int synth_1to1_8bit_m2s(real*, mpg123_handle*);
#ifndef NO_16BIT
int synth_1to1_8bit_wrap_mono (real*, mpg123_handle*);
int synth_1to1_8bit_wrap_m2s(real*, mpg123_handle*);
#endif
#ifndef NO_DOWNSAMPLE
int synth_2to1_8bit (real*, int, mpg123_handle*, int);
int synth_2to1_8bit_i386 (real*, int, mpg123_handle*, int);
int synth_2to1_8bit_mono (real*, mpg123_handle*);
int synth_2to1_8bit_m2s(real*, mpg123_handle*);
int synth_4to1_8bit (real*, int, mpg123_handle*, int);
int synth_4to1_8bit_i386 (real*, int, mpg123_handle*, int);
int synth_4to1_8bit_mono (real*, mpg123_handle*);
int synth_4to1_8bit_m2s(real*, mpg123_handle*);
#endif
#ifndef NO_NTOM
int synth_ntom_8bit (real*, int, mpg123_handle*, int);
int synth_ntom_8bit_mono (real*, mpg123_handle*);
int synth_ntom_8bit_m2s(real*, mpg123_handle*);
#endif
#endif
#ifndef REAL_IS_FIXED
#ifndef NO_REAL
/* The real-producing variants. */
int synth_1to1_real (real*, int, mpg123_handle*, int);
int synth_1to1_real_i386 (real*, int, mpg123_handle*, int);
int synth_1to1_real_sse (real*, int, mpg123_handle*, int);
int synth_1to1_real_stereo_sse (real*, real*, mpg123_handle*);
int synth_1to1_real_x86_64 (real*, int, mpg123_handle*, int);
int synth_1to1_real_stereo_x86_64(real*, real*, mpg123_handle*);
int synth_1to1_real_avx (real*, int, mpg123_handle*, int);
int synth_1to1_fltst_avx (real*, real*, mpg123_handle*);
int synth_1to1_real_altivec (real*, int, mpg123_handle*, int);
int synth_1to1_fltst_altivec(real*, real*, mpg123_handle*);
int synth_1to1_real_neon (real*, int, mpg123_handle*, int);
int synth_1to1_real_stereo_neon(real*, real*, mpg123_handle*);
int synth_1to1_real_neon64 (real*, int, mpg123_handle*, int);
int synth_1to1_fltst_neon64(real*, real*, mpg123_handle*);
int synth_1to1_real_mono (real*, mpg123_handle*);
int synth_1to1_real_m2s(real*, mpg123_handle*);
#ifndef NO_DOWNSAMPLE
int synth_2to1_real (real*, int, mpg123_handle*, int);
int synth_2to1_real_i386 (real*, int, mpg123_handle*, int);
int synth_2to1_real_mono (real*, mpg123_handle*);
int synth_2to1_real_m2s(real*, mpg123_handle*);
int synth_4to1_real (real*, int, mpg123_handle*, int);
int synth_4to1_real_i386 (real*, int, mpg123_handle*, int);
int synth_4to1_real_mono (real*, mpg123_handle*);
int synth_4to1_real_m2s(real*, mpg123_handle*);
#endif
#ifndef NO_NTOM
int synth_ntom_real (real*, int, mpg123_handle*, int);
int synth_ntom_real_mono (real*, mpg123_handle*);
int synth_ntom_real_m2s(real*, mpg123_handle*);
#endif
#endif
#ifndef NO_32BIT
/* 32bit integer */
int synth_1to1_s32 (real*, int, mpg123_handle*, int);
int synth_1to1_s32_i386 (real*, int, mpg123_handle*, int);
int synth_1to1_s32_sse (real*, int, mpg123_handle*, int);
int synth_1to1_s32_stereo_sse (real*, real*, mpg123_handle*);
int synth_1to1_s32_x86_64 (real*, int, mpg123_handle*, int);
int synth_1to1_s32_stereo_x86_64(real*, real*, mpg123_handle*);
int synth_1to1_s32_avx (real*, int, mpg123_handle*, int);
int synth_1to1_s32_stereo_avx (real*, real*, mpg123_handle*);
int synth_1to1_s32_altivec (real*, int, mpg123_handle*, int);
int synth_1to1_s32_stereo_altivec(real*, real*, mpg123_handle*);
int synth_1to1_s32_neon (real*, int, mpg123_handle*, int);
int synth_1to1_s32_stereo_neon(real*, real*, mpg123_handle*);
int synth_1to1_s32_neon64 (real*, int, mpg123_handle*, int);
int synth_1to1_s32st_neon64(real*, real*, mpg123_handle*);
int synth_1to1_s32_mono (real*, mpg123_handle*);
int synth_1to1_s32_m2s(real*, mpg123_handle*);
#ifndef NO_DOWNSAMPLE
int synth_2to1_s32 (real*, int, mpg123_handle*, int);
int synth_2to1_s32_i386 (real*, int, mpg123_handle*, int);
int synth_2to1_s32_mono (real*, mpg123_handle*);
int synth_2to1_s32_m2s(real*, mpg123_handle*);
int synth_4to1_s32 (real*, int, mpg123_handle*, int);
int synth_4to1_s32_i386 (real*, int, mpg123_handle*, int);
int synth_4to1_s32_mono (real*, mpg123_handle*);
int synth_4to1_s32_m2s(real*, mpg123_handle*);
#endif
#ifndef NO_NTOM
int synth_ntom_s32 (real*, int, mpg123_handle*, int);
int synth_ntom_s32_mono (real*, mpg123_handle*);
int synth_ntom_s32_m2s(real*, mpg123_handle*);
#endif
#endif
#endif /* FIXED */
/* Inside these synth functions, some dct64 variants may be used.
The special optimized ones that only appear in assembler code are not mentioned here.
And, generally, these functions are only employed in a matching synth function. */
void dct64 (real *,real *,real *);
void dct64_i386 (real *,real *,real *);
void dct64_altivec(real *,real *,real *);
void dct64_i486(int*, int* , real*); /* Yeah, of no use outside of synth_i486.c .*/
/* This is used by the layer 3 decoder, one generic function and 3DNow variants. */
void dct36 (real *,real *,real *,real *,real *);
void dct36_3dnow (real *,real *,real *,real *,real *);
void dct36_3dnowext(real *,real *,real *,real *,real *);
void dct36_x86_64 (real *,real *,real *,real *,real *);
void dct36_sse (real *,real *,real *,real *,real *);
void dct36_avx (real *,real *,real *,real *,real *);
void dct36_neon (real *,real *,real *,real *,real *);
void dct36_neon64 (real *,real *,real *,real *,real *);
/* Tools for NtoM resampling synth, defined in ntom.c . */
int synth_ntom_set_step(mpg123_handle *fr); /* prepare ntom decoding */
unsigned long ntom_val(mpg123_handle *fr, off_t frame); /* compute ntom_val for frame offset */
/* Frame and sample offsets. */
#ifndef NO_NTOM
/*
Outsamples of _this_ frame.
To be exact: The samples to be expected from the next frame decode (using the current ntom_val). When you already decoded _this_ frame, this is the number of samples to be expected from the next one.
*/
off_t ntom_frame_outsamples(mpg123_handle *fr);
/* Total out/insample offset. */
off_t ntom_frmouts(mpg123_handle *fr, off_t frame);
off_t ntom_ins2outs(mpg123_handle *fr, off_t ins);
off_t ntom_frameoff(mpg123_handle *fr, off_t soff);
#endif
/* Initialization of any static data that majy be needed at runtime.
Make sure you call these once before it is too late. */
#ifndef NO_LAYER3
void init_layer3(void);
real init_layer3_gainpow2(mpg123_handle *fr, int i);
void init_layer3_stuff(mpg123_handle *fr, real (*gainpow2)(mpg123_handle *fr, int i));
#endif
#ifndef NO_LAYER12
void init_layer12(void);
real* init_layer12_table(mpg123_handle *fr, real *table, int m);
void init_layer12_stuff(mpg123_handle *fr, real* (*init_table)(mpg123_handle *fr, real *table, int m));
#endif
void prepare_decode_tables(void);
extern real *pnts[5]; /* tabinit provides, dct64 needs */
/* Runtime (re)init functions; needed more often. */
void make_decode_tables(mpg123_handle *fr); /* For every volume change. */
/* Stuff needed after updating synth setup (see set_synth_functions()). */
#ifdef OPT_MMXORSSE
/* Special treatment for mmx-like decoders, these functions go into the slots below. */
void make_decode_tables_mmx(mpg123_handle *fr);
#ifndef NO_LAYER3
real init_layer3_gainpow2_mmx(mpg123_handle *fr, int i);
#endif
#ifndef NO_LAYER12
real* init_layer12_table_mmx(mpg123_handle *fr, real *table, int m);
#endif
#endif
#ifndef NO_8BIT
/* Needed when switching to 8bit output. */
int make_conv16to8_table(mpg123_handle *fr);
#endif
/* These are the actual workers.
They operate on the parsed frame data and handle decompression to audio samples.
The synth functions defined above are called from inside the layer handlers. */
#ifndef NO_LAYER3
int do_layer3(mpg123_handle *fr);
#endif
#ifndef NO_LAYER2
int do_layer2(mpg123_handle *fr);
#endif
#ifndef NO_LAYER1
int do_layer1(mpg123_handle *fr);
#endif
/* There's an 3DNow counterpart in asm. */
void do_equalizer(real *bandPtr,int channel, real equalizer[2][32]);
#endif

View File

@ -0,0 +1,3 @@
/* Hack to allow building the same code with and without libtool. */
#include "intsym.h"
#include "dither_impl.h"

View File

@ -0,0 +1,23 @@
/*
dither: Generate noise for dithering / noise shaping.
copyright 2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#ifndef MPG123_DITHER_H
#define MPG123_DITHER_H
#define DITHERSIZE 65536
enum mpg123_noise_type
{
mpg123_white_noise = 0
,mpg123_tpdf_noise
,mpg123_highpass_tpdf_noise
};
void mpg123_noise(float* table, size_t count, enum mpg123_noise_type noisetype);
void dither_table_init(float *dithertable);
#endif

View File

@ -0,0 +1,119 @@
/*
dither: Generate shaped noise for dithering
copyright 2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "config.h"
#include "compat.h"
#include "dither.h"
static const uint32_t init_seed = 2463534242UL;
#define LAP 100
/*
xorshift random number generator, with output scaling to [-0.5, 0.5]
This is the white noise...
See http://www.jstatsoft.org/v08/i14/paper on XOR shift random number generators.
*/
static float rand_xorshift32(uint32_t *seed)
{
union
{
uint32_t i;
float f;
} fi;
fi.i = *seed;
fi.i ^= (fi.i<<13);
fi.i ^= (fi.i>>17);
fi.i ^= (fi.i<<5);
*seed = fi.i;
/* scale the number to [-0.5, 0.5] */
#ifdef IEEE_FLOAT
fi.i = (fi.i>>9)|0x3f800000;
fi.f -= 1.5f;
#else
fi.f = (double)fi.i / 4294967295.0;
fi.f -= 0.5f;
#endif
return fi.f;
}
static void white_noise(float *table, size_t count)
{
size_t i;
uint32_t seed = init_seed;
for(i=0; i<count; ++i)
table[i] = rand_xorshift32(&seed);
}
static void tpdf_noise(float *table, size_t count)
{
size_t i;
uint32_t seed = init_seed;
for(i=0; i<count; ++i)
table[i] = rand_xorshift32(&seed) + rand_xorshift32(&seed);
}
static void highpass_tpdf_noise(float *table, size_t count)
{
size_t i;
uint32_t seed = init_seed;
/* Ensure some minimum lap for keeping the high-pass filter circular. */
size_t lap = count > 2*LAP ? LAP : count/2;
float input_noise;
float xv[9], yv[9];
for(i=0;i<9;i++)
{
xv[i] = yv[i] = 0.0f;
}
for(i=0;i<count+lap;i++)
{
if(i==count) seed=init_seed;
/* generate and add 2 random numbers, to make a TPDF noise distribution */
input_noise = rand_xorshift32(&seed) + rand_xorshift32(&seed);
/* apply 8th order Chebyshev high-pass IIR filter */
/* Coefficients are from http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html
Given parameters are: Chebyshev, Highpass, ripple=-1, order=8, samplerate=44100, corner1=19000 */
xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7]; xv[7] = xv[8];
xv[8] = input_noise / 1.382814179e+07;
yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7]; yv[7] = yv[8];
yv[8] = (xv[0] + xv[8]) - 8 * (xv[1] + xv[7]) + 28 * (xv[2] + xv[6])
- 56 * (xv[3] + xv[5]) + 70 * xv[4]
+ ( -0.6706204984 * yv[0]) + ( -5.3720827038 * yv[1])
+ (-19.0865382480 * yv[2]) + (-39.2831607860 * yv[3])
+ (-51.2308985070 * yv[4]) + (-43.3590135780 * yv[5])
+ (-23.2632305320 * yv[6]) + ( -7.2370122050 * yv[7]);
if(i>=lap) table[i-lap] = yv[8] * 3.0f;
}
}
void mpg123_noise(float* table, size_t count, enum mpg123_noise_type noisetype)
{
switch(noisetype)
{
case mpg123_white_noise: white_noise(table, count); break;
case mpg123_tpdf_noise: tpdf_noise(table, count); break;
case mpg123_highpass_tpdf_noise:
highpass_tpdf_noise(table, count);
break;
}
}
/* Generate white noise and shape it with a high pass filter. */
void dither_table_init(float *dithertable)
{
highpass_tpdf_noise(dithertable, DITHERSIZE);
}

View File

@ -0,0 +1,17 @@
/*
equalizer.c: equalizer settings
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
#include "mpg123lib_intern.h"
void do_equalizer(real *bandPtr,int channel, real equalizer[2][32])
{
int i;
for(i=0;i<32;i++)
bandPtr[i] = REAL_MUL(bandPtr[i], equalizer[channel][i]);
}

View File

@ -0,0 +1,70 @@
/*
equalizer_3dnow: 3DNow! optimized do_equalizer()
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by KIMURA Takuhiro
*/
#include "mangle.h"
.text
ALIGN4
.globl ASM_NAME(do_equalizer_3dnow)
/* .type ASM_NAME(do_equalizer_3dnow),@function */
/* void do_equalizer(real *bandPtr,int channel, real equalizer[2][32]); */
ASM_NAME(do_equalizer_3dnow):
pushl %esi
pushl %ebx
/* bandPtr */
movl 12(%esp),%ebx
/* channel */
movl 16(%esp),%ecx
xorl %edx,%edx
/* equalizer */
movl 20(%esp),%esi
sall $7,%ecx
ALIGN4
.L9:
movq (%ebx,%edx),%mm0
pfmul (%esi,%ecx),%mm0
movq 8(%ebx,%edx),%mm1
pfmul 8(%esi,%ecx),%mm1
movq %mm0,(%ebx,%edx)
movq 16(%ebx,%edx),%mm0
pfmul 16(%esi,%ecx),%mm0
movq %mm1,8(%ebx,%edx)
movq 24(%ebx,%edx),%mm1
pfmul 24(%esi,%ecx),%mm1
movq %mm0,16(%ebx,%edx)
movq 32(%ebx,%edx),%mm0
pfmul 32(%esi,%ecx),%mm0
movq %mm1,24(%ebx,%edx)
movq 40(%ebx,%edx),%mm1
pfmul 40(%esi,%ecx),%mm1
movq %mm0,32(%ebx,%edx)
movq 48(%ebx,%edx),%mm0
pfmul 48(%esi,%ecx),%mm0
movq %mm1,40(%ebx,%edx)
movq 56(%ebx,%edx),%mm1
pfmul 56(%esi,%ecx),%mm1
movq %mm0,48(%ebx,%edx)
movq %mm1,56(%ebx,%edx)
addl $64,%edx
addl $32,%ecx
cmpl $124,%edx
jle .L9
ALIGN4
popl %ebx
popl %esi
ret
NONEXEC_STACK

View File

@ -0,0 +1,112 @@
#include "mpg123lib_intern.h"
int mpg123_feature(const enum mpg123_feature_set key)
{
switch(key)
{
case MPG123_FEATURE_ABI_UTF8OPEN:
#ifdef WANT_WIN32_UNICODE
return 1;
#else
return 0;
#endif /* WANT_WIN32_UNICODE */
case MPG123_FEATURE_OUTPUT_8BIT:
#ifdef NO_8BIT
return 0;
#else
return 1;
#endif /* mpg123_output_8bit */
case MPG123_FEATURE_OUTPUT_16BIT:
#ifdef NO_16BIT
return 0;
#else
return 1;
#endif /* mpg123_output_16bit */
case MPG123_FEATURE_OUTPUT_32BIT:
#ifdef NO_32BIT
return 0;
#else
return 1;
#endif /* mpg123_output_32bit */
case MPG123_FEATURE_PARSE_ID3V2:
#ifdef NO_ID3V2
return 0;
#else
return 1;
#endif /* NO_ID3V2 */
case MPG123_FEATURE_DECODE_LAYER1:
#ifdef NO_LAYER1
return 0;
#else
return 1;
#endif /* NO_LAYER1 */
case MPG123_FEATURE_DECODE_LAYER2:
#ifdef NO_LAYER2
return 0;
#else
return 1;
#endif /* NO_LAYER2 */
case MPG123_FEATURE_DECODE_LAYER3:
#ifdef NO_LAYER3
return 0;
#else
return 1;
#endif /* NO_LAYER3 */
case MPG123_FEATURE_DECODE_ACCURATE:
#ifdef ACCURATE_ROUNDING
return 1;
#else
return 0;
#endif /* ACCURATE_ROUNDING */
case MPG123_FEATURE_DECODE_DOWNSAMPLE:
#ifdef NO_DOWNSAMPLE
return 0;
#else
return 1;
#endif /* NO_DOWNSAMPLE */
case MPG123_FEATURE_DECODE_NTOM:
#ifdef NO_NTOM
return 0;
#else
return 1;
#endif /* NO_NTOM */
case MPG123_FEATURE_PARSE_ICY:
#ifdef NO_ICY
return 0;
#else
return 1;
#endif /* NO_ICY */
case MPG123_FEATURE_INDEX:
#ifdef FRAME_INDEX
return 1;
#else
return 0;
#endif /* FRAME_INDEX */
case MPG123_FEATURE_TIMEOUT_READ:
#ifdef TIMEOUT_READ
return 1;
#else
return 0;
#endif
case MPG123_FEATURE_EQUALIZER:
#ifndef NO_EQUALIZER
return 1;
#else
return 0;
#endif
default: return 0;
}
}

View File

@ -0,0 +1,135 @@
/*
libmpg123: MPEG Audio Decoder library
separate header just for audio format definitions not tied to
library code
copyright 1995-2015 by the mpg123 project
free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
*/
#ifndef MPG123_ENC_H
#define MPG123_ENC_H
/** \file fmt123.h Audio format definitions. */
/** \defgroup mpg123_enc mpg123 PCM sample encodings
* These are definitions for audio formats used by libmpg123 and
* libout123.
*
* @{
*/
/** An enum over all sample types possibly known to mpg123.
* The values are designed as bit flags to allow bitmasking for encoding
* families.
* This is also why the enum is not used as type for actual encoding variables,
* plain integers (at least 16 bit, 15 bit being used) cover the possible
* combinations of these flags.
*
* Note that (your build of) libmpg123 does not necessarily support all these.
* Usually, you can expect the 8bit encodings and signed 16 bit.
* Also 32bit float will be usual beginning with mpg123-1.7.0 .
* What you should bear in mind is that (SSE, etc) optimized routines may be
* absent for some formats. We do have SSE for 16, 32 bit and float, though.
* 24 bit integer is done via postprocessing of 32 bit output -- just cutting
* the last byte, no rounding, even. If you want better, do it yourself.
*
* All formats are in native byte order. If you need different endinaness, you
* can simply postprocess the output buffers (libmpg123 wouldn't do anything
* else). The macro MPG123_SAMPLESIZE() can be helpful there.
*/
enum mpg123_enc_enum
{
/* 0000 0000 0000 1111 Some 8 bit integer encoding. */
MPG123_ENC_8 = 0x00f
/* 0000 0000 0100 0000 Some 16 bit integer encoding. */
, MPG123_ENC_16 = 0x040
/* 0100 0000 0000 0000 Some 24 bit integer encoding. */
, MPG123_ENC_24 = 0x4000
/* 0000 0001 0000 0000 Some 32 bit integer encoding. */
, MPG123_ENC_32 = 0x100
/* 0000 0000 1000 0000 Some signed integer encoding. */
, MPG123_ENC_SIGNED = 0x080
/* 0000 1110 0000 0000 Some float encoding. */
, MPG123_ENC_FLOAT = 0xe00
/* 0000 0000 1101 0000 signed 16 bit */
, MPG123_ENC_SIGNED_16 = (MPG123_ENC_16|MPG123_ENC_SIGNED|0x10)
/* 0000 0000 0110 0000 unsigned 16 bit */
, MPG123_ENC_UNSIGNED_16 = (MPG123_ENC_16|0x20)
/* 0000 0000 0000 0001 unsigned 8 bit */
, MPG123_ENC_UNSIGNED_8 = 0x01
/* 0000 0000 1000 0010 signed 8 bit */
, MPG123_ENC_SIGNED_8 = (MPG123_ENC_SIGNED|0x02)
/* 0000 0000 0000 0100 ulaw 8 bit */
, MPG123_ENC_ULAW_8 = 0x04
/* 0000 0000 0000 1000 alaw 8 bit */
, MPG123_ENC_ALAW_8 = 0x08
/* 0001 0001 1000 0000 signed 32 bit */
, MPG123_ENC_SIGNED_32 = MPG123_ENC_32|MPG123_ENC_SIGNED|0x1000
/* 0010 0001 0000 0000 unsigned 32 bit */
, MPG123_ENC_UNSIGNED_32 = MPG123_ENC_32|0x2000
/* 0101 0000 1000 0000 signed 24 bit */
, MPG123_ENC_SIGNED_24 = MPG123_ENC_24|MPG123_ENC_SIGNED|0x1000
/* 0110 0000 0000 0000 unsigned 24 bit */
, MPG123_ENC_UNSIGNED_24 = MPG123_ENC_24|0x2000
/* 0000 0010 0000 0000 32bit float */
, MPG123_ENC_FLOAT_32 = 0x200
/* 0000 0100 0000 0000 64bit float */
, MPG123_ENC_FLOAT_64 = 0x400
/* Any possibly known encoding from the list above. */
, MPG123_ENC_ANY = ( MPG123_ENC_SIGNED_16 | MPG123_ENC_UNSIGNED_16
| MPG123_ENC_UNSIGNED_8 | MPG123_ENC_SIGNED_8
| MPG123_ENC_ULAW_8 | MPG123_ENC_ALAW_8
| MPG123_ENC_SIGNED_32 | MPG123_ENC_UNSIGNED_32
| MPG123_ENC_SIGNED_24 | MPG123_ENC_UNSIGNED_24
| MPG123_ENC_FLOAT_32 | MPG123_ENC_FLOAT_64 )
};
/** Get size of one PCM sample with given encoding.
* This is included both in libmpg123 and libout123. Both offer
* an API function to provide the macro results from library
* compile-time, not that of you application. This most likely
* does not matter as I do not expect any fresh PCM sample
* encoding to appear. But who knows? Perhaps the encoding type
* will be abused for funny things in future, not even plain PCM.
* And, by the way: Thomas really likes the ?: operator.
* \param enc the encoding (mpg123_enc_enum value)
* \return size of one sample in bytes
*/
#define MPG123_SAMPLESIZE(enc) ( \
(enc) & MPG123_ENC_8 \
? 1 \
: ( (enc) & MPG123_ENC_16 \
? 2 \
: ( (enc) & MPG123_ENC_24 \
? 3 \
: ( ( (enc) & MPG123_ENC_32 \
|| (enc) == MPG123_ENC_FLOAT_32 ) \
? 4 \
: ( (enc) == MPG123_ENC_FLOAT_64 \
? 8 \
: 0 \
) ) ) ) )
/** Structure defining an audio format.
* Providing the members as individual function arguments to define a certain
* output format is easy enough. This struct makes is more comfortable to deal
* with a list of formats.
* Negative values for the members might be used to communicate use of default
* values.
*/
struct mpg123_fmt
{
long rate; /**< sampling rate in Hz */
int channels; /**< channel count */
/** encoding code, can be single value or bitwise or of members of
* mpg123_enc_enum */
int encoding;
};
/* @} */
#endif

View File

@ -0,0 +1,683 @@
/*
format:routines to deal with audio (output) format
copyright 2008-14 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis, starting with parts of the old audio.c, with only faintly manage to show now
A Major change from mpg123 <= 1.18 is that all encodings are only really
disabled when done so via specific build configuration. Otherwise, the
missing support of decoders to produce a certain format is augmented by
postprocessing that converts the samples. This means happily creating
data with higher resolution from less accurate decoder output.
The main point is to still offer float encoding when the decoding core uses
a fixed point representation that has only 16 bit output. Actually, that's
the only point: A fixed-point build needs to create float from 16 bit, also
32 or 24 bit from the same source. That's all there is to it: Everything else
is covered by fallback synth functions. It may be a further step to check if
there are cases where conversion in postprocessing works well enough to omit
a certain specialized decoder ... but usually, they are justified by some
special way to get from float to integer to begin with.
I won't cover the case of faking double output with float/s16 decoders here.
Double precision output is a thing for experimental builds anyway. Mostly
theoretical and without a point.
*/
#include "mpg123lib_intern.h"
#include "debug.h"
/* static int chans[NUM_CHANNELS] = { 1 , 2 }; */
static const long my_rates[MPG123_RATES] = /* only the standard rates */
{
8000, 11025, 12000,
16000, 22050, 24000,
32000, 44100, 48000,
};
static const int my_encodings[MPG123_ENCODINGS] =
{
MPG123_ENC_SIGNED_16,
MPG123_ENC_UNSIGNED_16,
MPG123_ENC_SIGNED_32,
MPG123_ENC_UNSIGNED_32,
MPG123_ENC_SIGNED_24,
MPG123_ENC_UNSIGNED_24,
/* Floating point range, see below. */
MPG123_ENC_FLOAT_32,
MPG123_ENC_FLOAT_64,
/* 8 bit range, see below. */
MPG123_ENC_SIGNED_8,
MPG123_ENC_UNSIGNED_8,
MPG123_ENC_ULAW_8,
MPG123_ENC_ALAW_8
};
/* Make that match the above table.
And yes, I still don't like this kludgy stuff. */
/* range[0] <= i < range[1] for forced floating point */
static const int enc_float_range[2] = { 6, 8 };
/* same for 8 bit encodings */
static const int enc_8bit_range[2] = { 8, 12 };
/*
Only one type of float is supported.
Actually, double is a very special experimental case not occuring in normal
builds. Might actually get rid of it.
Remember here: Also with REAL_IS_FIXED, I want to be able to produce float
output (f32) via post-processing.
*/
# ifdef REAL_IS_DOUBLE
# define MPG123_FLOAT_ENC MPG123_ENC_FLOAT_64
# else
# define MPG123_FLOAT_ENC MPG123_ENC_FLOAT_32
# endif
/* The list of actually possible encodings. */
static const int good_encodings[] =
{
#ifndef NO_16BIT
MPG123_ENC_SIGNED_16,
MPG123_ENC_UNSIGNED_16,
#endif
#ifndef NO_32BIT
MPG123_ENC_SIGNED_32,
MPG123_ENC_UNSIGNED_32,
MPG123_ENC_SIGNED_24,
MPG123_ENC_UNSIGNED_24,
#endif
#ifndef NO_REAL
MPG123_FLOAT_ENC,
#endif
#ifndef NO_8BIT
MPG123_ENC_SIGNED_8,
MPG123_ENC_UNSIGNED_8,
MPG123_ENC_ULAW_8,
MPG123_ENC_ALAW_8
#endif
};
/* Check if encoding is a valid one in this build.
...lazy programming: linear search. */
static int good_enc(const int enc)
{
size_t i;
for(i=0; i<sizeof(good_encodings)/sizeof(int); ++i)
if(enc == good_encodings[i]) return TRUE;
return FALSE;
}
void attribute_align_arg mpg123_rates(const long **list, size_t *number)
{
if(list != NULL) *list = my_rates;
if(number != NULL) *number = sizeof(my_rates)/sizeof(long);
}
/* Now that's a bit tricky... One build of the library knows only a subset of the encodings. */
void attribute_align_arg mpg123_encodings(const int **list, size_t *number)
{
if(list != NULL) *list = good_encodings;
if(number != NULL) *number = sizeof(good_encodings)/sizeof(int);
}
int attribute_align_arg mpg123_encsize(int encoding)
{
return MPG123_SAMPLESIZE(encoding);
}
/* char audio_caps[NUM_CHANNELS][MPG123_RATES+1][MPG123_ENCODINGS]; */
static int rate2num(mpg123_pars *mp, long r)
{
int i;
for(i=0;i<MPG123_RATES;i++) if(my_rates[i] == r) return i;
#ifndef NO_NTOM
if(mp && mp->force_rate != 0 && mp->force_rate == r) return MPG123_RATES;
#endif
return -1;
}
static int enc2num(int encoding)
{
int i;
for(i=0;i<MPG123_ENCODINGS;++i)
if(my_encodings[i] == encoding) return i;
return -1;
}
static int cap_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2)
{
int i;
int c = nf->channels-1;
int rn = rate2num(&fr->p, nf->rate);
if(rn >= 0) for(i=f0;i<f2;i++)
{
if(fr->p.audio_caps[c][rn][i])
{
nf->encoding = my_encodings[i];
return 1;
}
}
return 0;
}
static int freq_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2)
{
nf->rate = frame_freq(fr)>>fr->p.down_sample;
if(cap_fit(fr,nf,f0,f2)) return 1;
if(fr->p.flags & MPG123_AUTO_RESAMPLE)
{
nf->rate>>=1;
if(cap_fit(fr,nf,f0,f2)) return 1;
nf->rate>>=1;
if(cap_fit(fr,nf,f0,f2)) return 1;
}
#ifndef NO_NTOM
/* If nothing worked, try the other rates, only without constrains from user.
In case you didn't guess: We enable flexible resampling if we find a working rate. */
if( fr->p.flags & MPG123_AUTO_RESAMPLE &&
!fr->p.force_rate && fr->p.down_sample == 0)
{
int i;
int c = nf->channels-1;
int rn = rate2num(&fr->p, frame_freq(fr));
int rrn;
if(rn < 0) return 0;
/* Try higher rates first. */
for(i=f0;i<f2;i++) for(rrn=rn+1; rrn<MPG123_RATES; ++rrn)
if(fr->p.audio_caps[c][rrn][i])
{
nf->rate = my_rates[rrn];
nf->encoding = my_encodings[i];
return 1;
}
/* Then lower rates. */
for(i=f0;i<f2;i++) for(rrn=rn-1; rrn>=0; --rrn)
if(fr->p.audio_caps[c][rrn][i])
{
nf->rate = my_rates[rrn];
nf->encoding = my_encodings[i];
return 1;
}
}
#endif
return 0;
}
/* match constraints against supported audio formats, store possible setup in frame
return: -1: error; 0: no format change; 1: format change */
int frame_output_format(mpg123_handle *fr)
{
struct audioformat nf;
int f0=0;
int f2=MPG123_ENCODINGS; /* Omit the 32bit and float encodings. */
mpg123_pars *p = &fr->p;
/* initialize new format, encoding comes later */
nf.channels = fr->stereo;
/* All this forcing should be removed in favour of the capabilities table... */
if(p->flags & MPG123_FORCE_8BIT)
{
f0 = enc_8bit_range[0];
f2 = enc_8bit_range[1];
}
if(p->flags & MPG123_FORCE_FLOAT)
{
f0 = enc_float_range[0];
f2 = enc_float_range[1];
}
/* force stereo is stronger */
if(p->flags & MPG123_FORCE_MONO) nf.channels = 1;
if(p->flags & MPG123_FORCE_STEREO) nf.channels = 2;
#ifndef NO_NTOM
if(p->force_rate)
{
nf.rate = p->force_rate;
if(cap_fit(fr,&nf,f0,2)) goto end; /* 16bit encodings */
if(cap_fit(fr,&nf,f0<=2 ? 2 : f0,f2)) goto end; /* 8bit encodings */
/* try again with different stereoness */
if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1;
else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2;
if(cap_fit(fr,&nf,f0,2)) goto end; /* 16bit encodings */
if(cap_fit(fr,&nf,f0<=2 ? 2 : f0,f2)) goto end; /* 8bit encodings */
if(NOQUIET)
error3( "Unable to set up output format! Constraints: %s%s%liHz.",
( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
(p->flags & MPG123_FORCE_MONO ? "mono, " : "") ),
(p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""),
p->force_rate );
/* if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */
fr->err = MPG123_BAD_OUTFORMAT;
return -1;
}
#endif
if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */
if(freq_fit(fr, &nf, f0<=2 ? 2 : f0, f2)) goto end; /* ... 8bit */
/* try again with different stereoness */
if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1;
else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2;
if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */
if(freq_fit(fr, &nf, f0<=2 ? 2 : f0, f2)) goto end; /* ... 8bit */
/* Here is the _bad_ end. */
if(NOQUIET)
{
error5( "Unable to set up output format! Constraints: %s%s%li, %li or %liHz.",
( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
(p->flags & MPG123_FORCE_MONO ? "mono, " : "") ),
(p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""),
frame_freq(fr), frame_freq(fr)>>1, frame_freq(fr)>>2 );
}
/* if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */
fr->err = MPG123_BAD_OUTFORMAT;
return -1;
end: /* Here is the _good_ end. */
/* we had a successful match, now see if there's a change */
if(nf.rate == fr->af.rate && nf.channels == fr->af.channels && nf.encoding == fr->af.encoding)
{
debug2("Old format with %i channels, and FORCE_MONO=%li", nf.channels, p->flags & MPG123_FORCE_MONO);
return 0; /* the same format as before */
}
else /* a new format */
{
debug1("New format with %i channels!", nf.channels);
fr->af.rate = nf.rate;
fr->af.channels = nf.channels;
fr->af.encoding = nf.encoding;
/* Cache the size of one sample in bytes, for ease of use. */
fr->af.encsize = mpg123_encsize(fr->af.encoding);
if(fr->af.encsize < 1)
{
if(NOQUIET) error1("Some unknown encoding??? (%i)", fr->af.encoding);
fr->err = MPG123_BAD_OUTFORMAT;
return -1;
}
/* Set up the decoder synth format. Might differ. */
#ifdef NO_SYNTH32
/* Without high-precision synths, 16 bit signed is the basis for
everything higher than 8 bit. */
if(fr->af.encsize > 2)
fr->af.dec_enc = MPG123_ENC_SIGNED_16;
else
{
#endif
switch(fr->af.encoding)
{
#ifndef NO_32BIT
case MPG123_ENC_SIGNED_24:
case MPG123_ENC_UNSIGNED_24:
case MPG123_ENC_UNSIGNED_32:
fr->af.dec_enc = MPG123_ENC_SIGNED_32;
break;
#endif
#ifndef NO_16BIT
case MPG123_ENC_UNSIGNED_16:
fr->af.dec_enc = MPG123_ENC_SIGNED_16;
break;
#endif
default:
fr->af.dec_enc = fr->af.encoding;
}
#ifdef NO_SYNTH32
}
#endif
fr->af.dec_encsize = mpg123_encsize(fr->af.dec_enc);
return 1;
}
}
int attribute_align_arg mpg123_format_none(mpg123_handle *mh)
{
int r;
if(mh == NULL) return MPG123_BAD_HANDLE;
r = mpg123_fmt_none(&mh->p);
if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
return r;
}
int attribute_align_arg mpg123_fmt_none(mpg123_pars *mp)
{
if(mp == NULL) return MPG123_BAD_PARS;
if(PVERB(mp,3)) fprintf(stderr, "Note: Disabling all formats.\n");
memset(mp->audio_caps,0,sizeof(mp->audio_caps));
return MPG123_OK;
}
int attribute_align_arg mpg123_format_all(mpg123_handle *mh)
{
int r;
if(mh == NULL) return MPG123_BAD_HANDLE;
r = mpg123_fmt_all(&mh->p);
if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
return r;
}
int attribute_align_arg mpg123_fmt_all(mpg123_pars *mp)
{
size_t rate, ch, enc;
if(mp == NULL) return MPG123_BAD_PARS;
if(PVERB(mp,3)) fprintf(stderr, "Note: Enabling all formats.\n");
for(ch=0; ch < NUM_CHANNELS; ++ch)
for(rate=0; rate < MPG123_RATES+1; ++rate)
for(enc=0; enc < MPG123_ENCODINGS; ++enc)
mp->audio_caps[ch][rate][enc] = good_enc(my_encodings[enc]) ? 1 : 0;
return MPG123_OK;
}
int attribute_align_arg mpg123_format(mpg123_handle *mh, long rate, int channels, int encodings)
{
int r;
if(mh == NULL) return MPG123_BAD_HANDLE;
r = mpg123_fmt(&mh->p, rate, channels, encodings);
if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
return r;
}
int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int encodings)
{
int ie, ic, ratei;
int ch[2] = {0, 1};
if(mp == NULL) return MPG123_BAD_PARS;
if(!(channels & (MPG123_MONO|MPG123_STEREO))) return MPG123_BAD_CHANNEL;
if(PVERB(mp,3)) fprintf(stderr, "Note: Want to enable format %li/%i for encodings 0x%x.\n", rate, channels, encodings);
if(!(channels & MPG123_STEREO)) ch[1] = 0; /* {0,0} */
else if(!(channels & MPG123_MONO)) ch[0] = 1; /* {1,1} */
ratei = rate2num(mp, rate);
if(ratei < 0) return MPG123_BAD_RATE;
/* now match the encodings */
for(ic = 0; ic < 2; ++ic)
{
for(ie = 0; ie < MPG123_ENCODINGS; ++ie)
if(good_enc(my_encodings[ie]) && ((my_encodings[ie] & encodings) == my_encodings[ie]))
mp->audio_caps[ch[ic]][ratei][ie] = 1;
if(ch[0] == ch[1]) break; /* no need to do it again */
}
return MPG123_OK;
}
int attribute_align_arg mpg123_format_support(mpg123_handle *mh, long rate, int encoding)
{
if(mh == NULL) return 0;
else return mpg123_fmt_support(&mh->p, rate, encoding);
}
int attribute_align_arg mpg123_fmt_support(mpg123_pars *mp, long rate, int encoding)
{
int ch = 0;
int ratei, enci;
ratei = rate2num(mp, rate);
enci = enc2num(encoding);
if(mp == NULL || ratei < 0 || enci < 0) return 0;
if(mp->audio_caps[0][ratei][enci]) ch |= MPG123_MONO;
if(mp->audio_caps[1][ratei][enci]) ch |= MPG123_STEREO;
return ch;
}
/* Call this one to ensure that any valid format will be something different than this. */
void invalidate_format(struct audioformat *af)
{
af->encoding = 0;
af->rate = 0;
af->channels = 0;
}
/* Number of bytes the decoder produces. */
off_t decoder_synth_bytes(mpg123_handle *fr, off_t s)
{
return s * fr->af.dec_encsize * fr->af.channels;
}
/* Samples/bytes for output buffer after post-processing. */
/* take into account: channels, bytes per sample -- NOT resampling!*/
off_t samples_to_bytes(mpg123_handle *fr , off_t s)
{
return s * fr->af.encsize * fr->af.channels;
}
off_t bytes_to_samples(mpg123_handle *fr , off_t b)
{
return b / fr->af.encsize / fr->af.channels;
}
/* Number of bytes needed for decoding _and_ post-processing. */
off_t outblock_bytes(mpg123_handle *fr, off_t s)
{
int encsize = (fr->af.encoding & MPG123_ENC_24)
? 4 /* Intermediate 32 bit. */
: (fr->af.encsize > fr->af.dec_encsize
? fr->af.encsize
: fr->af.dec_encsize);
return s * encsize * fr->af.channels;
}
#ifndef NO_32BIT
/* Remove every fourth byte, facilitating conversion from 32 bit to 24 bit integers.
This has to be aware of endianness, of course. */
static void chop_fourth_byte(struct outbuffer *buf)
{
unsigned char *wpos = buf->data;
unsigned char *rpos = buf->data;
#ifdef WORDS_BIGENDIAN
while((size_t) (rpos - buf->data + 4) <= buf->fill)
{
/* Really stupid: Copy, increment. Byte per byte. */
*wpos = *rpos;
wpos++; rpos++;
*wpos = *rpos;
wpos++; rpos++;
*wpos = *rpos;
wpos++; rpos++;
rpos++; /* Skip the lowest byte (last). */
}
#else
while((size_t) (rpos - buf->data + 4) <= buf->fill)
{
/* Really stupid: Copy, increment. Byte per byte. */
rpos++; /* Skip the lowest byte (first). */
*wpos = *rpos;
wpos++; rpos++;
*wpos = *rpos;
wpos++; rpos++;
*wpos = *rpos;
wpos++; rpos++;
}
#endif
buf->fill = wpos-buf->data;
}
static void conv_s32_to_u32(struct outbuffer *buf)
{
size_t i;
int32_t *ssamples = (int32_t*) buf->data;
uint32_t *usamples = (uint32_t*) buf->data;
size_t count = buf->fill/sizeof(int32_t);
for(i=0; i<count; ++i)
{
/* Different strategy since we don't have a larger type at hand.
Also watch out for silly +-1 fun because integer constants are signed in C90! */
if(ssamples[i] >= 0)
usamples[i] = (uint32_t)ssamples[i] + 2147483647+1;
/* The smallest value goes zero. */
else if(ssamples[i] == ((int32_t)-2147483647-1))
usamples[i] = 0;
/* Now -value is in the positive range of signed int ... so it's a possible value at all. */
else
usamples[i] = (uint32_t)2147483647+1 - (uint32_t)(-ssamples[i]);
}
}
#endif
/* We always assume that whole numbers are written!
partials will be cut out. */
static const char *bufsizeerr = "Fatal: Buffer too small for postprocessing!";
#ifndef NO_16BIT
static void conv_s16_to_u16(struct outbuffer *buf)
{
size_t i;
int16_t *ssamples = (int16_t*) buf->data;
uint16_t *usamples = (uint16_t*)buf->data;
size_t count = buf->fill/sizeof(int16_t);
for(i=0; i<count; ++i)
{
long tmp = (long)ssamples[i]+32768;
usamples[i] = (uint16_t)tmp;
}
}
#ifndef NO_REAL
static void conv_s16_to_f32(struct outbuffer *buf)
{
ssize_t i;
int16_t *in = (int16_t*) buf->data;
float *out = (float*) buf->data;
size_t count = buf->fill/sizeof(int16_t);
/* Does that make any sense? In x86, there is an actual instruction to divide
float by integer ... but then, if we have that FPU, we don't really need
fixed point decoder hacks ...? */
float scale = 1./SHORT_SCALE;
if(buf->size < count*sizeof(float))
{
error1("%s", bufsizeerr);
return;
}
/* Work from the back since output is bigger. */
for(i=count-1; i>=0; --i)
out[i] = (float)in[i] * scale;
buf->fill = count*sizeof(float);
}
#endif
#ifndef NO_32BIT
static void conv_s16_to_s32(struct outbuffer *buf)
{
ssize_t i;
int16_t *in = (int16_t*) buf->data;
int32_t *out = (int32_t*) buf->data;
size_t count = buf->fill/sizeof(int16_t);
if(buf->size < count*sizeof(int32_t))
{
error1("%s", bufsizeerr);
return;
}
/* Work from the back since output is bigger. */
for(i=count-1; i>=0; --i)
{
out[i] = in[i];
/* Could just shift bytes, but would have to mess with sign bit. */
out[i] *= S32_RESCALE;
}
buf->fill = count*sizeof(int32_t);
}
#endif
#endif
void postprocess_buffer(mpg123_handle *fr)
{
/*
This caters for the final output formats that are never produced by
decoder synth directly (wide unsigned and 24 bit formats) or that are
missing because of limited decoder precision (16 bit synth but 32 or
24 bit output).
*/
switch(fr->af.dec_enc)
{
#ifndef NO_32BIT
case MPG123_ENC_SIGNED_32:
switch(fr->af.encoding)
{
case MPG123_ENC_UNSIGNED_32:
conv_s32_to_u32(&fr->buffer);
break;
case MPG123_ENC_UNSIGNED_24:
conv_s32_to_u32(&fr->buffer);
chop_fourth_byte(&fr->buffer);
break;
case MPG123_ENC_SIGNED_24:
chop_fourth_byte(&fr->buffer);
break;
}
break;
#endif
#ifndef NO_16BIT
case MPG123_ENC_SIGNED_16:
switch(fr->af.encoding)
{
case MPG123_ENC_UNSIGNED_16:
conv_s16_to_u16(&fr->buffer);
break;
#ifndef NO_REAL
case MPG123_ENC_FLOAT_32:
conv_s16_to_f32(&fr->buffer);
break;
#endif
#ifndef NO_32BIT
case MPG123_ENC_SIGNED_32:
conv_s16_to_s32(&fr->buffer);
break;
case MPG123_ENC_UNSIGNED_32:
conv_s16_to_s32(&fr->buffer);
conv_s32_to_u32(&fr->buffer);
break;
case MPG123_ENC_UNSIGNED_24:
conv_s16_to_s32(&fr->buffer);
conv_s32_to_u32(&fr->buffer);
chop_fourth_byte(&fr->buffer);
break;
case MPG123_ENC_SIGNED_24:
conv_s16_to_s32(&fr->buffer);
chop_fourth_byte(&fr->buffer);
break;
#endif
}
break;
#endif
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,414 @@
/*
frame: Central data structures and opmitization hooks.
copyright 2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
*/
#ifndef MPG123_FRAME_H
#define MPG123_FRAME_H
#include <stdio.h>
#include "config.h"
#include "mpg123.h"
#include "optimize.h"
#include "id3.h"
#include "icy.h"
#include "reader.h"
#ifdef FRAME_INDEX
#include "index.h"
#endif
#include "synths.h"
#ifdef OPT_DITHER
#include "dither.h"
int frame_dither_init(mpg123_handle *fr);
#endif
/* max = 1728 */
#define MAXFRAMESIZE 3456
struct al_table
{
short bits;
short d;
};
/* the output buffer, used to be pcm_sample, pcm_point and audiobufsize */
struct outbuffer
{
unsigned char *data; /* main data pointer, aligned */
unsigned char *p; /* read pointer */
size_t fill; /* fill from read pointer */
size_t size;
unsigned char *rdata; /* unaligned base pointer */
};
struct audioformat
{
int encoding; /* Final encoding, after post-processing. */
int encsize; /* Size of one sample in bytes, plain int should be fine here... */
int dec_enc; /* Encoding of decoder synth. */
int dec_encsize; /* Size of one decoder sample. */
int channels;
long rate;
};
void invalidate_format(struct audioformat *af);
struct mpg123_pars_struct
{
int verbose; /* verbose level */
long flags; /* combination of above */
#ifndef NO_NTOM
long force_rate;
#endif
int down_sample;
int rva; /* (which) rva to do: 0: nothing, 1: radio/mix/track 2: album/audiophile */
long halfspeed;
long doublespeed;
long timeout;
#define NUM_CHANNELS 2
char audio_caps[NUM_CHANNELS][MPG123_RATES+1][MPG123_ENCODINGS];
/* long start_frame; */ /* frame offset to begin with */
/* long frame_number;*/ /* number of frames to decode */
#ifndef NO_ICY
long icy_interval;
#endif
double outscale;
long resync_limit;
long index_size; /* Long, because: negative values have a meaning. */
long preframes;
#ifndef NO_FEEDER
long feedpool;
long feedbuffer;
#endif
};
enum frame_state_flags
{
FRAME_ACCURATE = 0x1 /**< 0001 Positions are considered accurate. */
,FRAME_FRANKENSTEIN = 0x2 /**< 0010 This stream is concatenated. */
,FRAME_FRESH_DECODER = 0x4 /**< 0100 Decoder is fleshly initialized. */
};
/* There is a lot to condense here... many ints can be merged as flags; though the main space is still consumed by buffers. */
struct mpg123_handle_struct
{
int fresh; /* to be moved into flags */
int new_format;
real hybrid_block[2][2][SBLIMIT*SSLIMIT];
int hybrid_blc[2];
/* the scratch vars for the decoders, sometimes real, sometimes short... sometimes int/long */
short *short_buffs[2][2];
real *real_buffs[2][2];
unsigned char *rawbuffs;
int rawbuffss;
#ifdef OPT_I486
int i486bo[2];
#endif
int bo; /* Just have it always here. */
#ifdef OPT_DITHER
int ditherindex;
float *dithernoise;
#endif
unsigned char* rawdecwin; /* the block with all decwins */
int rawdecwins; /* size of rawdecwin memory */
real *decwin; /* _the_ decode table */
#ifdef OPT_MMXORSSE
/* I am not really sure that I need both of them... used in assembler */
float *decwin_mmx;
float *decwins;
#endif
#ifndef NO_EQUALIZER
int have_eq_settings;
real equalizer[2][32];
#endif
/* for halfspeed mode */
unsigned char ssave[34];
int halfphase;
#ifndef NO_8BIT
/* a raw buffer and a pointer into the middle for signed short conversion, only allocated on demand */
unsigned char *conv16to8_buf;
unsigned char *conv16to8;
#endif
/* There's some possible memory saving for stuff that is not _really_ dynamic. */
/* layer3 */
int longLimit[9][23];
int shortLimit[9][14];
real gainpow2[256+118+4]; /* not really dynamic, just different for mmx */
/* layer2 */
real muls[27][64]; /* also used by layer 1 */
#ifndef NO_NTOM
/* decode_ntom */
unsigned long ntom_val[2];
unsigned long ntom_step;
#endif
/* special i486 fun */
#ifdef OPT_I486
int *int_buffs[2][2];
#endif
/* special altivec... */
#ifdef OPT_ALTIVEC
real *areal_buffs[4][4];
#endif
struct synth_s synths;
struct
{
#ifdef OPT_MULTI
#ifndef NO_LAYER3
#if (defined OPT_3DNOW_VINTAGE || defined OPT_3DNOWEXT_VINTAGE || defined OPT_SSE || defined OPT_X86_64 || defined OPT_AVX || defined OPT_NEON || defined OPT_NEON64)
void (*the_dct36)(real *,real *,real *,real *,real *);
#endif
#endif
#endif
enum optdec type;
enum optcla class;
} cpu_opts;
int verbose; /* 0: nothing, 1: just print chosen decoder, 2: be verbose */
const struct al_table *alloc;
/* The runtime-chosen decoding, based on input and output format. */
func_synth synth;
func_synth_stereo synth_stereo;
func_synth_mono synth_mono;
/* Yes, this function is runtime-switched, too. */
void (*make_decode_tables)(mpg123_handle *fr); /* That is the volume control. */
int stereo; /* I _think_ 1 for mono and 2 for stereo */
int jsbound;
#define SINGLE_STEREO -1
#define SINGLE_LEFT 0
#define SINGLE_RIGHT 1
#define SINGLE_MIX 3
int single;
int II_sblimit;
int down_sample_sblimit;
int lsf; /* 0: MPEG 1.0; 1: MPEG 2.0/2.5 -- both used as bool and array index! */
/* Many flags in disguise as integers... wasting bytes. */
int mpeg25;
int down_sample;
int header_change;
int lay;
long spf; /* cached count of samples per frame */
int (*do_layer)(mpg123_handle *);
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 freesize; /* free format frame size */
enum mpg123_vbr vbr; /* 1 if variable bitrate was detected */
off_t num; /* frame offset ... */
off_t input_offset; /* byte offset of this frame in input stream */
off_t playnum; /* playback offset... includes repetitions, reset at seeks */
off_t audio_start; /* The byte offset in the file where audio data begins. */
int state_flags;
char silent_resync; /* Do not complain for the next n resyncs. */
unsigned char* xing_toc; /* The seek TOC from Xing header. */
int freeformat;
long freeformat_framesize;
/* bitstream info; bsi */
int bitindex;
unsigned char *wordpointer;
/* temporary storage for getbits stuff */
unsigned long ultmp;
unsigned char uctmp;
/* rva data, used in common.c, set in id3.c */
double maxoutburst; /* The maximum amplitude in current sample represenation. */
double lastscale;
struct
{
int level[2];
float gain[2];
float peak[2];
} rva;
/* input data */
off_t track_frames;
off_t track_samples;
double mean_framesize;
off_t mean_frames;
int fsizeold;
int ssize;
unsigned int bitreservoir;
unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */
unsigned char *bsbuf;
unsigned char *bsbufold;
int bsnum;
/* That is the header matching the last read frame body. */
unsigned long oldhead;
/* That is the header that is supposedly the first of the stream. */
unsigned long firsthead;
int abr_rate;
#ifdef FRAME_INDEX
struct frame_index index;
#endif
/* output data */
struct outbuffer buffer;
struct audioformat af;
int own_buffer;
size_t outblock; /* number of bytes that this frame produces (upper bound) */
int to_decode; /* this frame holds data to be decoded */
int to_ignore; /* the same, somehow */
off_t firstframe; /* start decoding from here */
off_t lastframe; /* last frame to decode (for gapless or num_frames limit) */
off_t ignoreframe; /* frames to decode but discard before firstframe */
#ifdef GAPLESS
off_t gapless_frames; /* frame count for the gapless part */
off_t firstoff; /* number of samples to ignore from firstframe */
off_t lastoff; /* number of samples to use from lastframe */
off_t begin_s; /* overall begin offset in samples */
off_t begin_os;
off_t end_s; /* overall end offset in samples */
off_t end_os;
off_t fullend_os; /* gapless_frames translated to output samples */
#endif
unsigned int crc; /* Well, I need a safe 16bit type, actually. But wider doesn't hurt. */
struct reader *rd; /* pointer to the reading functions */
struct reader_data rdat; /* reader data and state info */
struct mpg123_pars_struct p;
int err;
int decoder_change;
int delayed_change;
long clip;
/* the meta crap */
int metaflags;
unsigned char id3buf[128];
#ifndef NO_ID3V2
mpg123_id3v2 id3v2;
#endif
#ifndef NO_ICY
struct icy_meta icy;
#endif
/*
More variables needed for decoders, layerX.c.
This time it is not about static variables but about the need for alignment which cannot be guaranteed on the stack by certain compilers (Sun Studio).
We do not require the compiler to align stuff for our hand-written assembly. We only hope that it's able to align stuff for SSE and similar ops it generates itself.
*/
/*
Those layer-specific structs could actually share memory, as they are not in use simultaneously. One might allocate on decoder switch, too.
They all reside in one lump of memory (after each other), allocated to layerscratch.
*/
real *layerscratch;
#ifndef NO_LAYER1
struct
{
real (*fraction)[SBLIMIT]; /* ALIGNED(16) real fraction[2][SBLIMIT]; */
} layer1;
#endif
#ifndef NO_LAYER2
struct
{
real (*fraction)[4][SBLIMIT]; /* ALIGNED(16) real fraction[2][4][SBLIMIT] */
} layer2;
#endif
#ifndef NO_LAYER3
/* These are significant chunks of memory already... */
struct
{
real (*hybrid_in)[SBLIMIT][SSLIMIT]; /* ALIGNED(16) real hybridIn[2][SBLIMIT][SSLIMIT]; */
real (*hybrid_out)[SSLIMIT][SBLIMIT]; /* ALIGNED(16) real hybridOut[2][SSLIMIT][SBLIMIT]; */
} layer3;
#endif
/* A place for storing additional data for the large file wrapper.
This is cruft! */
void *wrapperdata;
/* A callback used to properly destruct the wrapper data. */
void (*wrapperclean)(void*);
};
/* generic init, does not include dynamic buffers */
void frame_init(mpg123_handle *fr);
void frame_init_par(mpg123_handle *fr, mpg123_pars *mp);
/* output buffer and format */
int frame_outbuffer(mpg123_handle *fr);
int frame_output_format(mpg123_handle *fr);
int frame_buffers(mpg123_handle *fr); /* various decoder buffers, needed once */
int frame_reset(mpg123_handle* fr); /* reset for next track */
int frame_buffers_reset(mpg123_handle *fr);
void frame_exit(mpg123_handle *fr); /* end, free all buffers */
/* Index functions... */
/* Well... print it... */
int mpg123_print_index(mpg123_handle *fr, FILE* out);
/* Find a seek position in index. */
off_t frame_index_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame);
/* Apply index_size setting. */
int frame_index_setup(mpg123_handle *fr);
void do_volume(mpg123_handle *fr, double factor);
void do_rva(mpg123_handle *fr);
/* samples per frame ...
Layer I
Layer II
Layer III
MPEG-1
384
1152
1152
MPEG-2 LSF
384
1152
576
MPEG 2.5
384
1152
576
*/
#ifdef GAPLESS
/* well, I take that one for granted... at least layer3 */
#define GAPLESS_DELAY 529
void frame_gapless_init(mpg123_handle *fr, off_t framecount, off_t bskip, off_t eskip);
void frame_gapless_realinit(mpg123_handle *fr);
void frame_gapless_update(mpg123_handle *mh, off_t total_samples);
/*void frame_gapless_position(mpg123_handle* fr);
void frame_gapless_bytify(mpg123_handle *fr);
void frame_gapless_ignore(mpg123_handle *fr, off_t frames);*/
/* void frame_gapless_buffercheck(mpg123_handle *fr); */
#endif
/* Number of samples the decoding of the current frame should yield. */
off_t frame_expect_outsamples(mpg123_handle *fr);
/* Skip this frame... do some fake action to get away without actually decoding it. */
void frame_skip(mpg123_handle *fr);
/*
Seeking core functions:
- convert input sample offset to output sample offset
- convert frame offset to output sample offset
- get leading frame offset for output sample offset
The offsets are "unadjusted"/internal; resampling is being taken care of.
*/
off_t frame_ins2outs(mpg123_handle *fr, off_t ins);
off_t frame_outs(mpg123_handle *fr, off_t num);
/* This one just computes the expected sample count for _this_ frame. */
off_t frame_expect_outsampels(mpg123_handle *fr);
off_t frame_offset(mpg123_handle *fr, off_t outs);
void frame_set_frameseek(mpg123_handle *fr, off_t fe);
void frame_set_seek(mpg123_handle *fr, off_t sp);
off_t frame_tell_seek(mpg123_handle *fr);
/* Take a copy of the Xing VBR TOC for fuzzy seeking. */
int frame_fill_toc(mpg123_handle *fr, unsigned char* in);
#endif

View File

@ -0,0 +1,119 @@
/*
sampleadjust: gapless sample offset math
copyright 1995-2012 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
This is no stand-alone header, precisely to be able to fool it into using fake handle types for testing the math.
*/
#include "debug.h"
#ifdef GAPLESS
/* From internal sample number to external. */
static off_t sample_adjust(mpg123_handle *mh, off_t x)
{
off_t s;
if(mh->p.flags & MPG123_GAPLESS)
{
/* It's a bit tricky to do this computation for the padding samples.
They are not there on the outside. */
if(x > mh->end_os)
{
if(x < mh->fullend_os)
s = mh->end_os - mh->begin_os;
else
s = x - (mh->fullend_os - mh->end_os + mh->begin_os);
}
else
s = x - mh->begin_os;
}
else
s = x;
return s;
}
/* from external samples to internal */
static off_t sample_unadjust(mpg123_handle *mh, off_t x)
{
off_t s;
if(mh->p.flags & MPG123_GAPLESS)
{
s = x + mh->begin_os;
/* There is a hole; we don't create sample positions in there.
Jump from the end of the gapless track directly to after the padding. */
if(s >= mh->end_os)
s += mh->fullend_os - mh->end_os;
}
else s = x;
return s;
}
/*
Take the buffer after a frame decode (strictly: it is the data from frame fr->num!) and cut samples out.
fr->buffer.fill may then be smaller than before...
*/
static void frame_buffercheck(mpg123_handle *fr)
{
/* When we have no accurate position, gapless code does not make sense. */
if(!(fr->state_flags & FRAME_ACCURATE)) return;
/* Get a grip on dirty streams that start with a gapless header.
Simply accept all data from frames that are too much,
they are supposedly attached to the stream after the fact. */
if(fr->gapless_frames > 0 && fr->num >= fr->gapless_frames) return;
/* Important: We first cut samples from the end, then cut from beginning (including left-shift of the buffer).
This order works also for the case where firstframe == lastframe. */
/* The last interesting (planned) frame: Only use some leading samples.
Note a difference from the below: The last frame and offset are unchanges by seeks.
The lastoff keeps being valid. */
if(fr->lastframe > -1 && fr->num >= fr->lastframe)
{
/* There can be more than one frame of padding at the end, so we ignore the whole frame if we are beyond lastframe. */
off_t byteoff = (fr->num == fr->lastframe) ? samples_to_bytes(fr, fr->lastoff) : 0;
if((off_t)fr->buffer.fill > byteoff)
{
fr->buffer.fill = byteoff;
}
if(VERBOSE3) fprintf(stderr, "\nNote: Cut frame %"OFF_P" buffer on end of stream to %"OFF_P" samples, fill now %"SIZE_P" bytes.\n", (off_p)fr->num, (off_p)(fr->num == fr->lastframe ? fr->lastoff : 0), (size_p)fr->buffer.fill);
}
/* The first interesting frame: Skip some leading samples. */
if(fr->firstoff && fr->num == fr->firstframe)
{
off_t byteoff = samples_to_bytes(fr, fr->firstoff);
if((off_t)fr->buffer.fill > byteoff)
{
fr->buffer.fill -= byteoff;
/* buffer.p != buffer.data only for own buffer */
debug6("cutting %li samples/%li bytes on begin, own_buffer=%i at %p=%p, buf[1]=%i",
(long)fr->firstoff, (long)byteoff, fr->own_buffer, (void*)fr->buffer.p, (void*)fr->buffer.data, ((short*)fr->buffer.p)[2]);
if(fr->own_buffer) fr->buffer.p = fr->buffer.data + byteoff;
else memmove(fr->buffer.data, fr->buffer.data + byteoff, fr->buffer.fill);
debug3("done cutting, buffer at %p =? %p, buf[1]=%i",
(void*)fr->buffer.p, (void*)fr->buffer.data, ((short*)fr->buffer.p)[2]);
}
else fr->buffer.fill = 0;
if(VERBOSE3) fprintf(stderr, "\nNote: Cut frame %"OFF_P" buffer on beginning of stream by %"OFF_P" samples, fill now %"SIZE_P" bytes.\n", (off_p)fr->num, (off_p)fr->firstoff, (size_p)fr->buffer.fill);
/* We can only reach this frame again by seeking. And on seeking, firstoff will be recomputed.
So it is safe to null it here (and it makes the if() decision abort earlier). */
fr->firstoff = 0;
}
}
#define SAMPLE_ADJUST(mh,x) sample_adjust(mh,x)
#define SAMPLE_UNADJUST(mh,x) sample_unadjust(mh,x)
#define FRAME_BUFFERCHECK(mh) frame_buffercheck(mh)
#else /* no gapless code included */
#define SAMPLE_ADJUST(mh,x) (x)
#define SAMPLE_UNADJUST(mh,x) (x)
#define FRAME_BUFFERCHECK(mh)
#endif

View File

@ -0,0 +1,103 @@
/*
getbits
copyright ?-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
All code is in the header to suggest/force inlining of these small often-used functions.
This indeed has some impact on performance.
*/
#ifndef _MPG123_GETBITS_H_
#define _MPG123_GETBITS_H_
#include "mpg123lib_intern.h"
#define backbits(fr,nob) ((void)( \
fr->bitindex -= nob, \
fr->wordpointer += (fr->bitindex>>3), \
fr->bitindex &= 0x7 ))
#define getbitoffset(fr) ((-fr->bitindex)&0x7)
#define getbyte(fr) (*fr->wordpointer++)
/* There is something wrong with that macro... the function below works also for the layer1 test case. */
#define macro_getbits(fr, nob) ( \
fr->ultmp = fr->wordpointer[0],\
fr->ultmp <<= 8, \
fr->ultmp |= fr->wordpointer[1], \
fr->ultmp <<= 8, \
fr->ultmp |= fr->wordpointer[2], \
fr->ultmp <<= fr->bitindex, \
fr->ultmp &= 0xffffff, \
fr->bitindex += nob, \
fr->ultmp >>= (24-nob), \
fr->wordpointer += (fr->bitindex>>3), \
fr->bitindex &= 7, \
fr->ultmp)
static unsigned int getbits(mpg123_handle *fr, int number_of_bits)
{
unsigned long rval;
#ifdef DEBUG_GETBITS
fprintf(stderr,"g%d",number_of_bits);
#endif
/* Safety catch until we got the nasty code fully figured out. */
if( (long)(fr->wordpointer-fr->bsbuf)*8
+ fr->bitindex+number_of_bits > (long)fr->framesize*8 )
return 0;
/* This is actually slow: if(!number_of_bits)
return 0; */
#if 0
check_buffer_range(number_of_bits+fr->bitindex);
#endif
{
rval = fr->wordpointer[0];
rval <<= 8;
rval |= fr->wordpointer[1];
rval <<= 8;
rval |= fr->wordpointer[2];
rval <<= fr->bitindex;
rval &= 0xffffff;
fr->bitindex += number_of_bits;
rval >>= (24-number_of_bits);
fr->wordpointer += (fr->bitindex>>3);
fr->bitindex &= 7;
}
#ifdef DEBUG_GETBITS
fprintf(stderr,":%lx\n",rval);
#endif
return rval;
}
#define skipbits(fr, nob) fr->ultmp = ( \
fr->ultmp = fr->wordpointer[0], fr->ultmp <<= 8, fr->ultmp |= fr->wordpointer[1], \
fr->ultmp <<= 8, fr->ultmp |= fr->wordpointer[2], fr->ultmp <<= fr->bitindex, \
fr->ultmp &= 0xffffff, fr->bitindex += nob, \
fr->ultmp >>= (24-nob), fr->wordpointer += (fr->bitindex>>3), \
fr->bitindex &= 7 )
#define getbits_fast(fr, nob) ( \
fr->ultmp = (unsigned char) (fr->wordpointer[0] << fr->bitindex), \
fr->ultmp |= ((unsigned long) fr->wordpointer[1]<<fr->bitindex)>>8, \
fr->ultmp <<= nob, fr->ultmp >>= 8, \
fr->bitindex += nob, fr->wordpointer += (fr->bitindex>>3), \
fr->bitindex &= 7, fr->ultmp )
#define get1bit(fr) ( \
fr->uctmp = *fr->wordpointer << fr->bitindex, fr->bitindex++, \
fr->wordpointer += (fr->bitindex>>3), fr->bitindex &= 7, fr->uctmp>>7 )
#endif

View File

@ -0,0 +1,102 @@
/*
getcpucpuflags: get cpuflags for ia32
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http:#mpg123.org
initially written by KIMURA Takuhiro (for 3DNow!)
extended for general use by Thomas Orgis
extern int getcpuid(struct cpuflags*)
or just
extern int getcpuid(unsigned int*)
where there is memory for 4 ints
-> the first set of idflags (basic cpu family info)
and the idflags, stdflags, std2flags, extflags written to the parameter
-> 0x00000000 (CPUID instruction not supported)
*/
#include "mangle.h"
.text
ALIGN4
.globl ASM_NAME(getcpuflags)
/* .type ASM_NAME(getcpuflags),@function */
ASM_NAME(getcpuflags):
pushl %ebp
movl %esp,%ebp
pushl %edx
pushl %ecx
pushl %ebx
pushl %esi
/* get the int pointer for storing the flags */
movl 8(%ebp), %esi
/* does that one make sense? */
movl $0x80000000,%eax
/* now save the flags and do a check for cpuid availability */
pushfl
pushfl
popl %eax
movl %eax,%ebx
/* set that bit... */
xorl $0x00200000,%eax
pushl %eax
popfl
/* ...and read back the flags to see if it is understood */
pushfl
popl %eax
popfl
cmpl %ebx,%eax
je .Lnocpuid
/* In principle, I would have to check the CPU's identify first to be sure how to interpret the extended flags. */
/* now get the info, first extended */
movl $0x0, 12(%esi) /* clear value */
movl $0x0, 16(%esi) /* clear value */
/* only if supported... */
movl $0x80000000, %eax
cpuid
/* IDT CPUs should not change EAX, generally I hope that non-3DNow cpus do not set a bogus support level here. */
cmpl $0x80000001, %eax
jb .Lnoextended /* Skip ext check without minimal support level. */
/* is supported, get flags value */
movl $0x80000001,%eax
cpuid
movl %edx,12(%esi)
.Lnoextended:
/* then the other ones, called last to get the id flags in %eax for ret */
movl $0x00000001,%eax
cpuid
movl %eax, (%esi)
movl %ecx, 4(%esi)
movl %edx, 8(%esi)
/* check if xgetbv instruction is available */
test $0x04000000, %ecx
jz .Lend
test $0x08000000, %ecx
jz .Lend
xor %ecx, %ecx
.byte 0x0f, 0x01, 0xd0 /* xgetbv instruction */
movl %eax, 16(%esi)
movl (%esi), %eax
jmp .Lend
ALIGN4
.Lnocpuid:
/* error: set everything to zero */
movl $0, %eax
movl $0, (%esi)
movl $0, 4(%esi)
movl $0, 8(%esi)
movl $0, 12(%esi)
movl $0, 16(%esi)
ALIGN4
.Lend:
/* return value are the id flags, still stored in %eax */
popl %esi
popl %ebx
popl %ecx
popl %edx
movl %ebp,%esp
popl %ebp
ret
NONEXEC_STACK

View File

@ -0,0 +1,60 @@
/*
getcpucpuflags: get cpuflags for ia32
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http:#mpg123.org
initially written by KIMURA Takuhiro (for 3DNow!)
extended for general use by Thomas Orgis
*/
#ifndef MPG123_H_GETCPUFLAGS
#define MPG123_H_GETCPUFLAGS
/* standard level flags part 1 (ECX)*/
#define FLAG_SSE3 0x00000001
#define FLAG_SSSE3 0x00000200
#define FLAG_AVX 0x1C000000
/* standard level flags part 2 (EDX) */
#define FLAG2_MMX 0x00800000
#define FLAG2_SSE 0x02000000
#define FLAG2_SSE2 0x04000000
#define FLAG2_FPU 0x00000001
/* cpuid extended level 1 (AMD) */
#define XFLAG_MMX 0x00800000
#define XFLAG_3DNOW 0x80000000
#define XFLAG_3DNOWEXT 0x40000000
/* eXtended Control Register 0 */
#define XCR0FLAG_AVX 0x00000006
struct cpuflags
{
#if defined(OPT_ARM) || defined(OPT_NEON) || defined(OPT_NEON64)
unsigned int has_neon;
#else
unsigned int id;
unsigned int std;
unsigned int std2;
unsigned int ext;
unsigned int xcr0_lo;
#endif
};
unsigned int getcpuflags(struct cpuflags* cf);
/* checks the family */
#define cpu_i586(s) ( ((s.id & 0xf00)>>8) == 0 || ((s.id & 0xf00)>>8) > 4 )
/* checking some flags... */
#define cpu_fpu(s) (FLAG2_FPU & s.std2)
#define cpu_mmx(s) (FLAG2_MMX & s.std2 || XFLAG_MMX & s.ext)
#define cpu_3dnow(s) (XFLAG_3DNOW & s.ext)
#define cpu_3dnowext(s) (XFLAG_3DNOWEXT & s.ext)
#define cpu_sse(s) (FLAG2_SSE & s.std2)
#define cpu_sse2(s) (FLAG2_SSE2 & s.std2)
#define cpu_sse3(s) (FLAG_SSE3 & s.std)
#define cpu_avx(s) ((FLAG_AVX & s.std) == FLAG_AVX && (XCR0FLAG_AVX & s.xcr0_lo) == XCR0FLAG_AVX)
#define cpu_fast_sse(s) ((((s.id & 0xf00)>>8) == 6 && FLAG_SSSE3 & s.std) /* for Intel/VIA; family 6 CPUs with SSSE3 */ || \
(((s.id & 0xf00)>>8) == 0xf && (((s.id & 0x0ff00000)>>20) > 0 && ((s.id & 0x0ff00000)>>20) != 5))) /* for AMD; family > 0xF CPUs except Bobcat */
#define cpu_neon(s) (s.has_neon)
#endif

View File

@ -0,0 +1,61 @@
/*
getcpuflags_arm: get cpuflags for ARM
copyright 1995-2014 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Momma
*/
#include <setjmp.h>
#include <signal.h>
#include "mpg123lib_intern.h"
#include "getcpuflags.h"
extern void check_neon(void);
#ifndef _M_ARM
static sigjmp_buf jmpbuf;
#else
static jmp_buf jmpbuf;
#endif
static void mpg123_arm_catch_sigill(int sig)
{
#ifndef _M_ARM
siglongjmp(jmpbuf, 1);
#else
longjmp(jmpbuf, 1);
#endif
}
unsigned int getcpuflags(struct cpuflags* cf)
{
#ifndef _M_ARM
struct sigaction act, act_old;
act.sa_handler = mpg123_arm_catch_sigill;
act.sa_flags = SA_RESTART;
sigemptyset(&act.sa_mask);
sigaction(SIGILL, &act, &act_old);
cf->has_neon = 0;
if(!sigsetjmp(jmpbuf, 1)) {
check_neon();
cf->has_neon = 1;
}
sigaction(SIGILL, &act_old, NULL);
#else
cf->has_neon = 0;
if (!setjmp(jmpbuf)) {
signal(SIGILL, mpg123_arm_catch_sigill);
check_neon();
cf->has_neon = 1;
}
signal(SIGILL, SIG_DFL);
#endif
return 0;
}

View File

@ -0,0 +1,57 @@
/*
getcpuflags_x86_64: get cpuflags for x86-64
copyright 1995-2013 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#include "mangle.h"
.text
ALIGN4
.globl ASM_NAME(getcpuflags)
ASM_NAME(getcpuflags):
push %rbp
mov %rsp, %rbp
push %rbx
#ifdef IS_MSABI
push %rdi
mov %rcx, %rdi
#endif
movl $0, 12(%rdi)
movl $0, 16(%rdi)
mov $0x80000000, %eax
cpuid
cmp $0x80000001, %eax
jb 1f
mov $0x80000001, %eax
cpuid
movl %edx, 12(%rdi)
1:
mov $0x00000001, %eax
cpuid
movl %eax, (%rdi)
movl %ecx, 4(%rdi)
movl %edx, 8(%rdi)
test $0x04000000, %ecx
jz 2f
test $0x08000000, %ecx
jz 2f
xor %ecx, %ecx
.byte 0x0f, 0x01, 0xd0 /* xgetbv instruction */
movl %eax, 16(%rdi)
movl (%rdi), %eax
2:
#ifdef IS_MSABI
pop %rdi
#endif
pop %rbx
mov %rbp, %rsp
pop %rbp
ret
NONEXEC_STACK

View File

@ -0,0 +1,340 @@
/*
huffman.h: huffman tables ... recalcualted to work with optimized decoder scheme (MH)
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
probably we could save a few bytes of memory, because the
smaller tables are often the part of a bigger table
*/
#ifndef _MPG123_HUFFMAN_H_
#define _MPG123_HUFFMAN_H_
struct newhuff
{
unsigned int linbits;
const short *table;
};
static const short tab0[] =
{
0
};
static const short tab1[] =
{
-5, -3, -1, 17, 1, 16, 0
};
static const short tab2[] =
{
-15, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 17, -1, 1,
16, 0
};
static const short tab3[] =
{
-13, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 16, 17, -1,
1, 0
};
static const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const struct newhuff htc[] =
{
{ /* 1 , 1 , */ 0 , tab_c0 } ,
{ /* 1 , 1 , */ 0 , tab_c1 }
};
#endif

View File

@ -0,0 +1,34 @@
/*
icy: Puny code to pretend for a serious ICY data structure.
copyright 2007-2015 by the mpg123 project
-= free software under the terms of the LGPL 2.1 =-
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
*/
#include "intsym.h"
#include "icy.h"
void init_icy(struct icy_meta *icy)
{
icy->data = NULL;
}
void clear_icy(struct icy_meta *icy)
{
if(icy->data != NULL) free(icy->data);
init_icy(icy);
}
void reset_icy(struct icy_meta *icy)
{
clear_icy(icy);
init_icy(icy);
}
/*void set_icy(struct icy_meta *icy, char* new_data)
{
if(icy->data) free(icy->data);
icy->data = new_data;
icy->changed = 1;
}*/

View File

@ -0,0 +1,38 @@
/*
icy: support for SHOUTcast ICY meta info, an attempt to keep it organized
copyright 2006-7 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis and modelled after patch by Honza
*/
#ifndef MPG123_ICY_H
#define MPG123_ICY_H
#ifndef NO_ICY
#include "compat.h"
#include "mpg123.h"
struct icy_meta
{
char* data;
off_t interval;
off_t next;
};
void init_icy(struct icy_meta *);
void clear_icy(struct icy_meta *);
void reset_icy(struct icy_meta *);
#else
#undef init_icy
#define init_icy(a)
#undef clear_icy
#define clear_icy(a)
#undef reset_icy
#define reset_icy(a)
#endif /* NO_ICY */
#endif

View File

@ -0,0 +1,440 @@
/* mpg123 note: This is BSD-licensed code that is no problem for mpg123 usage under LGPL.
It's Free, understood? ;-) */
/* Another note: This code is basically written by Thorsten Glaser,
Thomas Orgis did just some rearrangements and comments. */
/*-
* Copyright (c) 2008
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission
* is granted to deal in this work without restriction, including un-
* limited rights to use, publicly perform, distribute, sell, modify,
* merge, give away, or sublicence.
*
* This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
* the utmost extent permitted by applicable law, neither express nor
* implied; without malicious intent or gross negligence. In no event
* may a licensor, author or contributor be held liable for indirect,
* direct, other damage, loss, or other issues arising in any way out
* of dealing in the work, even if advised of the possibility of such
* damage or existence of a defect, except proven that it results out
* of said person's immediate fault when using the work as intended.
*-
* Convert from ICY encoding (windows-1252 codepage) to UTF-8
*/
#include "config.h"
#include "intsym.h"
/* Includes string and stdlib headers... */
#include "compat.h"
/* ThOr: too lazy for this type check; also we use char/short all around anyway.
Of cource, it would be the proper way to use _these_ kind of types all around. */
#define uint8_t unsigned char
#define uint16_t unsigned short
static const uint8_t cp1252_utf8[] = {
/* 0x00 @ 0 */ 0x00,
/* 0x01 @ 1 */ 0x01,
/* 0x02 @ 2 */ 0x02,
/* 0x03 @ 3 */ 0x03,
/* 0x04 @ 4 */ 0x04,
/* 0x05 @ 5 */ 0x05,
/* 0x06 @ 6 */ 0x06,
/* 0x07 @ 7 */ 0x07,
/* 0x08 @ 8 */ 0x08,
/* 0x09 @ 9 */ 0x09,
/* 0x0A @ 10 */ 0x0A,
/* 0x0B @ 11 */ 0x0B,
/* 0x0C @ 12 */ 0x0C,
/* 0x0D @ 13 */ 0x0D,
/* 0x0E @ 14 */ 0x0E,
/* 0x0F @ 15 */ 0x0F,
/* 0x10 @ 16 */ 0x10,
/* 0x11 @ 17 */ 0x11,
/* 0x12 @ 18 */ 0x12,
/* 0x13 @ 19 */ 0x13,
/* 0x14 @ 20 */ 0x14,
/* 0x15 @ 21 */ 0x15,
/* 0x16 @ 22 */ 0x16,
/* 0x17 @ 23 */ 0x17,
/* 0x18 @ 24 */ 0x18,
/* 0x19 @ 25 */ 0x19,
/* 0x1A @ 26 */ 0x1A,
/* 0x1B @ 27 */ 0x1B,
/* 0x1C @ 28 */ 0x1C,
/* 0x1D @ 29 */ 0x1D,
/* 0x1E @ 30 */ 0x1E,
/* 0x1F @ 31 */ 0x1F,
/* 0x20 @ 32 */ 0x20,
/* 0x21 @ 33 */ 0x21,
/* 0x22 @ 34 */ 0x22,
/* 0x23 @ 35 */ 0x23,
/* 0x24 @ 36 */ 0x24,
/* 0x25 @ 37 */ 0x25,
/* 0x26 @ 38 */ 0x26,
/* 0x27 @ 39 */ 0x27,
/* 0x28 @ 40 */ 0x28,
/* 0x29 @ 41 */ 0x29,
/* 0x2A @ 42 */ 0x2A,
/* 0x2B @ 43 */ 0x2B,
/* 0x2C @ 44 */ 0x2C,
/* 0x2D @ 45 */ 0x2D,
/* 0x2E @ 46 */ 0x2E,
/* 0x2F @ 47 */ 0x2F,
/* 0x30 @ 48 */ 0x30,
/* 0x31 @ 49 */ 0x31,
/* 0x32 @ 50 */ 0x32,
/* 0x33 @ 51 */ 0x33,
/* 0x34 @ 52 */ 0x34,
/* 0x35 @ 53 */ 0x35,
/* 0x36 @ 54 */ 0x36,
/* 0x37 @ 55 */ 0x37,
/* 0x38 @ 56 */ 0x38,
/* 0x39 @ 57 */ 0x39,
/* 0x3A @ 58 */ 0x3A,
/* 0x3B @ 59 */ 0x3B,
/* 0x3C @ 60 */ 0x3C,
/* 0x3D @ 61 */ 0x3D,
/* 0x3E @ 62 */ 0x3E,
/* 0x3F @ 63 */ 0x3F,
/* 0x40 @ 64 */ 0x40,
/* 0x41 @ 65 */ 0x41,
/* 0x42 @ 66 */ 0x42,
/* 0x43 @ 67 */ 0x43,
/* 0x44 @ 68 */ 0x44,
/* 0x45 @ 69 */ 0x45,
/* 0x46 @ 70 */ 0x46,
/* 0x47 @ 71 */ 0x47,
/* 0x48 @ 72 */ 0x48,
/* 0x49 @ 73 */ 0x49,
/* 0x4A @ 74 */ 0x4A,
/* 0x4B @ 75 */ 0x4B,
/* 0x4C @ 76 */ 0x4C,
/* 0x4D @ 77 */ 0x4D,
/* 0x4E @ 78 */ 0x4E,
/* 0x4F @ 79 */ 0x4F,
/* 0x50 @ 80 */ 0x50,
/* 0x51 @ 81 */ 0x51,
/* 0x52 @ 82 */ 0x52,
/* 0x53 @ 83 */ 0x53,
/* 0x54 @ 84 */ 0x54,
/* 0x55 @ 85 */ 0x55,
/* 0x56 @ 86 */ 0x56,
/* 0x57 @ 87 */ 0x57,
/* 0x58 @ 88 */ 0x58,
/* 0x59 @ 89 */ 0x59,
/* 0x5A @ 90 */ 0x5A,
/* 0x5B @ 91 */ 0x5B,
/* 0x5C @ 92 */ 0x5C,
/* 0x5D @ 93 */ 0x5D,
/* 0x5E @ 94 */ 0x5E,
/* 0x5F @ 95 */ 0x5F,
/* 0x60 @ 96 */ 0x60,
/* 0x61 @ 97 */ 0x61,
/* 0x62 @ 98 */ 0x62,
/* 0x63 @ 99 */ 0x63,
/* 0x64 @ 100 */ 0x64,
/* 0x65 @ 101 */ 0x65,
/* 0x66 @ 102 */ 0x66,
/* 0x67 @ 103 */ 0x67,
/* 0x68 @ 104 */ 0x68,
/* 0x69 @ 105 */ 0x69,
/* 0x6A @ 106 */ 0x6A,
/* 0x6B @ 107 */ 0x6B,
/* 0x6C @ 108 */ 0x6C,
/* 0x6D @ 109 */ 0x6D,
/* 0x6E @ 110 */ 0x6E,
/* 0x6F @ 111 */ 0x6F,
/* 0x70 @ 112 */ 0x70,
/* 0x71 @ 113 */ 0x71,
/* 0x72 @ 114 */ 0x72,
/* 0x73 @ 115 */ 0x73,
/* 0x74 @ 116 */ 0x74,
/* 0x75 @ 117 */ 0x75,
/* 0x76 @ 118 */ 0x76,
/* 0x77 @ 119 */ 0x77,
/* 0x78 @ 120 */ 0x78,
/* 0x79 @ 121 */ 0x79,
/* 0x7A @ 122 */ 0x7A,
/* 0x7B @ 123 */ 0x7B,
/* 0x7C @ 124 */ 0x7C,
/* 0x7D @ 125 */ 0x7D,
/* 0x7E @ 126 */ 0x7E,
/* 0x7F @ 127 */ 0x7F,
/* 0x80 @ 128 */ 0xE2, 0x82, 0xAC,
/* 0x81 @ 131 */ 0xEF, 0xBF, 0xBD,
/* 0x82 @ 134 */ 0xE2, 0x80, 0x9A,
/* 0x83 @ 137 */ 0xC6, 0x92,
/* 0x84 @ 139 */ 0xE2, 0x80, 0x9E,
/* 0x85 @ 142 */ 0xE2, 0x80, 0xA6,
/* 0x86 @ 145 */ 0xE2, 0x80, 0xA0,
/* 0x87 @ 148 */ 0xE2, 0x80, 0xA1,
/* 0x88 @ 151 */ 0xCB, 0x86,
/* 0x89 @ 153 */ 0xE2, 0x80, 0xB0,
/* 0x8A @ 156 */ 0xC5, 0xA0,
/* 0x8B @ 158 */ 0xE2, 0x80, 0xB9,
/* 0x8C @ 161 */ 0xC5, 0x92,
/* 0x8D @ 163 */ 0xEF, 0xBF, 0xBD,
/* 0x8E @ 166 */ 0xC5, 0xBD,
/* 0x8F @ 168 */ 0xEF, 0xBF, 0xBD,
/* 0x90 @ 171 */ 0xEF, 0xBF, 0xBD,
/* 0x91 @ 174 */ 0xE2, 0x80, 0x98,
/* 0x92 @ 177 */ 0xE2, 0x80, 0x99,
/* 0x93 @ 180 */ 0xE2, 0x80, 0x9C,
/* 0x94 @ 183 */ 0xE2, 0x80, 0x9D,
/* 0x95 @ 186 */ 0xE2, 0x80, 0xA2,
/* 0x96 @ 189 */ 0xE2, 0x80, 0x93,
/* 0x97 @ 192 */ 0xE2, 0x80, 0x94,
/* 0x98 @ 195 */ 0xCB, 0x9C,
/* 0x99 @ 197 */ 0xE2, 0x84, 0xA2,
/* 0x9A @ 200 */ 0xC5, 0xA1,
/* 0x9B @ 202 */ 0xE2, 0x80, 0xBA,
/* 0x9C @ 205 */ 0xC5, 0x93,
/* 0x9D @ 207 */ 0xEF, 0xBF, 0xBD,
/* 0x9E @ 210 */ 0xC5, 0xBE,
/* 0x9F @ 212 */ 0xC5, 0xB8,
/* 0xA0 @ 214 */ 0xC2, 0xA0,
/* 0xA1 @ 216 */ 0xC2, 0xA1,
/* 0xA2 @ 218 */ 0xC2, 0xA2,
/* 0xA3 @ 220 */ 0xC2, 0xA3,
/* 0xA4 @ 222 */ 0xC2, 0xA4,
/* 0xA5 @ 224 */ 0xC2, 0xA5,
/* 0xA6 @ 226 */ 0xC2, 0xA6,
/* 0xA7 @ 228 */ 0xC2, 0xA7,
/* 0xA8 @ 230 */ 0xC2, 0xA8,
/* 0xA9 @ 232 */ 0xC2, 0xA9,
/* 0xAA @ 234 */ 0xC2, 0xAA,
/* 0xAB @ 236 */ 0xC2, 0xAB,
/* 0xAC @ 238 */ 0xC2, 0xAC,
/* 0xAD @ 240 */ 0xC2, 0xAD,
/* 0xAE @ 242 */ 0xC2, 0xAE,
/* 0xAF @ 244 */ 0xC2, 0xAF,
/* 0xB0 @ 246 */ 0xC2, 0xB0,
/* 0xB1 @ 248 */ 0xC2, 0xB1,
/* 0xB2 @ 250 */ 0xC2, 0xB2,
/* 0xB3 @ 252 */ 0xC2, 0xB3,
/* 0xB4 @ 254 */ 0xC2, 0xB4,
/* 0xB5 @ 256 */ 0xC2, 0xB5,
/* 0xB6 @ 258 */ 0xC2, 0xB6,
/* 0xB7 @ 260 */ 0xC2, 0xB7,
/* 0xB8 @ 262 */ 0xC2, 0xB8,
/* 0xB9 @ 264 */ 0xC2, 0xB9,
/* 0xBA @ 266 */ 0xC2, 0xBA,
/* 0xBB @ 268 */ 0xC2, 0xBB,
/* 0xBC @ 270 */ 0xC2, 0xBC,
/* 0xBD @ 272 */ 0xC2, 0xBD,
/* 0xBE @ 274 */ 0xC2, 0xBE,
/* 0xBF @ 276 */ 0xC2, 0xBF,
/* 0xC0 @ 278 */ 0xC3, 0x80,
/* 0xC1 @ 280 */ 0xC3, 0x81,
/* 0xC2 @ 282 */ 0xC3, 0x82,
/* 0xC3 @ 284 */ 0xC3, 0x83,
/* 0xC4 @ 286 */ 0xC3, 0x84,
/* 0xC5 @ 288 */ 0xC3, 0x85,
/* 0xC6 @ 290 */ 0xC3, 0x86,
/* 0xC7 @ 292 */ 0xC3, 0x87,
/* 0xC8 @ 294 */ 0xC3, 0x88,
/* 0xC9 @ 296 */ 0xC3, 0x89,
/* 0xCA @ 298 */ 0xC3, 0x8A,
/* 0xCB @ 300 */ 0xC3, 0x8B,
/* 0xCC @ 302 */ 0xC3, 0x8C,
/* 0xCD @ 304 */ 0xC3, 0x8D,
/* 0xCE @ 306 */ 0xC3, 0x8E,
/* 0xCF @ 308 */ 0xC3, 0x8F,
/* 0xD0 @ 310 */ 0xC3, 0x90,
/* 0xD1 @ 312 */ 0xC3, 0x91,
/* 0xD2 @ 314 */ 0xC3, 0x92,
/* 0xD3 @ 316 */ 0xC3, 0x93,
/* 0xD4 @ 318 */ 0xC3, 0x94,
/* 0xD5 @ 320 */ 0xC3, 0x95,
/* 0xD6 @ 322 */ 0xC3, 0x96,
/* 0xD7 @ 324 */ 0xC3, 0x97,
/* 0xD8 @ 326 */ 0xC3, 0x98,
/* 0xD9 @ 328 */ 0xC3, 0x99,
/* 0xDA @ 330 */ 0xC3, 0x9A,
/* 0xDB @ 332 */ 0xC3, 0x9B,
/* 0xDC @ 334 */ 0xC3, 0x9C,
/* 0xDD @ 336 */ 0xC3, 0x9D,
/* 0xDE @ 338 */ 0xC3, 0x9E,
/* 0xDF @ 340 */ 0xC3, 0x9F,
/* 0xE0 @ 342 */ 0xC3, 0xA0,
/* 0xE1 @ 344 */ 0xC3, 0xA1,
/* 0xE2 @ 346 */ 0xC3, 0xA2,
/* 0xE3 @ 348 */ 0xC3, 0xA3,
/* 0xE4 @ 350 */ 0xC3, 0xA4,
/* 0xE5 @ 352 */ 0xC3, 0xA5,
/* 0xE6 @ 354 */ 0xC3, 0xA6,
/* 0xE7 @ 356 */ 0xC3, 0xA7,
/* 0xE8 @ 358 */ 0xC3, 0xA8,
/* 0xE9 @ 360 */ 0xC3, 0xA9,
/* 0xEA @ 362 */ 0xC3, 0xAA,
/* 0xEB @ 364 */ 0xC3, 0xAB,
/* 0xEC @ 366 */ 0xC3, 0xAC,
/* 0xED @ 368 */ 0xC3, 0xAD,
/* 0xEE @ 370 */ 0xC3, 0xAE,
/* 0xEF @ 372 */ 0xC3, 0xAF,
/* 0xF0 @ 374 */ 0xC3, 0xB0,
/* 0xF1 @ 376 */ 0xC3, 0xB1,
/* 0xF2 @ 378 */ 0xC3, 0xB2,
/* 0xF3 @ 380 */ 0xC3, 0xB3,
/* 0xF4 @ 382 */ 0xC3, 0xB4,
/* 0xF5 @ 384 */ 0xC3, 0xB5,
/* 0xF6 @ 386 */ 0xC3, 0xB6,
/* 0xF7 @ 388 */ 0xC3, 0xB7,
/* 0xF8 @ 390 */ 0xC3, 0xB8,
/* 0xF9 @ 392 */ 0xC3, 0xB9,
/* 0xFA @ 394 */ 0xC3, 0xBA,
/* 0xFB @ 396 */ 0xC3, 0xBB,
/* 0xFC @ 398 */ 0xC3, 0xBC,
/* 0xFD @ 400 */ 0xC3, 0xBD,
/* 0xFE @ 402 */ 0xC3, 0xBE,
/* 0xFF @ 404 */ 0xC3, 0xBF,
};
static const uint16_t tblofs[257] = {
/* 0x00 */ 0, 1, 2, 3, 4, 5, 6, 7,
/* 0x08 */ 8, 9, 10, 11, 12, 13, 14, 15,
/* 0x10 */ 16, 17, 18, 19, 20, 21, 22, 23,
/* 0x18 */ 24, 25, 26, 27, 28, 29, 30, 31,
/* 0x20 */ 32, 33, 34, 35, 36, 37, 38, 39,
/* 0x28 */ 40, 41, 42, 43, 44, 45, 46, 47,
/* 0x30 */ 48, 49, 50, 51, 52, 53, 54, 55,
/* 0x38 */ 56, 57, 58, 59, 60, 61, 62, 63,
/* 0x40 */ 64, 65, 66, 67, 68, 69, 70, 71,
/* 0x48 */ 72, 73, 74, 75, 76, 77, 78, 79,
/* 0x50 */ 80, 81, 82, 83, 84, 85, 86, 87,
/* 0x58 */ 88, 89, 90, 91, 92, 93, 94, 95,
/* 0x60 */ 96, 97, 98, 99, 100, 101, 102, 103,
/* 0x68 */ 104, 105, 106, 107, 108, 109, 110, 111,
/* 0x70 */ 112, 113, 114, 115, 116, 117, 118, 119,
/* 0x78 */ 120, 121, 122, 123, 124, 125, 126, 127,
/* 0x80 */ 128, 131, 134, 137, 139, 142, 145, 148,
/* 0x88 */ 151, 153, 156, 158, 161, 163, 166, 168,
/* 0x90 */ 171, 174, 177, 180, 183, 186, 189, 192,
/* 0x98 */ 195, 197, 200, 202, 205, 207, 210, 212,
/* 0xA0 */ 214, 216, 218, 220, 222, 224, 226, 228,
/* 0xA8 */ 230, 232, 234, 236, 238, 240, 242, 244,
/* 0xB0 */ 246, 248, 250, 252, 254, 256, 258, 260,
/* 0xB8 */ 262, 264, 266, 268, 270, 272, 274, 276,
/* 0xC0 */ 278, 280, 282, 284, 286, 288, 290, 292,
/* 0xC8 */ 294, 296, 298, 300, 302, 304, 306, 308,
/* 0xD0 */ 310, 312, 314, 316, 318, 320, 322, 324,
/* 0xD8 */ 326, 328, 330, 332, 334, 336, 338, 340,
/* 0xE0 */ 342, 344, 346, 348, 350, 352, 354, 356,
/* 0xE8 */ 358, 360, 362, 364, 366, 368, 370, 372,
/* 0xF0 */ 374, 376, 378, 380, 382, 384, 386, 388,
/* 0xF8 */ 390, 392, 394, 396, 398, 400, 402, 404,
/* sizeof (cp1252_utf8) */ 406
};
/* Check if a string qualifies as UTF-8. */
static int
is_utf8(const char* src)
{
uint8_t ch;
size_t i;
const uint8_t* s = (const uint8_t*) src;
/* We make a loop over every character, until we find a null one.
Remember: The string is supposed to end with a NUL, so ahead checks are safe. */
while ((ch = *s++)) {
/* Ye olde 7bit ASCII chars 'rr fine for anything */
if(ch < 0x80) continue;
/* Now, we watch out for non-UTF conform sequences. */
else if ((ch < 0xC2) || (ch > 0xFD))
return 0;
/* check for some misformed sequences */
if (((ch == 0xC2) && (s[0] < 0xA0)) ||
((ch == 0xEF) && (s[0] == 0xBF) && (s[1] > 0xBD)))
/* XXX add more for outside the BMP */
return 0;
/* Check the continuation bytes. */
if (ch < 0xE0) i = 1;
else if (ch < 0xF0) i = 2;
else if (ch < 0xF8) i = 3;
else if (ch < 0xFC) i = 4;
else
i = 5;
while (i--)
if ((*s++ & 0xC0) != 0x80)
return 0;
}
/* If no check failed, the string indeed looks like valid UTF-8. */
return 1;
}
/* The main conversion routine.
ICY in CP-1252 (or UTF-8 alreay) to UTF-8 encoded string.
If force is applied, it will always encode to UTF-8, without checking. */
char *
icy2utf8(const char *src, int force)
{
const uint8_t *s = (const uint8_t *)src;
size_t srclen, dstlen, i, k;
uint8_t ch, *d;
char *dst;
/* Some funny streams from Apple/iTunes give ICY info in UTF-8 already.
So, be prepared and don't try to re-encode such. Unless forced. */
if(!force && is_utf8(src)) return (compat_strdup(src));
srclen = strlen(src) + 1;
/* allocate conservatively */
if ((d = malloc(srclen * 3)) == NULL)
return (NULL);
i = 0;
dstlen = 0;
while (i < srclen) {
ch = s[i++];
k = tblofs[ch];
while (k < tblofs[ch + 1])
d[dstlen++] = cp1252_utf8[k++];
}
/* dstlen includes trailing NUL since srclen also does */
if ((dst = realloc(d, dstlen)) == NULL) {
free(d);
return (NULL);
}
return (dst);
}
/* This stuff is for testing only. */
#ifdef TEST
static const char intext[] = "\225 Gr\374\337e kosten 0,55 \200\205";
#include <stdio.h>
int
main(void)
{
char *t, *t2;
if ((t = icy2utf8(intext, 0)) == NULL) {
fprintf(stderr, "out of memory\n");
return (1);
}
/* make sure it won't be converted twice */
if ((t2 = icy2utf8(t), 0) == NULL) {
fprintf(stderr, "out of memory\n");
return (1);
}
printf("Result is:\t\343\200\214%s\343\200\215\n"
"\t\t\343\200\214%s\343\200\215\n", t, t2);
free(t);
free(t2);
return (0);
}
#endif

View File

@ -0,0 +1,10 @@
/* You expect a license plate for _this_ file? */
#ifndef MPG123_ICY2UTF_H
#define MPG123_ICY2UTF_H
#ifndef NO_ICY
/* (string, force conversion) */
char *icy2utf8(const char *, int);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,43 @@
/*
id3: ID3v2.3 and ID3v2.4 parsing (a relevant subset)
copyright 2006-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
*/
#ifndef MPG123_ID3_H
#define MPG123_ID3_H
/* really need it _here_! */
#include "frame.h"
#ifdef NO_ID3V2
# ifdef init_id3
# undef init_id3
# endif
# define init_id3(fr)
# ifdef exit_id3
# undef exit_id3
# endif
# define exit_id3(fr)
# ifdef reset_id3
# undef reset_id3
# endif
# define reset_id3(fr)
# ifdef id3_link
# undef id3_link
# endif
# define id3_link(fr)
#else
void init_id3(mpg123_handle *fr);
void exit_id3(mpg123_handle *fr);
void reset_id3(mpg123_handle *fr);
void id3_link(mpg123_handle *fr);
#endif
int parse_new_id3(mpg123_handle *fr, unsigned long first4bytes);
/* Convert text from some ID3 encoding to UTf-8.
On error, sb->fill is 0. The noquiet flag enables warning/error messages. */
void id3_to_utf8(mpg123_string *sb, unsigned char encoding, const unsigned char *source, size_t source_size, int noquiet);
#endif

View File

@ -0,0 +1,136 @@
/*
index: frame index data structure and functions
copyright 2007-2015 by the mpg123 project
-= free software under the terms of the LGPL 2.1 =-
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
*/
#include "intsym.h"
#include "index.h"
#include "debug.h"
/* The next expected frame offset, one step ahead. */
static off_t fi_next(struct frame_index *fi)
{
return (off_t)fi->fill*fi->step;
}
/* Shrink down the used index to the half.
Be careful with size = 1 ... there's no shrinking possible there. */
static void fi_shrink(struct frame_index *fi)
{
if(fi->fill < 2) return; /* Won't shrink below 1. */
else
{ /* Double the step, half the fill. Should work as well for fill%2 = 1 */
size_t c;
debug2("shrink index with fill %lu and step %lu", (unsigned long)fi->fill, (unsigned long)fi->step);
fi->step *= 2;
fi->fill /= 2;
/* Move the data down. */
for(c = 0; c < fi->fill; ++c)
fi->data[c] = fi->data[2*c];
}
fi->next = fi_next(fi);
}
void fi_init(struct frame_index *fi)
{
fi->data = NULL;
fi->step = 1;
fi->fill = 0;
fi->size = 0;
fi->grow_size = 0;
fi->next = fi_next(fi);
}
void fi_exit(struct frame_index *fi)
{
debug2("fi_exit: %p and %lu", (void*)fi->data, (unsigned long)fi->size);
if(fi->size && fi->data != NULL) free(fi->data);
fi_init(fi); /* Be prepared for further fun, still. */
}
int fi_resize(struct frame_index *fi, size_t newsize)
{
off_t *newdata = NULL;
if(newsize == fi->size) return 0;
if(newsize > 0 && newsize < fi->size)
{ /* When we reduce buffer size a bit, shrink stuff. */
while(fi->fill > newsize){ fi_shrink(fi); }
}
newdata = safe_realloc(fi->data, newsize*sizeof(off_t));
if(newsize == 0 || newdata != NULL)
{
fi->data = newdata;
fi->size = newsize;
if(fi->fill > fi->size) fi->fill = fi->size;
fi->next = fi_next(fi);
debug2("new index of size %lu at %p", (unsigned long)fi->size, (void*)fi->data);
return 0;
}
else
{
error("failed to resize index!");
return -1;
}
}
void fi_add(struct frame_index *fi, off_t pos)
{
debug3("wanting to add to fill %lu, step %lu, size %lu", (unsigned long)fi->fill, (unsigned long)fi->step, (unsigned long)fi->size);
if(fi->fill == fi->size)
{ /* Index is full, we need to shrink... or grow. */
/* Store the current frame number to check later if we still want it. */
off_t framenum = fi->fill*fi->step;
/* If we want not / cannot grow, we shrink. */
if( !(fi->grow_size && fi_resize(fi, fi->size+fi->grow_size)==0) )
fi_shrink(fi);
/* Now check if we still want to add this frame (could be that not, because of changed step). */
if(fi->next != framenum) return;
}
/* When we are here, we want that frame. */
if(fi->fill < fi->size) /* safeguard for size=1, or just generally */
{
debug1("adding to index at %p", (void*)(fi->data+fi->fill));
fi->data[fi->fill] = pos;
++fi->fill;
fi->next = fi_next(fi);
debug3("added pos %li to index with fill %lu and step %lu", (long) pos, (unsigned long)fi->fill, (unsigned long)fi->step);
}
}
int fi_set(struct frame_index *fi, off_t *offsets, off_t step, size_t fill)
{
if(fi_resize(fi, fill) == -1) return -1;
fi->step = step;
if(offsets != NULL)
{
memcpy(fi->data, offsets, fill*sizeof(off_t));
fi->fill = fill;
}
else
{
/* allocation only, no entries in index yet */
fi->fill = 0;
}
fi->next = fi_next(fi);
debug3("set new index of fill %lu, size %lu at %p",
(unsigned long)fi->fill, (unsigned long)fi->size, (void*)fi->data);
return 0;
}
void fi_reset(struct frame_index *fi)
{
debug1("reset with size %"SIZE_P, (size_p)fi->size);
fi->fill = 0;
fi->step = 1;
fi->next = fi_next(fi);
}

View File

@ -0,0 +1,59 @@
#ifndef MPG123_H_INDEX
#define MPG123_H_INDEX
/*
index: frame index data structure and functions
This is for keeping track of frame positions for accurate seeking.
Now in it's own file, with initial code from frame.c and parse.c .
The idea of the index with a certain amount of entries is to cover
all yet-encountered frame positions with minimal coarseness.
Meaning: At first every frame position is recorded, then, when
the index is full, every second position is trown away to make
space. Next time it is full, the same happens. And so on.
In this manner we maintain a good resolution with the given
maximum index size while covering the whole stream.
copyright 2007-8 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
*/
#include "config.h"
#include "compat.h"
struct frame_index
{
off_t *data; /* actual data, the frame positions */
off_t step; /* advancement in frame number per index point */
off_t next; /* frame offset supposed to come next into the index */
size_t size; /* total number of possible entries */
size_t fill; /* number of used entries */
size_t grow_size; /* if > 0: index allowed to grow on need with these steps, instead of lowering resolution */
};
/* The condition for a framenum to be appended to the index.
if(FI_NEXT(fr->index, fr->num)) fi_add(offset); */
#define FI_NEXT(fi, framenum) ((fi).size && framenum == (fi).next)
/* Initialize stuff, set things to zero and NULL... */
void fi_init(struct frame_index *fi);
/* Deallocate/zero things. */
void fi_exit(struct frame_index *fi);
/* Prepare a given size, preserving current fill, if possible.
If the new size is smaller than fill, the entry density is reduced.
Return 0 on success. */
int fi_resize(struct frame_index *fi, size_t newsize);
/* Append a frame position, reducing index density if needed. */
void fi_add(struct frame_index *fi, off_t pos);
/* Replace the frame index */
int fi_set(struct frame_index *fi, off_t *offsets, off_t step, size_t fill);
/* Empty the index (setting fill=0 and step=1), but keep current size. */
void fi_reset(struct frame_index *fi);
#endif

View File

@ -0,0 +1,282 @@
/*
l12_integer_tables.h: Layer1/2 Constant tables for integer decoders
copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#ifndef MPG123_L12_INTEGER_TABLES_H
#define MPG123_L12_INTEGER_TABLES_H
static const real layer12_table[27][64] =
{
{ /* C90 does not like empty initializer. Fill with junk. */
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38
, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56
, 57, 58, 59, 60, 61, 62, 63, 64
},
{
-1431655765,-1136305934,-901886617,-715827883,-568152967,-450943309,-357913941,-284076483,
-225471654,-178956971,-142038242,-112735827,-89478485,-71019121,-56367914,-44739243,
-35509560,-28183957,-22369621,-17754780,-14091978,-11184811,-8877390,-7045989,
-5592405,-4438695,-3522995,-2796203,-2219348,-1761497,-1398101,-1109674,
-880749,-699051,-554837,-440374,-349525,-277418,-220187,-174763,
-138709,-110094,-87381,-69355,-55047,-43691,-34677,-27523,
-21845,-17339,-13762,-10923,-8669,-6881,-5461,-4335,
-3440,-2731,-2167,-1720,-1365,-1084,-860,0
},
{
1431655765,1136305934,901886617,715827883,568152967,450943309,357913941,284076483,
225471654,178956971,142038242,112735827,89478485,71019121,56367914,44739243,
35509560,28183957,22369621,17754780,14091978,11184811,8877390,7045989,
5592405,4438695,3522995,2796203,2219348,1761497,1398101,1109674,
880749,699051,554837,440374,349525,277418,220187,174763,
138709,110094,87381,69355,55047,43691,34677,27523,
21845,17339,13762,10923,8669,6881,5461,4335,
3440,2731,2167,1720,1365,1084,860,0
},
{
613566757,486988257,386522836,306783378,243494129,193261418,153391689,121747064,
96630709,76695845,60873532,48315355,38347922,30436766,24157677,19173961,
15218383,12078839,9586981,7609192,6039419,4793490,3804596,3019710,
2396745,1902298,1509855,1198373,951149,754927,599186,475574,
377464,299593,237787,188732,149797,118894,94366,74898,
59447,47183,37449,29723,23591,18725,14862,11796,
9362,7431,5898,4681,3715,2949,2341,1858,
1474,1170,929,737,585,464,369,0
},
{
286331153,227261187,180377323,143165577,113630593,90188662,71582788,56815297,
45094331,35791394,28407648,22547165,17895697,14203824,11273583,8947849,
7101912,5636791,4473924,3550956,2818396,2236962,1775478,1409198,
1118481,887739,704599,559241,443870,352299,279620,221935,
176150,139810,110967,88075,69905,55484,44037,34953,
27742,22019,17476,13871,11009,8738,6935,5505,
4369,3468,2752,2185,1734,1376,1092,867,
688,546,433,344,273,217,172,0
},
{
138547332,109965090,87279350,69273666,54982545,43639675,34636833,27491273,
21819838,17318417,13745636,10909919,8659208,6872818,5454959,4329604,
3436409,2727480,2164802,1718205,1363740,1082401,859102,681870,
541201,429551,340935,270600,214776,170467,135300,107388,
85234,67650,53694,42617,33825,26847,21308,16913,
13423,10654,8456,6712,5327,4228,3356,2664,
2114,1678,1332,1057,839,666,529,419,
333,264,210,166,132,105,83,0
},
{
68174084,54109806,42946982,34087042,27054903,21473491,17043521,13527452,
10736745,8521761,6763726,5368373,4260880,3381863,2684186,2130440,
1690931,1342093,1065220,845466,671047,532610,422733,335523,
266305,211366,167762,133153,105683,83881,66576,52842,
41940,33288,26421,20970,16644,13210,10485,8322,
6605,5243,4161,3303,2621,2081,1651,1311,
1040,826,655,520,413,328,260,206,
164,130,103,82,65,52,41,0
},
{
33818640,26841872,21304408,16909320,13420936,10652204,8454660,6710468,
5326102,4227330,3355234,2663051,2113665,1677617,1331526,1056833,
838809,665763,528416,419404,332881,264208,209702,166441,
132104,104851,83220,66052,52426,41610,33026,26213,
20805,16513,13106,10403,8257,6553,5201,4128,
3277,2601,2064,1638,1300,1032,819,650,
516,410,325,258,205,163,129,102,
81,65,51,41,32,26,20,0
},
{
16843009,13368305,10610431,8421505,6684153,5305215,4210752,3342076,
2652608,2105376,1671038,1326304,1052688,835519,663152,526344,
417760,331576,263172,208880,165788,131586,104440,82894,
65793,52220,41447,32897,26110,20723,16448,13055,
10362,8224,6527,5181,4112,3264,2590,2056,
1632,1295,1028,816,648,514,408,324,
257,204,162,129,102,81,64,51,
40,32,25,20,16,13,10,0
},
{
8405024,6671072,5294833,4202512,3335536,2647417,2101256,1667768,
1323708,1050628,833884,661854,525314,416942,330927,262657,
208471,165464,131329,104236,82732,65664,52118,41366,
32832,26059,20683,16416,13029,10341,8208,6515,
5171,4104,3257,2585,2052,1629,1293,1026,
814,646,513,407,323,257,204,162,
128,102,81,64,51,40,32,25,
20,16,13,10,8,6,5,0
},
{
4198404,3332275,2644829,2099202,1666138,1322414,1049601,833069,
661207,524801,416534,330604,262400,208267,165302,131200,
104134,82651,65600,52067,41325,32800,26033,20663,
16400,13017,10331,8200,6508,5166,4100,3254,
2583,2050,1627,1291,1025,814,646,513,
407,323,256,203,161,128,102,81,
64,51,40,32,25,20,16,13,
10,8,6,5,4,3,3,0
},
{
2098177,1665324,1321768,1049088,832662,660884,524544,416331,
330442,262272,208165,165221,131136,104083,82611,65568,
52041,41305,32784,26021,20653,16392,13010,10326,
8196,6505,5163,4098,3253,2582,2049,1626,
1291,1025,813,645,512,407,323,256,
203,161,128,102,81,64,51,40,
32,25,20,16,13,10,8,6,
5,4,3,3,2,2,1,0
},
{
1048832,832459,660723,524416,416229,330361,262208,208115,
165181,131104,104057,82590,65552,52029,41295,32776,
26014,20648,16388,13007,10324,8194,6504,5162,
4097,3252,2581,2049,1626,1290,1024,813,
645,512,406,323,256,203,161,128,
102,81,64,51,40,32,25,20,
16,13,10,8,6,5,4,3,
3,2,2,1,1,1,1,0
},
{
524352,416178,330321,262176,208089,165161,131088,104045,
82580,65544,52022,41290,32772,26011,20645,16386,
13006,10323,8193,6503,5161,4097,3251,2581,
2048,1626,1290,1024,813,645,512,406,
323,256,203,161,128,102,81,64,
51,40,32,25,20,16,13,10,
8,6,5,4,3,3,2,2,
1,1,1,1,1,0,0,0
},
{
262160,208077,165150,131080,104038,82575,65540,52019,
41288,32770,26010,20644,16385,13005,10322,8193,
6502,5161,4096,3251,2580,2048,1626,1290,
1024,813,645,512,406,323,256,203,
161,128,102,81,64,51,40,32,
25,20,16,13,10,8,6,5,
4,3,3,2,2,1,1,1,
1,1,0,0,0,0,0,0
},
{
131076,104035,82573,65538,52018,41286,32769,26009,
20643,16385,13004,10322,8192,6502,5161,4096,
3251,2580,2048,1626,1290,1024,813,645,
512,406,323,256,203,161,128,102,
81,64,51,40,32,25,20,16,
13,10,8,6,5,4,3,3,
2,2,1,1,1,1,1,0,
0,0,0,0,0,0,0,0
},
{
65537,52017,41286,32769,26008,20643,16384,13004,
10321,8192,6502,5161,4096,3251,2580,2048,
1626,1290,1024,813,645,512,406,323,
256,203,161,128,102,81,64,51,
40,32,25,20,16,13,10,8,
6,5,4,3,3,2,2,1,
1,1,1,1,0,0,0,0,
0,0,0,0,0,0,0,0
},
{
-1717986918,-1363567121,-1082263941,-858993459,-681783560,-541131970,-429496730,-340891780,
-270565985,-214748365,-170445890,-135282993,-107374182,-85222945,-67641496,-53687091,
-42611473,-33820748,-26843546,-21305736,-16910374,-13421773,-10652868,-8455187,
-6710886,-5326434,-4227594,-3355443,-2663217,-2113797,-1677722,-1331609,
-1056898,-838861,-665804,-528449,-419430,-332902,-264225,-209715,
-166451,-132112,-104858,-83226,-66056,-52429,-41613,-33028,
-26214,-20806,-16514,-13107,-10403,-8257,-6554,-5202,
-4129,-3277,-2601,-2064,-1638,-1300,-1032,0
},
{
-858993459,-681783560,-541131970,-429496730,-340891780,-270565985,-214748365,-170445890,
-135282993,-107374182,-85222945,-67641496,-53687091,-42611473,-33820748,-26843546,
-21305736,-16910374,-13421773,-10652868,-8455187,-6710886,-5326434,-4227594,
-3355443,-2663217,-2113797,-1677722,-1331609,-1056898,-838861,-665804,
-528449,-419430,-332902,-264225,-209715,-166451,-132112,-104858,
-83226,-66056,-52429,-41613,-33028,-26214,-20806,-16514,
-13107,-10403,-8257,-6554,-5202,-4129,-3277,-2601,
-2064,-1638,-1300,-1032,-819,-650,-516,0
},
{
858993459,681783560,541131970,429496730,340891780,270565985,214748365,170445890,
135282993,107374182,85222945,67641496,53687091,42611473,33820748,26843546,
21305736,16910374,13421773,10652868,8455187,6710886,5326434,4227594,
3355443,2663217,2113797,1677722,1331609,1056898,838861,665804,
528449,419430,332902,264225,209715,166451,132112,104858,
83226,66056,52429,41613,33028,26214,20806,16514,
13107,10403,8257,6554,5202,4129,3277,2601,
2064,1638,1300,1032,819,650,516,0
},
{
1717986918,1363567121,1082263941,858993459,681783560,541131970,429496730,340891780,
270565985,214748365,170445890,135282993,107374182,85222945,67641496,53687091,
42611473,33820748,26843546,21305736,16910374,13421773,10652868,8455187,
6710886,5326434,4227594,3355443,2663217,2113797,1677722,1331609,
1056898,838861,665804,528449,419430,332902,264225,209715,
166451,132112,104858,83226,66056,52429,41613,33028,
26214,20806,16514,13107,10403,8257,6554,5202,
4129,3277,2601,2064,1638,1300,1032,0
},
{
-1908874354,-1515074579,-1202515490,-954437177,-757537289,-601257745,-477218588,-378768645,
-300628872,-238609294,-189384322,-150314436,-119304647,-94692161,-75157218,-59652324,
-47346081,-37578609,-29826162,-23673040,-18789305,-14913081,-11836520,-9394652,
-7456540,-5918260,-4697326,-3728270,-2959130,-2348663,-1864135,-1479565,
-1174332,-932068,-739783,-587166,-466034,-369891,-293583,-233017,
-184946,-146791,-116508,-92473,-73396,-58254,-46236,-36698,
-29127,-23118,-18349,-14564,-11559,-9174,-7282,-5780,
-4587,-3641,-2890,-2294,-1820,-1445,-1147,0
},
{
-954437177,-757537289,-601257745,-477218588,-378768645,-300628872,-238609294,-189384322,
-150314436,-119304647,-94692161,-75157218,-59652324,-47346081,-37578609,-29826162,
-23673040,-18789305,-14913081,-11836520,-9394652,-7456540,-5918260,-4697326,
-3728270,-2959130,-2348663,-1864135,-1479565,-1174332,-932068,-739783,
-587166,-466034,-369891,-293583,-233017,-184946,-146791,-116508,
-92473,-73396,-58254,-46236,-36698,-29127,-23118,-18349,
-14564,-11559,-9174,-7282,-5780,-4587,-3641,-2890,
-2294,-1820,-1445,-1147,-910,-722,-573,0
},
{
-477218588,-378768645,-300628872,-238609294,-189384322,-150314436,-119304647,-94692161,
-75157218,-59652324,-47346081,-37578609,-29826162,-23673040,-18789305,-14913081,
-11836520,-9394652,-7456540,-5918260,-4697326,-3728270,-2959130,-2348663,
-1864135,-1479565,-1174332,-932068,-739783,-587166,-466034,-369891,
-293583,-233017,-184946,-146791,-116508,-92473,-73396,-58254,
-46236,-36698,-29127,-23118,-18349,-14564,-11559,-9174,
-7282,-5780,-4587,-3641,-2890,-2294,-1820,-1445,
-1147,-910,-722,-573,-455,-361,-287,0
},
{
477218588,378768645,300628872,238609294,189384322,150314436,119304647,94692161,
75157218,59652324,47346081,37578609,29826162,23673040,18789305,14913081,
11836520,9394652,7456540,5918260,4697326,3728270,2959130,2348663,
1864135,1479565,1174332,932068,739783,587166,466034,369891,
293583,233017,184946,146791,116508,92473,73396,58254,
46236,36698,29127,23118,18349,14564,11559,9174,
7282,5780,4587,3641,2890,2294,1820,1445,
1147,910,722,573,455,361,287,0
},
{
954437177,757537289,601257745,477218588,378768645,300628872,238609294,189384322,
150314436,119304647,94692161,75157218,59652324,47346081,37578609,29826162,
23673040,18789305,14913081,11836520,9394652,7456540,5918260,4697326,
3728270,2959130,2348663,1864135,1479565,1174332,932068,739783,
587166,466034,369891,293583,233017,184946,146791,116508,
92473,73396,58254,46236,36698,29127,23118,18349,
14564,11559,9174,7282,5780,4587,3641,2890,
2294,1820,1445,1147,910,722,573,0
},
{
1908874354,1515074579,1202515490,954437177,757537289,601257745,477218588,378768645,
300628872,238609294,189384322,150314436,119304647,94692161,75157218,59652324,
47346081,37578609,29826162,23673040,18789305,14913081,11836520,9394652,
7456540,5918260,4697326,3728270,2959130,2348663,1864135,1479565,
1174332,932068,739783,587166,466034,369891,293583,233017,
184946,146791,116508,92473,73396,58254,46236,36698,
29127,23118,18349,14564,11559,9174,7282,5780,
4587,3641,2890,2294,1820,1445,1147,0
},
};
#endif

View File

@ -0,0 +1,164 @@
/*
l2tables.h: Layer 2 Alloc tables
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
most other tables are calculated on program start (which is (of course) not ISO-conform)
Layer-3 huffman table is in huffman.h
*/
#ifndef _MPG123_L2TABLES_H_
#define _MPG123_L2TABLES_H_
static const 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} };
static const 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} };
static const 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} };
static const 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} };
static const 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} };
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,191 @@
/*
layer1.c: the layer 1 decoder
copyright 1995-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
may have a few bugs after last optimization ...
*/
#include "mpg123lib_intern.h"
#include "getbits.h"
#include "debug.h"
/*
Allocation value is not allowed to be 15. Initially, libmad showed me the
error that mpg123 used to ignore. Then, I found a quote on that in
Shlien, S. (1994): Guide to MPEG-1 Audio Standard.
IEEE Transactions on Broadcasting 40, 4
"To avoid conflicts with the synchronization code, code '1111' is defined
to be illegal."
*/
static int check_balloc(mpg123_handle *fr, unsigned int *balloc, unsigned int *end)
{
unsigned int *ba;
for(ba=balloc; ba != end; ++ba)
if(*ba == 15)
{
if(NOQUIET) error("Illegal bit allocation value.");
return -1;
}
return 0;
}
static int I_step_one(unsigned int balloc[], unsigned int scale_index[2][SBLIMIT],mpg123_handle *fr)
{
unsigned int *ba=balloc;
unsigned int *sca = (unsigned int *) scale_index;
if(fr->stereo == 2)
{
int i;
int jsbound = fr->jsbound;
for(i=0;i<jsbound;i++)
{
*ba++ = getbits(fr, 4);
*ba++ = getbits(fr, 4);
}
for(i=jsbound;i<SBLIMIT;i++) *ba++ = getbits(fr, 4);
if(check_balloc(fr, balloc, ba)) return -1;
ba = balloc;
for(i=0;i<jsbound;i++)
{
if ((*ba++))
*sca++ = getbits(fr, 6);
if ((*ba++))
*sca++ = getbits(fr, 6);
}
for (i=jsbound;i<SBLIMIT;i++)
if((*ba++))
{
*sca++ = getbits(fr, 6);
*sca++ = getbits(fr, 6);
}
}
else
{
int i;
for(i=0;i<SBLIMIT;i++) *ba++ = getbits(fr, 4);
if(check_balloc(fr, balloc, ba)) return -1;
ba = balloc;
for (i=0;i<SBLIMIT;i++)
if ((*ba++))
*sca++ = getbits(fr, 6);
}
return 0;
}
/* Something sane in place of undefined (-1)<<n. Well, not really. */
#define MINUS_SHIFT(n) ( (int)(((unsigned int)-1)<<(n)) )
static void I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT], unsigned int scale_index[2][SBLIMIT],mpg123_handle *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 == 2)
{
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(fr, n+1);
if((n = *ba++)) *sample++ = getbits(fr, n+1);
}
for(i=jsbound;i<SBLIMIT;i++)
if((n = *ba++))
*sample++ = getbits(fr, n+1);
ba = balloc;
for(sample=smpb,i=0;i<jsbound;i++)
{
if((n=*ba++))
*f0++ = REAL_MUL_SCALE_LAYER12(DOUBLE_TO_REAL_15(MINUS_SHIFT(n) + (*sample++) + 1), fr->muls[n+1][*sca++]);
else *f0++ = DOUBLE_TO_REAL(0.0);
if((n=*ba++))
*f1++ = REAL_MUL_SCALE_LAYER12(DOUBLE_TO_REAL_15(MINUS_SHIFT(n) + (*sample++) + 1), fr->muls[n+1][*sca++]);
else *f1++ = DOUBLE_TO_REAL(0.0);
}
for(i=jsbound;i<SBLIMIT;i++)
{
if((n=*ba++))
{
real samp = DOUBLE_TO_REAL_15(MINUS_SHIFT(n) + (*sample++) + 1);
*f0++ = REAL_MUL_SCALE_LAYER12(samp, fr->muls[n+1][*sca++]);
*f1++ = REAL_MUL_SCALE_LAYER12(samp, fr->muls[n+1][*sca++]);
}
else *f0++ = *f1++ = DOUBLE_TO_REAL(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(fr, n+1);
ba = balloc;
for(sample=smpb,i=0;i<SBLIMIT;i++)
{
if((n=*ba++))
*f0++ = REAL_MUL_SCALE_LAYER12(DOUBLE_TO_REAL_15(MINUS_SHIFT(n) + (*sample++) + 1), fr->muls[n+1][*sca++]);
else *f0++ = DOUBLE_TO_REAL(0.0);
}
for(i=fr->down_sample_sblimit;i<32;i++)
fraction[0][i] = DOUBLE_TO_REAL(0.0);
}
}
int do_layer1(mpg123_handle *fr)
{
int clip=0;
int i,stereo = fr->stereo;
unsigned int balloc[2*SBLIMIT];
unsigned int scale_index[2][SBLIMIT];
real (*fraction)[SBLIMIT] = fr->layer1.fraction; /* 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 == SINGLE_MIX) /* I don't see mixing handled here */
single = SINGLE_LEFT;
if(I_step_one(balloc,scale_index,fr))
{
if(NOQUIET) error("Aborting layer I decoding after step one.\n");
return clip;
}
for(i=0;i<SCALE_BLOCK;i++)
{
I_step_two(fraction,balloc,scale_index,fr);
if(single != SINGLE_STEREO)
clip += (fr->synth_mono)(fraction[single], fr);
else
clip += (fr->synth_stereo)(fraction[0], fraction[1], fr);
}
return clip;
}

View File

@ -0,0 +1,371 @@
/*
layer2.c: the layer 2 decoder, root of mpg123
copyright 1994-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
mpg123 started as mp2 decoder a long time ago...
part of this file is required for layer 1, too.
*/
#include "mpg123lib_intern.h"
#ifndef NO_LAYER2
#include "l2tables.h"
#endif
#include "getbits.h"
#ifndef NO_LAYER12 /* Stuff needed for layer I and II. */
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 */
#if defined(REAL_IS_FIXED) && defined(PRECALC_TABLES)
#include "l12_integer_tables.h"
#else
static const 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
};
#endif
void init_layer12(void)
{
const 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;
const int tablen[3] = { 3 , 5 , 9 };
int *itable;
int *tables[3] = { grp_3tab , grp_5tab , grp_9tab };
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];
}
}
}
void init_layer12_stuff(mpg123_handle *fr, real* (*init_table)(mpg123_handle *fr, real *table, int m))
{
int k;
real *table;
for(k=0;k<27;k++)
{
table = init_table(fr, fr->muls[k], k);
*table++ = 0.0;
}
}
real* init_layer12_table(mpg123_handle *fr, real *table, int m)
{
#if defined(REAL_IS_FIXED) && defined(PRECALC_TABLES)
int i;
for(i=0;i<63;i++)
*table++ = layer12_table[m][i];
#else
int i,j;
for(j=3,i=0;i<63;i++,j--)
*table++ = DOUBLE_TO_REAL_SCALE_LAYER12(mulmul[m] * pow(2.0,(double) j / 3.0));
#endif
return table;
}
#ifdef OPT_MMXORSSE
real* init_layer12_table_mmx(mpg123_handle *fr, real *table, int m)
{
int i,j;
if(!fr->p.down_sample)
{
for(j=3,i=0;i<63;i++,j--)
*table++ = DOUBLE_TO_REAL(16384 * mulmul[m] * pow(2.0,(double) j / 3.0));
}
else
{
for(j=3,i=0;i<63;i++,j--)
*table++ = DOUBLE_TO_REAL(mulmul[m] * pow(2.0,(double) j / 3.0));
}
return table;
}
#endif
#endif /* NO_LAYER12 */
/* The rest is the actual decoding of layer II data. */
#ifndef NO_LAYER2
static void II_step_one(unsigned int *bit_alloc,int *scale,mpg123_handle *fr)
{
int stereo = fr->stereo-1;
int sblimit = fr->II_sblimit;
int jsbound = fr->jsbound;
int sblimit2 = fr->II_sblimit<<stereo;
const struct al_table *alloc1 = fr->alloc;
int i;
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))
{
step=alloc1->bits;
*bita++ = (char) getbits(fr, step);
*bita++ = (char) getbits(fr, step);
}
for(i=sblimit-jsbound;i;i--,alloc1+=(1<<step))
{
step=alloc1->bits;
bita[0] = (char) getbits(fr, step);
bita[1] = bita[0];
bita+=2;
}
bita = bit_alloc;
scfsi=scfsi_buf;
for(i=sblimit2;i;i--)
if(*bita++) *scfsi++ = (char) getbits_fast(fr, 2);
}
else /* mono */
{
for(i=sblimit;i;i--,alloc1+=(1<<step))
{
step=alloc1->bits;
*bita++ = (char) getbits(fr, step);
}
bita = bit_alloc;
scfsi=scfsi_buf;
for(i=sblimit;i;i--)
if(*bita++) *scfsi++ = (char) getbits_fast(fr, 2);
}
bita = bit_alloc;
scfsi=scfsi_buf;
for(i=sblimit2;i;i--)
if(*bita++)
switch(*scfsi++)
{
case 0:
*scale++ = getbits_fast(fr, 6);
*scale++ = getbits_fast(fr, 6);
*scale++ = getbits_fast(fr, 6);
break;
case 1 :
*scale++ = sc = getbits_fast(fr, 6);
*scale++ = sc;
*scale++ = getbits_fast(fr, 6);
break;
case 2:
*scale++ = sc = getbits_fast(fr, 6);
*scale++ = sc;
*scale++ = sc;
break;
default: /* case 3 */
*scale++ = getbits_fast(fr, 6);
*scale++ = sc = getbits_fast(fr, 6);
*scale++ = sc;
break;
}
}
static void II_step_two(unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int *scale,mpg123_handle *fr,int x1)
{
int i,j,k,ba;
int stereo = fr->stereo;
int sblimit = fr->II_sblimit;
int jsbound = fr->jsbound;
const 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=fr->muls[k][scale[x1]];
fraction[j][0][i] = REAL_MUL_SCALE_LAYER12(DOUBLE_TO_REAL_15((int)getbits(fr, k) + d1), cm);
fraction[j][1][i] = REAL_MUL_SCALE_LAYER12(DOUBLE_TO_REAL_15((int)getbits(fr, k) + d1), cm);
fraction[j][2][i] = REAL_MUL_SCALE_LAYER12(DOUBLE_TO_REAL_15((int)getbits(fr, k) + d1), cm);
}
else
{
const 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(fr, k);
tab = (unsigned int *) (table[d1] + idx + idx + idx);
fraction[j][0][i] = REAL_SCALE_LAYER12(fr->muls[*tab++][m]);
fraction[j][1][i] = REAL_SCALE_LAYER12(fr->muls[*tab++][m]);
fraction[j][2][i] = REAL_SCALE_LAYER12(fr->muls[*tab][m]);
}
scale+=3;
}
else
fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = DOUBLE_TO_REAL(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=fr->muls[k][scale[x1+3]];
fraction[0][0][i] = DOUBLE_TO_REAL_15((int)getbits(fr, k) + d1);
fraction[0][1][i] = DOUBLE_TO_REAL_15((int)getbits(fr, k) + d1);
fraction[0][2][i] = DOUBLE_TO_REAL_15((int)getbits(fr, k) + d1);
fraction[1][0][i] = REAL_MUL_SCALE_LAYER12(fraction[0][0][i], cm);
fraction[1][1][i] = REAL_MUL_SCALE_LAYER12(fraction[0][1][i], cm);
fraction[1][2][i] = REAL_MUL_SCALE_LAYER12(fraction[0][2][i], cm);
cm=fr->muls[k][scale[x1]];
fraction[0][0][i] = REAL_MUL_SCALE_LAYER12(fraction[0][0][i], cm);
fraction[0][1][i] = REAL_MUL_SCALE_LAYER12(fraction[0][1][i], cm);
fraction[0][2][i] = REAL_MUL_SCALE_LAYER12(fraction[0][2][i], cm);
}
else
{
const 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(fr, k);
tab = (unsigned int *) (table[d1] + idx + idx + idx);
fraction[0][0][i] = REAL_SCALE_LAYER12(fr->muls[*tab][m1]); fraction[1][0][i] = REAL_SCALE_LAYER12(fr->muls[*tab++][m2]);
fraction[0][1][i] = REAL_SCALE_LAYER12(fr->muls[*tab][m1]); fraction[1][1][i] = REAL_SCALE_LAYER12(fr->muls[*tab++][m2]);
fraction[0][2][i] = REAL_SCALE_LAYER12(fr->muls[*tab][m1]); fraction[1][2][i] = REAL_SCALE_LAYER12(fr->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] = DOUBLE_TO_REAL(0.0);
}
/*
Historic comment...
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] = DOUBLE_TO_REAL(0.0);
}
static void II_select_table(mpg123_handle *fr)
{
const 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;
const struct al_table *tables[5] = { alloc_0, alloc_1, alloc_2, alloc_3 , alloc_4 };
const int sblims[5] = { 27 , 30 , 8, 12 , 30 };
if(fr->sampling_frequency >= 3) /* Or equivalent: (fr->lsf == 1) */
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(mpg123_handle *fr)
{
int clip=0;
int i,j;
int stereo = fr->stereo;
/* pick_table clears unused subbands */
/* replacement for real fraction[2][4][SBLIMIT], needs alignment. */
real (*fraction)[4][SBLIMIT] = fr->layer2.fraction;
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(fr->jsbound > fr->II_sblimit)
{
fprintf(stderr, "Truncating stereo boundary to sideband limit.\n");
fr->jsbound=fr->II_sblimit;
}
/* TODO: What happens with mono mixing, actually? */
if(stereo == 1 || single == SINGLE_MIX) /* also, mix not really handled */
single = SINGLE_LEFT;
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 != SINGLE_STEREO)
clip += (fr->synth_mono)(fraction[single][j], fr);
else
clip += (fr->synth_stereo)(fraction[0][j], fraction[1][j], fr);
}
}
return clip;
}
#endif /* NO_LAYER2 */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,228 @@
/*
lfs_alias: Aliases to the small/native API functions with the size of long int as suffix.
copyright 2010-2013 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
Use case: Client code on Linux/x86-64 that defines _FILE_OFFSET_BITS to 64,
which is the only choice on that platform anyway. It should be no-op, but
prompts the platform-agnostic header of mpg123 to define API calls with the
corresponding suffix. This file provides the names for this case. It's cruft,
but glibc does it, too -- so people rely on it.
Oh, and it also caters for the lunatics that define _FILE_OFFSET_BITS=32 on
32 bit platforms. In addition, it's needed for platforms that always have
off_t /= long, and clients still insisting on defining _FILE_OFFSET_BITS.
Depending on use case, the aliases map to 32 (small) or 64 bit (large) offset
functions, to the ones from libmpg123 or the ones from lfs_wrap.
So, two basic cases:
1. mpg123_bla_32 alias for mpg123_bla (native)
2. mpg123_bla alias for mpg123_bla_32 (wrapper)
Same for 64 bits. Confusing, I know. It sucks.
Note that the mpg123 header is _not_ used here to avoid definition with whacky off_t.
The aliases are always about arguments of native alias_t type. This can be off_t, but
on Linux/x86, this is long int. The off_t declarations in mpg123.h confuse things,
so reproduce definitions for the wrapper functions in that case. The definitions are
pulled by an inline Perl script in any case ... no need to copy anything manually!
As a benefit, one can skip undefining possible largefile namings.
*/
#include "config.h"
/* Hack for Solaris: Some system headers included from compat.h might force _FILE_OFFSET_BITS. Need to follow that here.
Also, want it around to have types defined. */
#include "compat.h"
#ifndef LFS_ALIAS_BITS
#error "I need the count of alias bits here."
#endif
#define MACROCAT_REALLY(a, b) a ## b
#define MACROCAT(a, b) MACROCAT_REALLY(a, b)
/* This is wicked switchery: Decide which way the aliases are facing. */
#if _FILE_OFFSET_BITS+0 == LFS_ALIAS_BITS
/* The native functions have suffix, the aliases not. */
#define NATIVE_SUFFIX MACROCAT(_, _FILE_OFFSET_BITS)
#define NATIVE_NAME(func) MACROCAT(func, NATIVE_SUFFIX)
#define ALIAS_NAME(func) func
#else
/* The alias functions have suffix, the native ones not. */
#define ALIAS_SUFFIX MACROCAT(_, LFS_ALIAS_BITS)
#define ALIAS_NAME(func) MACROCAT(func, ALIAS_SUFFIX)
#define NATIVE_NAME(func) func
#endif
/* Copy of necessary definitions, actually just forward declarations. */
struct mpg123_handle_struct;
typedef struct mpg123_handle_struct mpg123_handle;
/* Get attribute_align_arg, to stay safe. */
#include "abi_align.h"
/*
Extract the list of functions we need wrappers for, pregenerating the wrappers for simple cases (inline script for nedit):
perl -ne '
if(/^\s*MPG123_EXPORT\s+(\S+)\s+(mpg123_\S+)\((.*)\);\s*$/)
{
my $type = $1;
my $name = $2;
my $args = $3;
next unless ($type =~ /off_t/ or $args =~ /off_t/ or ($name =~ /open/ and $name ne mpg123_open_feed));
$type =~ s/off_t/lfs_alias_t/g;
my @nargs = ();
$args =~ s/off_t/lfs_alias_t/g;
foreach my $a (split(/,/, $args))
{
$a =~ s/^.*\s\**([a-z_]+)$/$1/;
push(@nargs, $a);
}
my $nargs = join(", ", @nargs);
$nargs = "Human: figure me out." if($nargs =~ /\(/);
print <<EOT
$type NATIVE_NAME($name)($args);
$type attribute_align_arg ALIAS_NAME($name)($args)
{
return NATIVE_NAME($name)($nargs);
}
EOT
}' < mpg123.h.in
*/
int NATIVE_NAME(mpg123_open)(mpg123_handle *mh, const char *path);
int attribute_align_arg ALIAS_NAME(mpg123_open)(mpg123_handle *mh, const char *path)
{
return NATIVE_NAME(mpg123_open)(mh, path);
}
int NATIVE_NAME(mpg123_open_fd)(mpg123_handle *mh, int fd);
int attribute_align_arg ALIAS_NAME(mpg123_open_fd)(mpg123_handle *mh, int fd)
{
return NATIVE_NAME(mpg123_open_fd)(mh, fd);
}
int NATIVE_NAME(mpg123_open_handle)(mpg123_handle *mh, void *iohandle);
int attribute_align_arg ALIAS_NAME(mpg123_open_handle)(mpg123_handle *mh, void *iohandle)
{
return NATIVE_NAME(mpg123_open_handle)(mh, iohandle);
}
int NATIVE_NAME(mpg123_decode_frame)(mpg123_handle *mh, lfs_alias_t *num, unsigned char **audio, size_t *bytes);
int attribute_align_arg ALIAS_NAME(mpg123_decode_frame)(mpg123_handle *mh, lfs_alias_t *num, unsigned char **audio, size_t *bytes)
{
return NATIVE_NAME(mpg123_decode_frame)(mh, num, audio, bytes);
}
int NATIVE_NAME(mpg123_framebyframe_decode)(mpg123_handle *mh, lfs_alias_t *num, unsigned char **audio, size_t *bytes);
int attribute_align_arg ALIAS_NAME(mpg123_framebyframe_decode)(mpg123_handle *mh, lfs_alias_t *num, unsigned char **audio, size_t *bytes)
{
return NATIVE_NAME(mpg123_framebyframe_decode)(mh, num, audio, bytes);
}
lfs_alias_t NATIVE_NAME(mpg123_framepos)(mpg123_handle *mh);
lfs_alias_t attribute_align_arg ALIAS_NAME(mpg123_framepos)(mpg123_handle *mh)
{
return NATIVE_NAME(mpg123_framepos)(mh);
}
lfs_alias_t NATIVE_NAME(mpg123_tell)(mpg123_handle *mh);
lfs_alias_t attribute_align_arg ALIAS_NAME(mpg123_tell)(mpg123_handle *mh)
{
return NATIVE_NAME(mpg123_tell)(mh);
}
lfs_alias_t NATIVE_NAME(mpg123_tellframe)(mpg123_handle *mh);
lfs_alias_t attribute_align_arg ALIAS_NAME(mpg123_tellframe)(mpg123_handle *mh)
{
return NATIVE_NAME(mpg123_tellframe)(mh);
}
lfs_alias_t NATIVE_NAME(mpg123_tell_stream)(mpg123_handle *mh);
lfs_alias_t attribute_align_arg ALIAS_NAME(mpg123_tell_stream)(mpg123_handle *mh)
{
return NATIVE_NAME(mpg123_tell_stream)(mh);
}
lfs_alias_t NATIVE_NAME(mpg123_seek)(mpg123_handle *mh, lfs_alias_t sampleoff, int whence);
lfs_alias_t attribute_align_arg ALIAS_NAME(mpg123_seek)(mpg123_handle *mh, lfs_alias_t sampleoff, int whence)
{
return NATIVE_NAME(mpg123_seek)(mh, sampleoff, whence);
}
lfs_alias_t NATIVE_NAME(mpg123_feedseek)(mpg123_handle *mh, lfs_alias_t sampleoff, int whence, lfs_alias_t *input_offset);
lfs_alias_t attribute_align_arg ALIAS_NAME(mpg123_feedseek)(mpg123_handle *mh, lfs_alias_t sampleoff, int whence, lfs_alias_t *input_offset)
{
return NATIVE_NAME(mpg123_feedseek)(mh, sampleoff, whence, input_offset);
}
lfs_alias_t NATIVE_NAME(mpg123_seek_frame)(mpg123_handle *mh, lfs_alias_t frameoff, int whence);
lfs_alias_t attribute_align_arg ALIAS_NAME(mpg123_seek_frame)(mpg123_handle *mh, lfs_alias_t frameoff, int whence)
{
return NATIVE_NAME(mpg123_seek_frame)(mh, frameoff, whence);
}
lfs_alias_t NATIVE_NAME(mpg123_timeframe)(mpg123_handle *mh, double sec);
lfs_alias_t attribute_align_arg ALIAS_NAME(mpg123_timeframe)(mpg123_handle *mh, double sec)
{
return NATIVE_NAME(mpg123_timeframe)(mh, sec);
}
int NATIVE_NAME(mpg123_index)(mpg123_handle *mh, lfs_alias_t **offsets, lfs_alias_t *step, size_t *fill);
int attribute_align_arg ALIAS_NAME(mpg123_index)(mpg123_handle *mh, lfs_alias_t **offsets, lfs_alias_t *step, size_t *fill)
{
return NATIVE_NAME(mpg123_index)(mh, offsets, step, fill);
}
int NATIVE_NAME(mpg123_set_index)(mpg123_handle *mh, lfs_alias_t *offsets, lfs_alias_t step, size_t fill);
int attribute_align_arg ALIAS_NAME(mpg123_set_index)(mpg123_handle *mh, lfs_alias_t *offsets, lfs_alias_t step, size_t fill)
{
return NATIVE_NAME(mpg123_set_index)(mh, offsets, step, fill);
}
int NATIVE_NAME(mpg123_position)( mpg123_handle *mh, lfs_alias_t frame_offset, lfs_alias_t buffered_bytes, lfs_alias_t *current_frame, lfs_alias_t *frames_left, double *current_seconds, double *seconds_left);
int attribute_align_arg ALIAS_NAME(mpg123_position)( mpg123_handle *mh, lfs_alias_t frame_offset, lfs_alias_t buffered_bytes, lfs_alias_t *current_frame, lfs_alias_t *frames_left, double *current_seconds, double *seconds_left)
{
return NATIVE_NAME(mpg123_position)(mh, frame_offset, buffered_bytes, current_frame, frames_left, current_seconds, seconds_left);
}
lfs_alias_t NATIVE_NAME(mpg123_framelength)(mpg123_handle *mh);
lfs_alias_t attribute_align_arg ALIAS_NAME(mpg123_framelength)(mpg123_handle *mh)
{
return NATIVE_NAME(mpg123_framelength)(mh);
}
lfs_alias_t NATIVE_NAME(mpg123_length)(mpg123_handle *mh);
lfs_alias_t attribute_align_arg ALIAS_NAME(mpg123_length)(mpg123_handle *mh)
{
return NATIVE_NAME(mpg123_length)(mh);
}
int NATIVE_NAME(mpg123_set_filesize)(mpg123_handle *mh, lfs_alias_t size);
int attribute_align_arg ALIAS_NAME(mpg123_set_filesize)(mpg123_handle *mh, lfs_alias_t size)
{
return NATIVE_NAME(mpg123_set_filesize)(mh, size);
}
int NATIVE_NAME(mpg123_replace_reader)(mpg123_handle *mh, ssize_t (*r_read) (int, void *, size_t), lfs_alias_t (*r_lseek)(int, lfs_alias_t, int));
int attribute_align_arg ALIAS_NAME(mpg123_replace_reader)(mpg123_handle *mh, ssize_t (*r_read) (int, void *, size_t), lfs_alias_t (*r_lseek)(int, lfs_alias_t, int))
{
return NATIVE_NAME(mpg123_replace_reader)(mh, r_read, r_lseek);
}
int NATIVE_NAME(mpg123_replace_reader_handle)(mpg123_handle *mh, ssize_t (*r_read) (void *, void *, size_t), lfs_alias_t (*r_lseek)(void *, lfs_alias_t, int), void (*cleanup)(void*));
int attribute_align_arg ALIAS_NAME(mpg123_replace_reader_handle)(mpg123_handle *mh, ssize_t (*r_read) (void *, void *, size_t), lfs_alias_t (*r_lseek)(void *, lfs_alias_t, int), void (*cleanup)(void*))
{
return NATIVE_NAME(mpg123_replace_reader_handle)(mh, r_read, r_lseek, cleanup);
}

View File

@ -0,0 +1,768 @@
/*
lfs_wrap: Crappy wrapper code for supporting crappy ambiguous large file support.
copyright 2010 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis, thanks to Guido Draheim for consulting
This file contains wrappers for the case that _FILE_OFFSET_BITS (or equivalent, theoretically, depends on mpg123.h) is defined and thus certain mpg123 API calls get renamed with a suffix (p.ex. _64).
The renamed calls expect large off_t arguments, and possibly return large off_t values... these wrappers here provide the same functionality with long integer arguments/values.
Prototypical idea: There is
off_t mpg123_seek_64(mpg123_handle*, off_t, int)
This code provides
long mpg123_seek(mpg123_handle*, long, int)
This is rather simple business... wouldn't mpg123 offer replacing the I/O core with callbacks. Translating the callbacks between long and off_t world is the main reason why this file contains non-trivial code.
Note about file descriptors: We just assume that they are generally interchangeable between large and small file code... and that a large file descriptor will trigger errors when accessed with small file code where it may cause trouble (a really large file).
*/
/* It mainly needs the official API ... */
/* ... but also some inside access (frame struct, readers). */
#include "mpg123lib_intern.h"
/* Include the system headers _after_ the implied config.h!
Otherwise _FILE_OFFSET_BITS is not in effect! */
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "compat.h"
#include "debug.h"
/*
Now, start off easy... translate simple API calls.
I need to deal with these here:
perl -ne '
if(/^\s*MPG123_EXPORT\s+(\S+)\s+(mpg123_\S+)\((.*)\);\s*$/)
{
$type = $1;
$name = $2;
$args = $3;
next unless ($type =~ /off_t/ or $args =~ /off_t/);
print "$name\n" unless grep {$_ eq $name}
("mpg123_open", "mpg123_open_fd", "mpg123_open_handle", "mpg123_replace_reader", "mpg123_replace_reader_handle");
}' < mpg123.h.in
mpg123_decode_frame
mpg123_framebyframe_decode
mpg123_framepos
mpg123_tell
mpg123_tellframe
mpg123_tell_stream
mpg123_seek
mpg123_feedseek
mpg123_seek_frame
mpg123_timeframe
mpg123_index
mpg123_set_index
mpg123_position
mpg123_length
mpg123_set_filesize
mpg123_decode_raw ... that's experimental.
Let's work on them in that order.
*/
/* I see that I will need custom data storage. Main use is for the replaced I/O later, but the seek table for small file offsets needs extra storage, too. */
/* The wrapper handle for descriptor and handle I/O. */
/* The handle is used for nothing (0), or one of these two modes of operation: */
#define IO_FD 1 /* Wrapping over callbacks operation on integer file descriptor. */
#define IO_HANDLE 2 /* Wrapping over custom handle callbacks. */
struct wrap_data
{
/* Storage for small offset index table. */
long *indextable;
/* I/O handle stuff */
int iotype; /* IO_FD or IO_HANDLE */
/* Data for IO_FD. */
int fd;
int my_fd; /* A descriptor that the wrapper code opened itself. */
/* The actual callbacks from the outside. */
ssize_t (*r_read) (int, void *, size_t);
long (*r_lseek)(int, long, int);
/* Data for IO_HANDLE. */
void* handle;
ssize_t (*r_h_read)(void *, void *, size_t);
long (*r_h_lseek)(void*, long, int);
void (*h_cleanup)(void*);
};
/* Cleanup I/O part of the handle handle... but not deleting the wrapper handle itself.
That is stored in the frame and only deleted on mpg123_delete(). */
static void wrap_io_cleanup(void *handle)
{
struct wrap_data *ioh = handle;
if(ioh->iotype == IO_HANDLE)
{
if(ioh->h_cleanup != NULL && ioh->handle != NULL)
ioh->h_cleanup(ioh->handle);
ioh->handle = NULL;
}
if(ioh->my_fd >= 0)
{
close(ioh->my_fd);
ioh->my_fd = -1;
}
}
/* Really finish off the handle... freeing all memory. */
static void wrap_destroy(void *handle)
{
struct wrap_data *wh = handle;
wrap_io_cleanup(handle);
if(wh->indextable != NULL)
free(wh->indextable);
free(wh);
}
/* More helper code... extract the special wrapper handle, possible allocate and initialize it. */
static struct wrap_data* wrap_get(mpg123_handle *mh)
{
struct wrap_data* whd;
if(mh == NULL) return NULL;
/* Access the private storage inside the mpg123 handle.
The real callback functions and handles are stored there. */
if(mh->wrapperdata == NULL)
{
/* Create a new one. */
mh->wrapperdata = malloc(sizeof(struct wrap_data));
if(mh->wrapperdata == NULL)
{
mh->err = MPG123_OUT_OF_MEM;
return NULL;
}
/* When we have wrapper data present, the callback for its proper cleanup is needed. */
mh->wrapperclean = wrap_destroy;
whd = mh->wrapperdata;
whd->indextable = NULL;
whd->iotype = 0;
whd->fd = -1;
whd->my_fd = -1;
whd->r_read = NULL;
whd->r_lseek = NULL;
whd->handle = NULL;
whd->r_h_read = NULL;
whd->r_h_lseek = NULL;
whd->h_cleanup = NULL;
}
else whd = mh->wrapperdata;
return whd;
}
/* After settling the data... start with some simple wrappers. */
#undef mpg123_decode_frame
/* int mpg123_decode_frame(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes) */
int attribute_align_arg mpg123_decode_frame(mpg123_handle *mh, long *num, unsigned char **audio, size_t *bytes)
{
off_t largenum;
int err;
err = MPG123_LARGENAME(mpg123_decode_frame)(mh, &largenum, audio, bytes);
if(err == MPG123_OK && num != NULL)
{
*num = largenum;
if(*num != largenum)
{
mh->err = MPG123_LFS_OVERFLOW;
err = MPG123_ERR;
}
}
return err;
}
#undef mpg123_framebyframe_decode
/* int mpg123_framebyframe_decode(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes); */
int attribute_align_arg mpg123_framebyframe_decode(mpg123_handle *mh, long *num, unsigned char **audio, size_t *bytes)
{
off_t largenum;
int err;
err = MPG123_LARGENAME(mpg123_framebyframe_decode)(mh, &largenum, audio, bytes);
if(err == MPG123_OK && num != NULL)
{
*num = largenum;
if(*num != largenum)
{
mh->err = MPG123_LFS_OVERFLOW;
err = MPG123_ERR;
}
}
return err;
}
#undef mpg123_framepos
/* off_t mpg123_framepos(mpg123_handle *mh); */
long attribute_align_arg mpg123_framepos(mpg123_handle *mh)
{
long val;
off_t largeval;
largeval = MPG123_LARGENAME(mpg123_framepos)(mh);
val = largeval;
if(val != largeval)
{
mh->err = MPG123_LFS_OVERFLOW;
return MPG123_ERR;
}
return val;
}
#undef mpg123_tell
/* off_t mpg123_tell(mpg123_handle *mh); */
long attribute_align_arg mpg123_tell(mpg123_handle *mh)
{
long val;
off_t largeval;
largeval = MPG123_LARGENAME(mpg123_tell)(mh);
val = largeval;
if(val != largeval)
{
mh->err = MPG123_LFS_OVERFLOW;
return MPG123_ERR;
}
return val;
}
#undef mpg123_tellframe
/* off_t mpg123_tellframe(mpg123_handle *mh); */
long attribute_align_arg mpg123_tellframe(mpg123_handle *mh)
{
long val;
off_t largeval;
largeval = MPG123_LARGENAME(mpg123_tellframe)(mh);
val = largeval;
if(val != largeval)
{
mh->err = MPG123_LFS_OVERFLOW;
return MPG123_ERR;
}
return val;
}
#undef mpg123_tell_stream
/* off_t mpg123_tell_stream(mpg123_handle *mh); */
long attribute_align_arg mpg123_tell_stream(mpg123_handle *mh)
{
long val;
off_t largeval;
largeval = MPG123_LARGENAME(mpg123_tell_stream)(mh);
val = largeval;
if(val != largeval)
{
mh->err = MPG123_LFS_OVERFLOW;
return MPG123_ERR;
}
return val;
}
#undef mpg123_seek
/* off_t mpg123_seek(mpg123_handle *mh, off_t sampleoff, int whence); */
long attribute_align_arg mpg123_seek(mpg123_handle *mh, long sampleoff, int whence)
{
long val;
off_t largeval;
largeval = MPG123_LARGENAME(mpg123_seek)(mh, sampleoff, whence);
val = largeval;
if(val != largeval)
{
mh->err = MPG123_LFS_OVERFLOW;
return MPG123_ERR;
}
return val;
}
#undef mpg123_feedseek
/* off_t mpg123_feedseek(mpg123_handle *mh, off_t sampleoff, int whence, off_t *input_offset); */
long attribute_align_arg mpg123_feedseek(mpg123_handle *mh, long sampleoff, int whence, long *input_offset)
{
long val;
off_t largeioff;
off_t largeval;
largeval = MPG123_LARGENAME(mpg123_feedseek)(mh, sampleoff, whence, &largeioff);
/* Error/message codes are small... */
if(largeval < 0) return (long)largeval;
val = largeval;
*input_offset = largeioff;
if(val != largeval || *input_offset != largeioff)
{
mh->err = MPG123_LFS_OVERFLOW;
return MPG123_ERR;
}
return val;
}
#undef mpg123_seek_frame
/* off_t mpg123_seek_frame(mpg123_handle *mh, off_t frameoff, int whence); */
long attribute_align_arg mpg123_seek_frame(mpg123_handle *mh, long frameoff, int whence)
{
long val;
off_t largeval;
largeval = MPG123_LARGENAME(mpg123_seek_frame)(mh, frameoff, whence);
val = largeval;
if(val != largeval)
{
mh->err = MPG123_LFS_OVERFLOW;
return MPG123_ERR;
}
return val;
}
#undef mpg123_timeframe
/* off_t mpg123_timeframe(mpg123_handle *mh, double sec); */
long attribute_align_arg mpg123_timeframe(mpg123_handle *mh, double sec)
{
long val;
off_t largeval;
largeval = MPG123_LARGENAME(mpg123_timeframe)(mh, sec);
val = largeval;
if(val != largeval)
{
mh->err = MPG123_LFS_OVERFLOW;
return MPG123_ERR;
}
return val;
}
/* Now something less simple: Index retrieval and manipulation.
The index is an _array_ of off_t, which means that I need to construct a copy with translated long values. */
#undef mpg123_index
/* int mpg123_index(mpg123_handle *mh, off_t **offsets, off_t *step, size_t *fill) */
int attribute_align_arg mpg123_index(mpg123_handle *mh, long **offsets, long *step, size_t *fill)
{
int err;
size_t i;
long smallstep;
size_t thefill;
off_t largestep;
off_t *largeoffsets;
struct wrap_data *whd;
whd = wrap_get(mh);
if(whd == NULL) return MPG123_ERR;
err = MPG123_LARGENAME(mpg123_index)(mh, &largeoffsets, &largestep, &thefill);
if(err != MPG123_OK) return err;
/* For a _very_ large file, even the step could overflow. */
smallstep = largestep;
if(smallstep != largestep)
{
mh->err = MPG123_LFS_OVERFLOW;
return MPG123_ERR;
}
if(step != NULL) *step = smallstep;
/* When there are no values stored, there is no table content to take care of.
Table pointer does not matter. Mission completed. */
if(thefill == 0) return MPG123_OK;
if(fill != NULL) *fill = thefill;
/* Construct a copy of the index to hand over to the small-minded client. */
*offsets = safe_realloc(whd->indextable, (*fill)*sizeof(long));
if(*offsets == NULL)
{
mh->err = MPG123_OUT_OF_MEM;
return MPG123_ERR;
}
whd->indextable = *offsets;
/* Elaborate conversion of each index value, with overflow check. */
for(i=0; i<*fill; ++i)
{
whd->indextable[i] = largeoffsets[i];
if(whd->indextable[i] != largeoffsets[i])
{
mh->err = MPG123_LFS_OVERFLOW;
return MPG123_ERR;
}
}
/* If we came that far... there should be a valid copy of the table now. */
return MPG123_OK;
}
/* The writing does basically the same than the above, just the opposite.
Oh, and the overflow checks are not needed -- off_t is bigger than long. */
#undef mpg123_set_index
/* int mpg123_set_index(mpg123_handle *mh, off_t *offsets, off_t step, size_t fill); */
int attribute_align_arg mpg123_set_index(mpg123_handle *mh, long *offsets, long step, size_t fill)
{
int err;
size_t i;
struct wrap_data *whd;
off_t *indextmp;
whd = wrap_get(mh);
if(whd == NULL) return MPG123_ERR;
/* Expensive temporary storage... for staying outside at the API layer. */
indextmp = malloc(fill*sizeof(off_t));
if(indextmp == NULL)
{
mh->err = MPG123_OUT_OF_MEM;
return MPG123_ERR;
}
if(fill > 0 && offsets == NULL)
{
mh->err = MPG123_BAD_INDEX_PAR;
err = MPG123_ERR;
}
else
{
/* Fill the large-file copy of the provided index, then feed it to mpg123. */
for(i=0; i<fill; ++i)
indextmp[i] = offsets[i];
err = MPG123_LARGENAME(mpg123_set_index)(mh, indextmp, step, fill);
}
free(indextmp);
return err;
}
/* So... breathe... a couple of simple wrappers before the big mess. */
#undef mpg123_position
/* int mpg123_position( mpg123_handle *mh, off_t frame_offset, off_t buffered_bytes, off_t *current_frame, off_t *frames_left, double *current_seconds, double *seconds_left); */
int attribute_align_arg mpg123_position(mpg123_handle *mh, long frame_offset, long buffered_bytes, long *current_frame, long *frames_left, double *current_seconds, double *seconds_left)
{
off_t curframe, frameleft;
long small_curframe, small_frameleft;
int err;
err = MPG123_LARGENAME(mpg123_position)(mh, frame_offset, buffered_bytes, &curframe, &frameleft, current_seconds, seconds_left);
if(err != MPG123_OK) return err;
small_curframe = curframe;
small_frameleft = frameleft;
if(small_curframe != curframe || small_frameleft != frameleft)
{
mh->err = MPG123_LFS_OVERFLOW;
return MPG123_ERR;
}
if(current_frame != NULL) *current_frame = small_curframe;
if(frames_left != NULL) *frames_left = small_frameleft;
return MPG123_OK;
}
#undef mpg123_framelength
/* off_t mpg123_framelength(mpg123_handle *mh); */
long attribute_align_arg mpg123_framelength(mpg123_handle *mh)
{
long val;
off_t largeval;
largeval = MPG123_LARGENAME(mpg123_framelength)(mh);
val = largeval;
if(val != largeval)
{
mh->err = MPG123_LFS_OVERFLOW;
return MPG123_ERR;
}
return val;
}
#undef mpg123_length
/* off_t mpg123_length(mpg123_handle *mh); */
long attribute_align_arg mpg123_length(mpg123_handle *mh)
{
long val;
off_t largeval;
largeval = MPG123_LARGENAME(mpg123_length)(mh);
val = largeval;
if(val != largeval)
{
mh->err = MPG123_LFS_OVERFLOW;
return MPG123_ERR;
}
return val;
}
/* The simplest wrapper of all... */
#undef mpg123_set_filesize
/* int mpg123_set_filesize(mpg123_handle *mh, off_t size); */
int attribute_align_arg mpg123_set_filesize(mpg123_handle *mh, long size)
{
return MPG123_LARGENAME(mpg123_set_filesize)(mh, size);
}
/* =========================================
THE BOUNDARY OF SANITY
Behold, stranger!
========================================= */
/*
The messy part: Replacement of I/O core (actally, this is only due to lseek()).
Both descriptor and handle replaced I/O are mapped to replaced handle I/O, the handle wrapping over the actual callbacks and the actual handle/descriptor.
You got multiple levels of handles and callbacks to think about. Have fun reading and comprehending.
*/
/* Could go into compat.h ... Windows needs that flag. */
#ifndef O_BINARY
#define O_BINARY 0
#endif
/* Read callback needs nothing special. */
ssize_t wrap_read(void* handle, void *buf, size_t count)
{
struct wrap_data *ioh = handle;
switch(ioh->iotype)
{
case IO_FD: return ioh->r_read(ioh->fd, buf, count);
case IO_HANDLE: return ioh->r_h_read(ioh->handle, buf, count);
}
error("Serious breakage - bad IO type in LFS wrapper!");
return -1;
}
/* Seek callback needs protection from too big offsets. */
off_t wrap_lseek(void *handle, off_t offset, int whence)
{
struct wrap_data *ioh = handle;
long smalloff = offset;
if(smalloff == offset)
{
switch(ioh->iotype)
{
case IO_FD: return ioh->r_lseek(ioh->fd, smalloff, whence);
case IO_HANDLE: return ioh->r_h_lseek(ioh->handle, smalloff, whence);
}
error("Serious breakage - bad IO type in LFS wrapper!");
return -1;
}
else
{
errno = EOVERFLOW;
return -1;
}
}
/*
Now, let's replace the API dealing with replacement I/O.
Start with undefining the renames...
*/
#undef mpg123_replace_reader
#undef mpg123_replace_reader_handle
#undef mpg123_open
#undef mpg123_open_fd
#undef mpg123_open_handle
/* Normal reader replacement needs fallback implementations. */
static ssize_t fallback_read(int fd, void *buf, size_t count)
{
return read(fd, buf, count);
}
static long fallback_lseek(int fd, long offset, int whence)
{
/* Since the offset is long int already, the returned value really should fit into a long... but whatever. */
long newpos_long;
off_t newpos;
newpos = lseek(fd, offset, whence);
newpos_long = newpos;
if(newpos_long == newpos)
return newpos_long;
else
{
errno = EOVERFLOW;
return -1;
}
}
/* Reader replacement prepares the hidden handle storage for next mpg123_open_fd() or plain mpg123_open(). */
int attribute_align_arg mpg123_replace_reader(mpg123_handle *mh, ssize_t (*r_read) (int, void *, size_t), long (*r_lseek)(int, long, int) )
{
struct wrap_data* ioh;
if(mh == NULL) return MPG123_ERR;
mpg123_close(mh);
ioh = wrap_get(mh);
if(ioh == NULL) return MPG123_ERR;
/* If both callbacks are NULL, switch totally to internal I/O, else just use fallback for at most half of them. */
if(r_read == NULL && r_lseek == NULL)
{
/* Only the type is actually important to disable the code. */
ioh->iotype = 0;
ioh->fd = -1;
ioh->r_read = NULL;
ioh->r_lseek = NULL;
}
else
{
ioh->iotype = IO_FD;
ioh->fd = -1; /* On next mpg123_open_fd(), this gets a value. */
ioh->r_read = r_read != NULL ? r_read : fallback_read;
ioh->r_lseek = r_lseek != NULL ? r_lseek : fallback_lseek;
}
/* The real reader replacement will happen while opening. */
return MPG123_OK;
}
int attribute_align_arg mpg123_replace_reader_handle(mpg123_handle *mh, ssize_t (*r_read) (void*, void *, size_t), long (*r_lseek)(void*, long, int), void (*cleanup)(void*))
{
struct wrap_data* ioh;
if(mh == NULL) return MPG123_ERR;
mpg123_close(mh);
ioh = wrap_get(mh);
if(ioh == NULL) return MPG123_ERR;
ioh->iotype = IO_HANDLE;
ioh->handle = NULL;
ioh->r_h_read = r_read;
ioh->r_h_lseek = r_lseek;
ioh->h_cleanup = cleanup;
/* The real reader replacement will happen while opening. */
return MPG123_OK;
}
/*
The open routines always need to watch out for a prepared wrapper handle to use replaced normal I/O.
Two cases to consider:
1. Plain normal open using internal I/O.
2. Client called mpg123_replace_reader() before.
The second case needs hackery to activate the client I/O callbacks. For that, we create a custom I/O handle and use the guts of mpg123_open_fd() on it.
*/
int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path)
{
struct wrap_data* ioh;
if(mh == NULL) return MPG123_ERR;
ioh = mh->wrapperdata;
/* Mimic the use of mpg123_replace_reader() functions by lower levels...
IO_HANDLE is not valid here, though. Only IO_FD. */
if(ioh != NULL && ioh->iotype == IO_FD)
{
int err;
err = MPG123_LARGENAME(mpg123_replace_reader_handle)(mh, wrap_read, wrap_lseek, wrap_io_cleanup);
if(err != MPG123_OK) return MPG123_ERR;
/* The above call implied mpg123_close() already */
/*
I really need to open the file here... to be able to use the replacer handle I/O ...
my_fd is used to indicate closing of the descriptor on cleanup.
*/
ioh->my_fd = compat_open(path, O_RDONLY|O_BINARY);
if(ioh->my_fd < 0)
{
if(!(mh->p.flags & MPG123_QUIET)) error2("Cannot open file %s: %s", path, strerror(errno));
mh->err = MPG123_BAD_FILE;
return MPG123_ERR;
}
/* Store a copy of the descriptor where it is actually used. */
ioh->fd = ioh->my_fd;
/* Initiate I/O operating on my handle now. */
err = open_stream_handle(mh, ioh);
if(err != MPG123_OK)
{
wrap_io_cleanup(ioh);
return MPG123_ERR;
}
/* All fine... */
return MPG123_OK;
}
else return MPG123_LARGENAME(mpg123_open)(mh, path);
}
/*
This is in fact very similar to the above:
The open routines always need to watch out for a prepared wrapper handle to use replaced normal I/O.
Two cases to consider:
1. Plain normal open_fd using internal I/O.
2. Client called mpg123_replace_reader() before.
The second case needs hackery to activate the client I/O callbacks. For that, we create a custom I/O handle and use the guts of mpg123_open_fd() on it.
*/
int attribute_align_arg mpg123_open_fd(mpg123_handle *mh, int fd)
{
struct wrap_data* ioh;
if(mh == NULL) return MPG123_ERR;
mpg123_close(mh);
ioh = mh->wrapperdata;
if(ioh != NULL && ioh->iotype == IO_FD)
{
int err;
err = MPG123_LARGENAME(mpg123_replace_reader_handle)(mh, wrap_read, wrap_lseek, wrap_io_cleanup);
if(err != MPG123_OK) return MPG123_ERR;
/* The above call implied mpg123_close() already */
/* Store the real file descriptor inside the handle. */
ioh->fd = fd;
/* Initiate I/O operating on my handle now. */
err = open_stream_handle(mh, ioh);
if(err != MPG123_OK)
{
wrap_io_cleanup(ioh);
return MPG123_ERR;
}
/* All fine... */
return MPG123_OK;
}
else return MPG123_LARGENAME(mpg123_open_fd)(mh, fd);
}
int attribute_align_arg mpg123_open_handle(mpg123_handle *mh, void *handle)
{
struct wrap_data* ioh;
if(mh == NULL) return MPG123_ERR;
mpg123_close(mh);
ioh = mh->wrapperdata;
if(ioh != NULL && ioh->iotype == IO_HANDLE && ioh->r_h_read != NULL)
{
/* Wrap the custom handle into my handle. */
int err;
err = MPG123_LARGENAME(mpg123_replace_reader_handle)(mh, wrap_read, wrap_lseek, wrap_io_cleanup);
if(err != MPG123_OK) return MPG123_ERR;
ioh->handle = handle;
/* No extra error handling, keep behaviour of the original open_handle. */
return open_stream_handle(mh, ioh);
}
else
{
/* This is an error ... you need to prepare the I/O before using it. */
mh->err = MPG123_BAD_CUSTOM_IO;
return MPG123_ERR;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,199 @@
/*
mangle: support defines for preprocessed assembler
copyright 1995-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
This once started out as mangle.h from MPlayer, but you can't really call it derived work... the small part that in principle stems from MPlayer also being not very special (once you decided to use such a header at all, it's quite obvious material).
*/
#ifndef __MANGLE_H
#define __MANGLE_H
#include "config.h"
#include "intsym.h"
#if (defined OPT_I486) || (defined OPT_I586) || (defined OPT_I586_DITHER) \
|| (defined OPT_MMX) || (defined OPT_SSE) || (defined OPT_3DNOW) || (defined OPT_3DNOWEXT) \
|| (defined OPT_3DNOW_VINTAGE) || (defined OPT_3DNOWEXT_VINTAGE) \
|| (defined OPT_SSE_VINTAGE)
#define OPT_X86
#endif
#ifdef CCALIGN
#define MOVUAPS movaps
#else
#define MOVUAPS movups
#endif
/*
ALIGNX: align to X bytes
This differs per compiler/platform in taking the byte count or an exponent for base 2.
A way out is balign, if the assembler supports it (gas extension).
*/
#ifdef ASMALIGN_BALIGN
#define ALIGN4 .balign 4
#define ALIGN8 .balign 8
#define ALIGN16 .balign 16
#define ALIGN32 .balign 32
#define ALIGN64 .balign 64
#else
#ifdef ASMALIGN_EXP
#define ALIGN4 .align 2
#define ALIGN8 .align 3
#define ALIGN16 .align 4
#define ALIGN32 .align 5
#define ALIGN64 .align 6
#else
#ifdef ASMALIGN_BYTE
#define ALIGN4 .align 4
#define ALIGN8 .align 8
#define ALIGN16 .align 16
#define ALIGN32 .align 32
#define ALIGN64 .align 64
#else
#ifdef ASMALIGN_ARMASM
#define ALIGN4 ALIGN 4
#define ALIGN8 ALIGN 8
#define ALIGN16 ALIGN 16
#define ALIGN32 ALIGN 32
#define ALIGN64 ALIGN 64
#else
#error "Dunno how assembler alignment works. Please specify."
#endif
#endif
#endif
#endif
#define MANGLE_MACROCAT_REALLY(a, b) a ## b
#define MANGLE_MACROCAT(a, b) MANGLE_MACROCAT_REALLY(a, b)
/* Feel free to add more to the list, eg. a.out IMO */
#if defined(__USER_LABEL_PREFIX__)
#define ASM_NAME(a) MANGLE_MACROCAT(__USER_LABEL_PREFIX__,a)
#define ASM_VALUE(a) MANGLE_MACROCAT($,ASM_NAME(a))
#elif defined(__CYGWIN__) || defined(_WIN32) && !defined (_WIN64) && !defined (_M_ARM) || defined(__OS2__) || \
(defined(__OpenBSD__) && !defined(__ELF__)) || defined(__APPLE__)
#define ASM_NAME(a) MANGLE_MACROCAT(_,a)
#define ASM_VALUE(a) MANGLE_MACROCAT($_,a)
#else
#define ASM_NAME(a) a
#define ASM_VALUE(a) MANGLE_MACROCAT($,a)
#endif
/* Enable position-independent code for certain platforms. */
#if defined(OPT_X86)
#define _EBX_ %ebx
#if defined(PIC) && defined(__ELF__)
/* ELF binaries (Unix/Linux) */
#define LOCAL_VAR(a) a ## @GOTOFF(_EBX_)
#define GLOBAL_VAR(a) ASM_NAME(a) ## @GOTOFF(_EBX_)
#define GLOBAL_VAR_PTR(a) ASM_NAME(a) ## @GOT(_EBX_)
#define FUNC(a) ASM_NAME(a)
#define EXTERNAL_FUNC(a) ASM_NAME(a) ## @PLT
#undef ASM_VALUE
#define ASM_VALUE(a) MANGLE_MACROCAT($,a) ##@GOTOFF
#define GET_GOT \
call 1f; \
1: \
pop _EBX_; \
2: \
addl $_GLOBAL_OFFSET_TABLE_ + (2b-1b), _EBX_
#define PREPARE_GOT pushl _EBX_
#define RESTORE_GOT popl _EBX_
#elif defined(PIC) && defined(__APPLE__)
/* Mach-O binaries (OSX/iOS) */
#define LOCAL_VAR(a) a ## - Lpic_base(_EBX_)
#define GLOBAL_VAR(a) #error This ABI cannot access non-local symbols directly.
#define GLOBAL_VAR_PTR(a) L_ ## a ## - Lpic_base(_EBX_)
#define FUNC(a) L_ ## a
#define EXTERNAL_FUNC(a) L_ ## a
#define GET_GOT \
call Lpic_base; \
Lpic_base: \
pop _EBX_
#define PREPARE_GOT pushl _EBX_
#define RESTORE_GOT popl _EBX_
#else
/* Dummies for everyone else. */
#define LOCAL_VAR(a) a
#define GLOBAL_VAR ASM_NAME
#define GLOBAL_VAR_PTR(a) #error Cannot use indirect addressing in non-PIC object.
#define FUNC ASM_NAME
#define EXTERNAL_FUNC ASM_NAME
#define GET_GOT
#define PREPARE_GOT
#define RESTORE_GOT
#endif /* PIC variants */
#endif /* OPT_X86 */
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__APPLE__)
#define COMM(a,b,c) .comm a,b
#else
#define COMM(a,b,c) .comm a,b,c
#endif
/* more hacks for macosx; no .bss ... */
#ifdef __APPLE__
#define BSS .data
#else
#define BSS .bss
#endif
/* armasm for WIN32 UWP */
#ifdef _M_ARM
#define GLOBAL_SYMBOL EXPORT
#else
#define GLOBAL_SYMBOL .globl
#endif
/* Mark non-executable stack.
It's mainly for GNU on Linux... who else does (not) like this? */
#if !defined(__SUNPRO_C) && defined(__linux__) && defined(__ELF__)
#if defined(__arm__)
#define NONEXEC_STACK .section .note.GNU-stack,"",%progbits
#else
#define NONEXEC_STACK .section .note.GNU-stack,"",@progbits
#endif
#else
#define NONEXEC_STACK
#endif
#if (defined(__x86_64__) || defined(_M_X64)) && (defined(_WIN64) || defined (__CYGWIN__))
#define IS_MSABI 1 /* Not using SYSV */
#endif
/* Macros for +-4GiB PC-relative addressing on AArch64 */
#ifdef __APPLE__
#define AARCH64_PCREL_HI(label) label@PAGE
#define AARCH64_PCREL_LO(label) label@PAGEOFF
#else
#define AARCH64_PCREL_HI(label) label
#define AARCH64_PCREL_LO(label) :lo12:label
#endif
#ifdef __APPLE__
#define AARCH64_DUP_4S(dst, src, elem) dup.4s dst, src[elem]
#define AARCH64_DUP_2D(dst, src, elem) dup.2d dst, src[elem]
#define AARCH64_SQXTN2_8H(dst, src) sqxtn2.8h dst, src
#else
#define AARCH64_DUP_4S(dst, src, elem) dup dst.4s, src.s[elem]
#define AARCH64_DUP_2D(dst, src, elem) dup dst.2d, src.d[elem]
#define AARCH64_SQXTN2_8H(dst, src) sqxtn2 dst.8h, src.4s
#endif
#endif /* !__MANGLE_H */

View File

@ -0,0 +1,89 @@
/*
mpeghead: the bits of an MPEG frame header
copyright ?-2011 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp & Thomas Orgis (from parse.c)
*/
#ifndef MPG123_MPEGHEAD_H
#define MPG123_MPEGHEAD_H
/*
Avoid human error, let perl do the work of dissecting an MPEG header into parts.
To be clear: Never edit the following definitions by hand, modify the code block inside this comment and run it through perl instead!
$head = "AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM";
%parts = qw(A sync B version C layer D crc E bitrate F samplerate G padding H private I channel J chanex K copyright L original M emphasis);
for(sort keys %parts)
{
$name = uc($parts{$_});
$bits = $head;
$bits =~ s/$_/1/g;
$bits =~ s/[^1 ]/0/g;
print "\/\* $bits \*\/\n";
$bits =~ s/\s//g;
print "#define HDR_$name".(" " x (18-length($name))).sprintf("0x%08x", eval("0b$bits"))."\n";
$bits =~ m/(0*)$/;
print "#define HDR_${name}_VAL(h)".(" " x (11-length($name)))."(((h)\&HDR_$name) >> ".length($1).")\n";
}
*/
/* 11111111 11100000 00000000 00000000 */
#define HDR_SYNC 0xffe00000
#define HDR_SYNC_VAL(h) (((h)&HDR_SYNC) >> 21)
/* 00000000 00011000 00000000 00000000 */
#define HDR_VERSION 0x00180000
#define HDR_VERSION_VAL(h) (((h)&HDR_VERSION) >> 19)
/* 00000000 00000110 00000000 00000000 */
#define HDR_LAYER 0x00060000
#define HDR_LAYER_VAL(h) (((h)&HDR_LAYER) >> 17)
/* 00000000 00000001 00000000 00000000 */
#define HDR_CRC 0x00010000
#define HDR_CRC_VAL(h) (((h)&HDR_CRC) >> 16)
/* 00000000 00000000 11110000 00000000 */
#define HDR_BITRATE 0x0000f000
#define HDR_BITRATE_VAL(h) (((h)&HDR_BITRATE) >> 12)
/* 00000000 00000000 00001100 00000000 */
#define HDR_SAMPLERATE 0x00000c00
#define HDR_SAMPLERATE_VAL(h) (((h)&HDR_SAMPLERATE) >> 10)
/* 00000000 00000000 00000010 00000000 */
#define HDR_PADDING 0x00000200
#define HDR_PADDING_VAL(h) (((h)&HDR_PADDING) >> 9)
/* 00000000 00000000 00000001 00000000 */
#define HDR_PRIVATE 0x00000100
#define HDR_PRIVATE_VAL(h) (((h)&HDR_PRIVATE) >> 8)
/* 00000000 00000000 00000000 11000000 */
#define HDR_CHANNEL 0x000000c0
#define HDR_CHANNEL_VAL(h) (((h)&HDR_CHANNEL) >> 6)
/* 00000000 00000000 00000000 00110000 */
#define HDR_CHANEX 0x00000030
#define HDR_CHANEX_VAL(h) (((h)&HDR_CHANEX) >> 4)
/* 00000000 00000000 00000000 00001000 */
#define HDR_COPYRIGHT 0x00000008
#define HDR_COPYRIGHT_VAL(h) (((h)&HDR_COPYRIGHT) >> 3)
/* 00000000 00000000 00000000 00000100 */
#define HDR_ORIGINAL 0x00000004
#define HDR_ORIGINAL_VAL(h) (((h)&HDR_ORIGINAL) >> 2)
/* 00000000 00000000 00000000 00000011 */
#define HDR_EMPHASIS 0x00000003
#define HDR_EMPHASIS_VAL(h) (((h)&HDR_EMPHASIS) >> 0)
/*
A generic mask for telling if a header is somewhat valid for the current stream.
Meaning: Most basic info is not allowed to change.
Checking of channel count needs to be done, too, though. So,
if channel count matches, frames are decoded the same way: frame buffers and decoding
routines can stay the same, especially frame buffers (think spf * channels!).
*/
#define HDR_CMPMASK (HDR_SYNC|HDR_VERSION|HDR_LAYER|HDR_SAMPLERATE)
/* A stricter mask, for matching free format headers. */
#define HDR_SAMEMASK (HDR_SYNC|HDR_VERSION|HDR_LAYER|HDR_BITRATE|HDR_SAMPLERATE|HDR_CHANNEL|HDR_CHANEX)
/* Free format headers have zero bitrate value. */
#define HDR_FREE_FORMAT(head) (!(head & HDR_BITRATE))
/* A mask for changed sampling rate (version or rate bits). */
#define HDR_SAMPMASK (HDR_VERSION|HDR_SAMPLERATE)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,312 @@
/*
mpg123lib_intern: Common non-public stuff for libmpg123
copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
derived from the old mpg123.h
*/
#ifndef MPG123_H_INTERN
#define MPG123_H_INTERN
#define MPG123_RATES 9
#define MPG123_ENCODINGS 12
#include "config.h" /* Load this before _anything_ */
#include "intsym.h" /* Prefixing of internal symbols that still are public in a static lib. */
#include "abi_align.h"
/* export DLL symbols */
#if defined(WIN32) && defined(DYNAMIC_BUILD)
#define BUILD_MPG123_DLL
#endif
#include "compat.h"
#include "mpg123.h"
#define SKIP_JUNK 1
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
#ifndef M_SQRT2
# define M_SQRT2 1.41421356237309504880
#endif
#ifdef SUNOS
#define memmove(dst,src,size) bcopy(src,dst,size)
#endif
/* We don't really do long double... there are 3 options for REAL:
float, long and double. */
#ifdef REAL_IS_FLOAT
# define real float
#elif defined(REAL_IS_FIXED)
# define real int32_t
# define dreal int64_t
/*
for fixed-point decoders, use pre-calculated tables to avoid expensive floating-point maths
undef this macro for run-time calculation
*/
#define PRECALC_TABLES
# define REAL_RADIX 24
# define REAL_FACTOR 16777216.0
static inline int32_t double_to_long_rounded(double x, double scalefac)
{
x *= scalefac;
x += (x > 0) ? 0.5 : -0.5;
return (int32_t)x;
}
static inline int32_t scale_rounded(int32_t x, int shift)
{
x += (x >> 31);
x >>= (shift - 1);
x += (x & 1);
return (x >> 1);
}
# ifdef __GNUC__
# if defined(OPT_I386)
/* for i386_nofpu decoder */
# define REAL_MUL_ASM(x, y, radix) \
({ \
long _x=(x), _y=(y); \
__asm__ ( \
"imull %1 \n\t" \
"shrdl %2, %%edx, %0 \n\t" \
: "+&a" (_x) \
: "mr" (_y), "I" (radix) \
: "%edx", "cc" \
); \
_x; \
})
# define REAL_MUL_SCALE_LAYER3_ASM(x, y, radix) \
({ \
long _x=(x), _y=(y), _radix=(radix); \
__asm__ ( \
"imull %1 \n\t" \
"shrdl %%cl, %%edx, %0 \n\t" \
: "+&a" (_x) \
: "mr" (_y), "c" (_radix) \
: "%edx", "cc" \
); \
_x; \
})
# elif defined(OPT_PPC)
/* for powerpc */
# define REAL_MUL_ASM(x, y, radix) \
({ \
long _x=(x), _y=(y), _mull, _mulh; \
__asm__ ( \
"mullw %0, %2, %3 \n\t" \
"mulhw %1, %2, %3 \n\t" \
"srwi %0, %0, %4 \n\t" \
"rlwimi %0, %1, %5, 0, %6 \n\t" \
: "=&r" (_mull), "=&r" (_mulh) \
: "r" (_x), "r" (_y), "i" (radix), "i" (32-(radix)), "i" ((radix)-1) \
); \
_mull; \
})
# define REAL_MUL_SCALE_LAYER3_ASM(x, y, radix) \
({ \
long _x=(x), _y=(y), _radix=(radix), _mull, _mulh, _radix2; \
__asm__ ( \
"mullw %0, %3, %4 \n\t" \
"mulhw %1, %3, %4 \n\t" \
"subfic %2, %5, 32 \n\t" \
"srw %0, %0, %5 \n\t" \
"slw %1, %1, %2 \n\t" \
"or %0, %0, %1 \n\t" \
: "=&r" (_mull), "=&r" (_mulh), "=&r" (_radix2) \
: "r" (_x), "r" (_y), "r" (_radix) \
: "cc" \
); \
_mull; \
})
# elif defined(OPT_ARM)
/* for arm */
# define REAL_MUL_ASM(x, y, radix) \
({ \
long _x=(x), _y=(y), _mull, _mulh; \
__asm__ ( \
"smull %0, %1, %2, %3 \n\t" \
"mov %0, %0, lsr %4 \n\t" \
"orr %0, %0, %1, lsl %5 \n\t" \
: "=&r" (_mull), "=&r" (_mulh) \
: "r" (_x), "r" (_y), "M" (radix), "M" (32-(radix)) \
); \
_mull; \
})
# define REAL_MUL_SCALE_LAYER3_ASM(x, y, radix) \
({ \
long _x=(x), _y=(y), _radix=(radix), _mull, _mulh, _radix2; \
__asm__ ( \
"smull %0, %1, %3, %4 \n\t" \
"mov %0, %0, lsr %5 \n\t" \
"rsb %2, %5, #32 \n\t" \
"mov %1, %1, lsl %2 \n\t" \
"orr %0, %0, %1 \n\t" \
: "=&r" (_mull), "=&r" (_mulh), "=&r" (_radix2) \
: "r" (_x), "r" (_y), "r" (_radix) \
); \
_mull; \
})
# endif
# endif
/* I just changed the (int) to (real) there... seemed right. */
# define DOUBLE_TO_REAL(x) (double_to_long_rounded(x, REAL_FACTOR))
# define DOUBLE_TO_REAL_15(x) (double_to_long_rounded(x, 32768.0))
# define DOUBLE_TO_REAL_POW43(x) (double_to_long_rounded(x, 8192.0))
# define DOUBLE_TO_REAL_SCALE_LAYER12(x) (double_to_long_rounded(x, 1073741824.0))
# define DOUBLE_TO_REAL_SCALE_LAYER3(x, y) (double_to_long_rounded(x, pow(2.0,gainpow2_scale[y])))
# define REAL_TO_DOUBLE(x) ((double)(x) / REAL_FACTOR)
# ifdef REAL_MUL_ASM
# define REAL_MUL(x, y) REAL_MUL_ASM(x, y, REAL_RADIX)
# define REAL_MUL_15(x, y) REAL_MUL_ASM(x, y, 15)
# define REAL_MUL_SCALE_LAYER12(x, y) REAL_MUL_ASM(x, y, 15 + 30 - REAL_RADIX)
# else
# define REAL_MUL(x, y) (((dreal)(x) * (dreal)(y)) >> REAL_RADIX)
# define REAL_MUL_15(x, y) (((dreal)(x) * (dreal)(y)) >> 15)
# define REAL_MUL_SCALE_LAYER12(x, y) (((dreal)(x) * (dreal)(y)) >> (15 + 30 - REAL_RADIX))
# endif
# ifdef REAL_MUL_SCALE_LAYER3_ASM
# define REAL_MUL_SCALE_LAYER3(x, y, z) REAL_MUL_SCALE_LAYER3_ASM(x, y, 13 + gainpow2_scale[z] - REAL_RADIX)
# else
# define REAL_MUL_SCALE_LAYER3(x, y, z) (((dreal)(x) * (dreal)(y)) >> (13 + gainpow2_scale[z] - REAL_RADIX))
# endif
# define REAL_SCALE_LAYER12(x) ((real)((x) >> (30 - REAL_RADIX)))
# define REAL_SCALE_LAYER3(x, y) ((real)((x) >> (gainpow2_scale[y] - REAL_RADIX)))
# ifdef ACCURATE_ROUNDING
# define REAL_MUL_SYNTH(x, y) REAL_MUL(x, y)
# define REAL_SCALE_DCT64(x) (x)
# define REAL_SCALE_WINDOW(x) (x)
# else
# define REAL_MUL_SYNTH(x, y) ((x) * (y))
# define REAL_SCALE_DCT64(x) ((x) >> 8)
# define REAL_SCALE_WINDOW(x) scale_rounded(x, 16)
# endif
#else
/* Just define a symbol to make things clear.
Existing code still uses (not (float or fixed)) for that. */
# define REAL_IS_DOUBLE
# define real double
#endif
#ifndef REAL_IS_FIXED
# if (defined SIZEOF_INT32_T) && (SIZEOF_INT32_T != 4)
# error "Bad 32bit types!!!"
# endif
#endif
#ifndef DOUBLE_TO_REAL
# define DOUBLE_TO_REAL(x) (real)(x)
#endif
#ifndef DOUBLE_TO_REAL_15
# define DOUBLE_TO_REAL_15(x) (real)(x)
#endif
#ifndef DOUBLE_TO_REAL_POW43
# define DOUBLE_TO_REAL_POW43(x) (real)(x)
#endif
#ifndef DOUBLE_TO_REAL_SCALE_LAYER12
# define DOUBLE_TO_REAL_SCALE_LAYER12(x) (real)(x)
#endif
#ifndef DOUBLE_TO_REAL_SCALE_LAYER3
# define DOUBLE_TO_REAL_SCALE_LAYER3(x, y) (real)(x)
#endif
#ifndef REAL_TO_DOUBLE
# define REAL_TO_DOUBLE(x) (x)
#endif
#ifndef REAL_MUL
# define REAL_MUL(x, y) ((x) * (y))
#endif
#ifndef REAL_MUL_SYNTH
# define REAL_MUL_SYNTH(x, y) ((x) * (y))
#endif
#ifndef REAL_MUL_15
# define REAL_MUL_15(x, y) ((x) * (y))
#endif
#ifndef REAL_MUL_SCALE_LAYER12
# define REAL_MUL_SCALE_LAYER12(x, y) ((x) * (y))
#endif
#ifndef REAL_MUL_SCALE_LAYER3
# define REAL_MUL_SCALE_LAYER3(x, y, z) ((x) * (y))
#endif
#ifndef REAL_SCALE_LAYER12
# define REAL_SCALE_LAYER12(x) (x)
#endif
#ifndef REAL_SCALE_LAYER3
# define REAL_SCALE_LAYER3(x, y) (x)
#endif
#ifndef REAL_SCALE_DCT64
# define REAL_SCALE_DCT64(x) (x)
#endif
/* used to be: AUDIOBUFSIZE = n*64 with n=1,2,3 ...
now: factor on minimum frame buffer size (which takes upsampling into account) */
#define AUDIOBUFSIZE 2
#include "true.h"
#define MAX_NAME_SIZE 81
#define SBLIMIT 32
#define SCALE_BLOCK 12
#define SSLIMIT 18
/* Same as MPG_M_* */
#define MPG_MD_STEREO 0
#define MPG_MD_JOINT_STEREO 1
#define MPG_MD_DUAL_CHANNEL 2
#define MPG_MD_MONO 3
/* We support short or float output samples...
Short integer amplitude is scaled by this. */
#define SHORT_SCALE 32768
/* That scales a short-scaled value to a 32bit integer scaled one
value = 2**31/2**15 */
#define S32_RESCALE 65536
/* Pre Shift fo 16 to 8 bit converter table */
#define AUSHIFT (3)
#include "optimize.h"
#include "decode.h"
#include "parse.h"
#include "frame.h"
/* fr is a mpg123_handle* by convention here... */
#define NOQUIET (!(fr->p.flags & MPG123_QUIET))
#define VERBOSE (NOQUIET && fr->p.verbose)
#define VERBOSE2 (NOQUIET && fr->p.verbose > 1)
#define VERBOSE3 (NOQUIET && fr->p.verbose > 2)
#define VERBOSE4 (NOQUIET && fr->p.verbose > 3)
#define PVERB(mp, level) (!((mp)->flags & MPG123_QUIET) && (mp)->verbose >= (level))
int decode_update(mpg123_handle *mh);
/* residing in format.c */
off_t decoder_synth_bytes(mpg123_handle *fr , off_t s);
off_t samples_to_bytes(mpg123_handle *fr , off_t s);
off_t bytes_to_samples(mpg123_handle *fr , off_t b);
off_t outblock_bytes(mpg123_handle *fr, off_t s);
/* Postprocessing format conversion of freshly decoded buffer. */
void postprocess_buffer(mpg123_handle *fr);
/* If networking is enabled and we really mean internal networking, the timeout_read function is available. */
#if defined (NETWORK) && !defined (WANT_WIN32_SOCKETS)
/* Does not work with win32 */
#define TIMEOUT_READ
#endif
#endif

View File

@ -0,0 +1,824 @@
/*
nwehuffman.h: optimized huffman tables (radix-4 lookup)
copyright 1995-2013 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Taihei Monma
*/
#ifndef _MPG123_NEWHUFFMAN_H_
#define _MPG123_NEWHUFFMAN_H_
struct newhuff
{
unsigned int linbits;
const short *table;
};
static const short tab0_[] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
static const short tab1_[] =
{
0x0311, 0x0311, 0x0301, 0x0301, 0x0210, 0x0210, 0x0210, 0x0210,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
};
static const short tab2_[] =
{
-16, -32, 0x0311, 0x0311, 0x0301, 0x0301, 0x0310, 0x0310,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0222, 0x0222, 0x0222, 0x0222, 0x0202, 0x0202, 0x0202, 0x0202,
0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112,
0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121,
0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120,
};
static const short tab3_[] =
{
-16, -32, 0x0310, 0x0310, 0x0211, 0x0211, 0x0211, 0x0211,
0x0201, 0x0201, 0x0201, 0x0201, 0x0200, 0x0200, 0x0200, 0x0200,
0x0222, 0x0222, 0x0222, 0x0222, 0x0202, 0x0202, 0x0202, 0x0202,
0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112,
0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121,
0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120
};
static const short tab5_[] =
{
-16, -32, 0x0311, 0x0311, 0x0301, 0x0301, 0x0310, 0x0310,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0433, 0x0423, 0x0332, 0x0332, 0x0231, 0x0231, 0x0231, 0x0231,
0x0313, 0x0313, 0x0303, 0x0303, 0x0330, 0x0330, 0x0322, 0x0322,
0x0212, 0x0212, 0x0212, 0x0212, 0x0221, 0x0221, 0x0221, 0x0221,
0x0202, 0x0202, 0x0202, 0x0202, 0x0220, 0x0220, 0x0220, 0x0220,
};
static const short tab6_[] =
{
-16, -32, -48, 0x0412, 0x0421, 0x0420, 0x0301, 0x0301,
0x0211, 0x0211, 0x0211, 0x0211, 0x0310, 0x0310, 0x0300, 0x0300,
0x0333, 0x0333, 0x0303, 0x0303, 0x0223, 0x0223, 0x0223, 0x0223,
0x0232, 0x0232, 0x0232, 0x0232, 0x0230, 0x0230, 0x0230, 0x0230,
0x0113, 0x0113, 0x0113, 0x0113, 0x0113, 0x0113, 0x0113, 0x0113,
0x0131, 0x0131, 0x0131, 0x0131, 0x0131, 0x0131, 0x0131, 0x0131,
0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
};
static const short tab7_[] =
{
-16, -32, -48, 0x0411, 0x0301, 0x0301, 0x0310, 0x0310,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
-48, -64, -80, 0x0415, 0x0451, -96, 0x0450, -112,
0x0424, 0x0442, 0x0314, 0x0314, 0x0341, 0x0341, 0x0340, 0x0340,
0x0404, 0x0423, 0x0432, 0x0403, 0x0313, 0x0313, 0x0331, 0x0331,
0x0330, 0x0330, 0x0322, 0x0322, 0x0212, 0x0212, 0x0212, 0x0212,
0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121,
0x0202, 0x0202, 0x0202, 0x0202, 0x0220, 0x0220, 0x0220, 0x0220,
0x0255, 0x0255, 0x0255, 0x0255, 0x0245, 0x0245, 0x0245, 0x0245,
0x0254, 0x0254, 0x0254, 0x0254, 0x0253, 0x0253, 0x0253, 0x0253,
0x0135, 0x0135, 0x0135, 0x0135, 0x0135, 0x0135, 0x0135, 0x0135,
0x0144, 0x0144, 0x0144, 0x0144, 0x0144, 0x0144, 0x0144, 0x0144,
0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125,
0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152,
0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105,
0x0134, 0x0134, 0x0134, 0x0134, 0x0134, 0x0134, 0x0134, 0x0134,
0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143,
0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133,
};
static const short tab8_[] =
{
-16, -32, 0x0412, 0x0421, 0x0211, 0x0211, 0x0211, 0x0211,
0x0301, 0x0301, 0x0310, 0x0310, 0x0200, 0x0200, 0x0200, 0x0200,
-32, -48, -64, 0x0415, 0x0451, -80, -96, 0x0424,
0x0442, 0x0414, 0x0341, 0x0341, 0x0404, 0x0440, 0x0423, 0x0432,
0x0413, 0x0431, 0x0403, 0x0430, 0x0222, 0x0222, 0x0222, 0x0222,
0x0202, 0x0202, 0x0202, 0x0202, 0x0220, 0x0220, 0x0220, 0x0220,
0x0355, 0x0355, 0x0354, 0x0354, 0x0245, 0x0245, 0x0245, 0x0245,
0x0153, 0x0153, 0x0153, 0x0153, 0x0153, 0x0153, 0x0153, 0x0153,
0x0235, 0x0235, 0x0235, 0x0235, 0x0244, 0x0244, 0x0244, 0x0244,
0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125,
0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152,
0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105,
0x0134, 0x0134, 0x0134, 0x0134, 0x0134, 0x0134, 0x0134, 0x0134,
0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143,
0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150,
0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133,
};
static const short tab9_[] =
{
-16, -32, -48, -64, -80, 0x0412, 0x0421, 0x0420,
0x0311, 0x0311, 0x0301, 0x0301, 0x0310, 0x0310, 0x0300, 0x0300,
-80, 0x0435, 0x0453, -96, 0x0444, 0x0425, 0x0452, 0x0415,
0x0351, 0x0351, 0x0334, 0x0334, 0x0343, 0x0343, 0x0450, 0x0404,
0x0324, 0x0324, 0x0342, 0x0342, 0x0333, 0x0333, 0x0340, 0x0340,
0x0214, 0x0214, 0x0214, 0x0214, 0x0241, 0x0241, 0x0241, 0x0241,
0x0223, 0x0223, 0x0223, 0x0223, 0x0232, 0x0232, 0x0232, 0x0232,
0x0113, 0x0113, 0x0113, 0x0113, 0x0113, 0x0113, 0x0113, 0x0113,
0x0131, 0x0131, 0x0131, 0x0131, 0x0131, 0x0131, 0x0131, 0x0131,
0x0203, 0x0203, 0x0203, 0x0203, 0x0230, 0x0230, 0x0230, 0x0230,
0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
0x0155, 0x0155, 0x0155, 0x0155, 0x0155, 0x0155, 0x0155, 0x0155,
0x0145, 0x0145, 0x0145, 0x0145, 0x0145, 0x0145, 0x0145, 0x0145,
0x0154, 0x0154, 0x0154, 0x0154, 0x0154, 0x0154, 0x0154, 0x0154,
0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105,
};
static const short tab10_[] =
{
-16, -32, -48, 0x0411, 0x0301, 0x0301, 0x0310, 0x0310,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
-48, -64, -80, -96, -112, -128, -144, 0x0417,
0x0471, -160, -176, -192, 0x0416, 0x0461, 0x0460, -208,
-208, -224, 0x0414, 0x0441, 0x0440, 0x0423, 0x0432, 0x0403,
0x0313, 0x0313, 0x0331, 0x0331, 0x0330, 0x0330, 0x0322, 0x0322,
0x0212, 0x0212, 0x0212, 0x0212, 0x0221, 0x0221, 0x0221, 0x0221,
0x0202, 0x0202, 0x0202, 0x0202, 0x0220, 0x0220, 0x0220, 0x0220,
0x0377, 0x0377, 0x0367, 0x0367, 0x0376, 0x0376, 0x0357, 0x0357,
0x0375, 0x0375, 0x0366, 0x0366, 0x0247, 0x0247, 0x0247, 0x0247,
0x0274, 0x0274, 0x0274, 0x0274, 0x0256, 0x0256, 0x0256, 0x0256,
0x0265, 0x0265, 0x0265, 0x0265, 0x0237, 0x0237, 0x0237, 0x0237,
0x0273, 0x0273, 0x0273, 0x0273, 0x0246, 0x0246, 0x0246, 0x0246,
0x0355, 0x0355, 0x0354, 0x0354, 0x0263, 0x0263, 0x0263, 0x0263,
0x0127, 0x0127, 0x0127, 0x0127, 0x0127, 0x0127, 0x0127, 0x0127,
0x0172, 0x0172, 0x0172, 0x0172, 0x0172, 0x0172, 0x0172, 0x0172,
0x0264, 0x0264, 0x0264, 0x0264, 0x0207, 0x0207, 0x0207, 0x0207,
0x0170, 0x0170, 0x0170, 0x0170, 0x0170, 0x0170, 0x0170, 0x0170,
0x0162, 0x0162, 0x0162, 0x0162, 0x0162, 0x0162, 0x0162, 0x0162,
0x0245, 0x0245, 0x0245, 0x0245, 0x0235, 0x0235, 0x0235, 0x0235,
0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106,
0x0253, 0x0253, 0x0253, 0x0253, 0x0244, 0x0244, 0x0244, 0x0244,
0x0136, 0x0136, 0x0136, 0x0136, 0x0136, 0x0136, 0x0136, 0x0136,
0x0126, 0x0126, 0x0126, 0x0126, 0x0126, 0x0126, 0x0126, 0x0126,
0x0225, 0x0225, 0x0225, 0x0225, 0x0252, 0x0252, 0x0252, 0x0252,
0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115,
0x0151, 0x0151, 0x0151, 0x0151, 0x0151, 0x0151, 0x0151, 0x0151,
0x0234, 0x0234, 0x0234, 0x0234, 0x0243, 0x0243, 0x0243, 0x0243,
0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105,
0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150,
0x0124, 0x0124, 0x0124, 0x0124, 0x0124, 0x0124, 0x0124, 0x0124,
0x0142, 0x0142, 0x0142, 0x0142, 0x0142, 0x0142, 0x0142, 0x0142,
0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133,
0x0104, 0x0104, 0x0104, 0x0104, 0x0104, 0x0104, 0x0104, 0x0104,
};
static const short tab11_[] =
{
-16, -32, -48, -64, 0x0412, -80, 0x0311, 0x0311,
0x0301, 0x0301, 0x0310, 0x0310, 0x0200, 0x0200, 0x0200, 0x0200,
-80, -96, -112, -128, -144, 0x0427, 0x0472, -160,
0x0371, 0x0371, 0x0417, 0x0470, 0x0436, 0x0463, 0x0460, -176,
-176, 0x0415, 0x0362, 0x0362, 0x0426, 0x0406, 0x0316, 0x0316,
0x0361, 0x0361, 0x0451, 0x0434, 0x0450, -192, 0x0424, 0x0442,
0x0414, 0x0441, 0x0404, 0x0440, 0x0323, 0x0323, 0x0332, 0x0332,
0x0213, 0x0213, 0x0213, 0x0213, 0x0231, 0x0231, 0x0231, 0x0231,
0x0303, 0x0303, 0x0330, 0x0330, 0x0222, 0x0222, 0x0222, 0x0222,
0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121,
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120,
0x0277, 0x0277, 0x0277, 0x0277, 0x0267, 0x0267, 0x0267, 0x0267,
0x0276, 0x0276, 0x0276, 0x0276, 0x0275, 0x0275, 0x0275, 0x0275,
0x0266, 0x0266, 0x0266, 0x0266, 0x0247, 0x0247, 0x0247, 0x0247,
0x0274, 0x0274, 0x0274, 0x0274, 0x0357, 0x0357, 0x0355, 0x0355,
0x0256, 0x0256, 0x0256, 0x0256, 0x0265, 0x0265, 0x0265, 0x0265,
0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137,
0x0173, 0x0173, 0x0173, 0x0173, 0x0173, 0x0173, 0x0173, 0x0173,
0x0146, 0x0146, 0x0146, 0x0146, 0x0146, 0x0146, 0x0146, 0x0146,
0x0245, 0x0245, 0x0245, 0x0245, 0x0254, 0x0254, 0x0254, 0x0254,
0x0235, 0x0235, 0x0235, 0x0235, 0x0253, 0x0253, 0x0253, 0x0253,
0x0164, 0x0164, 0x0164, 0x0164, 0x0164, 0x0164, 0x0164, 0x0164,
0x0107, 0x0107, 0x0107, 0x0107, 0x0107, 0x0107, 0x0107, 0x0107,
0x0144, 0x0144, 0x0144, 0x0144, 0x0144, 0x0144, 0x0144, 0x0144,
0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125,
0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152,
0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105,
0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143,
0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133,
};
static const short tab12_[] =
{
-16, -32, -48, -64, -80, -96, 0x0412, 0x0421,
-112, 0x0400, 0x0311, 0x0311, 0x0301, 0x0301, 0x0310, 0x0310,
-112, -128, -144, -160, 0x0456, 0x0437, -176, 0x0427,
0x0472, 0x0446, 0x0464, 0x0417, 0x0471, -192, 0x0436, 0x0463,
0x0445, 0x0454, 0x0444, -192, 0x0326, 0x0326, 0x0362, 0x0362,
0x0361, 0x0361, 0x0416, 0x0460, 0x0435, 0x0453, 0x0425, 0x0452,
0x0315, 0x0315, 0x0351, 0x0351, 0x0334, 0x0334, 0x0343, 0x0343,
0x0450, 0x0404, 0x0324, 0x0324, 0x0342, 0x0342, 0x0314, 0x0314,
0x0233, 0x0233, 0x0233, 0x0233, 0x0241, 0x0241, 0x0241, 0x0241,
0x0223, 0x0223, 0x0223, 0x0223, 0x0232, 0x0232, 0x0232, 0x0232,
0x0340, 0x0340, 0x0303, 0x0303, 0x0230, 0x0230, 0x0230, 0x0230,
0x0113, 0x0113, 0x0113, 0x0113, 0x0113, 0x0113, 0x0113, 0x0113,
0x0131, 0x0131, 0x0131, 0x0131, 0x0131, 0x0131, 0x0131, 0x0131,
0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120,
0x0277, 0x0277, 0x0277, 0x0277, 0x0267, 0x0267, 0x0267, 0x0267,
0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176,
0x0157, 0x0157, 0x0157, 0x0157, 0x0157, 0x0157, 0x0157, 0x0157,
0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175,
0x0166, 0x0166, 0x0166, 0x0166, 0x0166, 0x0166, 0x0166, 0x0166,
0x0147, 0x0147, 0x0147, 0x0147, 0x0147, 0x0147, 0x0147, 0x0147,
0x0174, 0x0174, 0x0174, 0x0174, 0x0174, 0x0174, 0x0174, 0x0174,
0x0165, 0x0165, 0x0165, 0x0165, 0x0165, 0x0165, 0x0165, 0x0165,
0x0173, 0x0173, 0x0173, 0x0173, 0x0173, 0x0173, 0x0173, 0x0173,
0x0155, 0x0155, 0x0155, 0x0155, 0x0155, 0x0155, 0x0155, 0x0155,
0x0107, 0x0107, 0x0107, 0x0107, 0x0107, 0x0107, 0x0107, 0x0107,
0x0170, 0x0170, 0x0170, 0x0170, 0x0170, 0x0170, 0x0170, 0x0170,
0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106,
0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105,
};
static const short tab13_[] =
{
-16, -32, -48, -64, 0x0411, 0x0401, 0x0310, 0x0310,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
-64, -80, -96, -112, -128, -144, -160, -176,
-192, -208, -224, -240, -256, -272, -288, -304,
-304, -320, -336, -352, 0x0481, -368, -384, -400,
-416, -432, 0x0415, 0x0451, -448, -464, -480, 0x0414,
0x0341, 0x0341, 0x0404, 0x0440, 0x0423, 0x0432, 0x0313, 0x0313,
0x0331, 0x0331, 0x0303, 0x0303, 0x0330, 0x0330, 0x0322, 0x0322,
0x0212, 0x0212, 0x0212, 0x0212, 0x0221, 0x0221, 0x0221, 0x0221,
0x0202, 0x0202, 0x0202, 0x0202, 0x0220, 0x0220, 0x0220, 0x0220,
-448, -464, -480, -496, -512, -528, -544, -560,
-576, -592, -608, -624, -640, -656, 0x041f, 0x04f1,
0x04f0, -656, -672, -688, 0x04e2, -704, 0x041e, 0x04e1,
-720, -736, -752, -768, -784, -800, 0x04c6, 0x043d,
-800, 0x042d, 0x04d2, 0x041d, 0x04b7, -816, -832, 0x04c3,
-848, 0x044b, 0x03d1, 0x03d1, 0x040d, 0x04d0, 0x048a, 0x04a8,
0x044c, 0x04c4, 0x046b, 0x04b6, 0x033c, 0x033c, 0x032c, 0x032c,
0x03c2, 0x03c2, 0x035b, 0x035b, 0x04b5, 0x0489, 0x031c, 0x031c,
0x03c1, 0x03c1, 0x0498, 0x040c, 0x03c0, 0x03c0, 0x04b4, 0x046a,
0x04a6, 0x0479, 0x033b, 0x033b, 0x03b3, 0x03b3, 0x0488, 0x045a,
0x032b, 0x032b, 0x04a5, 0x0469, 0x03a4, 0x03a4, 0x0478, 0x0487,
0x0394, 0x0394, 0x0477, 0x0476, 0x02b2, 0x02b2, 0x02b2, 0x02b2,
0x021b, 0x021b, 0x021b, 0x021b, 0x02b1, 0x02b1, 0x02b1, 0x02b1,
0x030b, 0x030b, 0x03b0, 0x03b0, 0x0396, 0x0396, 0x034a, 0x034a,
0x033a, 0x033a, 0x03a3, 0x03a3, 0x0359, 0x0359, 0x0395, 0x0395,
0x022a, 0x022a, 0x022a, 0x022a, 0x02a2, 0x02a2, 0x02a2, 0x02a2,
0x021a, 0x021a, 0x021a, 0x021a, 0x02a1, 0x02a1, 0x02a1, 0x02a1,
0x030a, 0x030a, 0x0368, 0x0368, 0x02a0, 0x02a0, 0x02a0, 0x02a0,
0x0386, 0x0386, 0x0349, 0x0349, 0x0293, 0x0293, 0x0293, 0x0293,
0x0339, 0x0339, 0x0358, 0x0358, 0x0385, 0x0385, 0x0367, 0x0367,
0x0229, 0x0229, 0x0229, 0x0229, 0x0292, 0x0292, 0x0292, 0x0292,
0x0357, 0x0357, 0x0375, 0x0375, 0x0238, 0x0238, 0x0238, 0x0238,
0x0283, 0x0283, 0x0283, 0x0283, 0x0366, 0x0366, 0x0347, 0x0347,
0x0374, 0x0374, 0x0356, 0x0356, 0x0365, 0x0365, 0x0373, 0x0373,
0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119,
0x0191, 0x0191, 0x0191, 0x0191, 0x0191, 0x0191, 0x0191, 0x0191,
0x0209, 0x0209, 0x0209, 0x0209, 0x0290, 0x0290, 0x0290, 0x0290,
0x0248, 0x0248, 0x0248, 0x0248, 0x0284, 0x0284, 0x0284, 0x0284,
0x0272, 0x0272, 0x0272, 0x0272, 0x0346, 0x0346, 0x0364, 0x0364,
0x0128, 0x0128, 0x0128, 0x0128, 0x0128, 0x0128, 0x0128, 0x0128,
0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182,
0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118,
0x0237, 0x0237, 0x0237, 0x0237, 0x0227, 0x0227, 0x0227, 0x0227,
0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117,
0x0171, 0x0171, 0x0171, 0x0171, 0x0171, 0x0171, 0x0171, 0x0171,
0x0255, 0x0255, 0x0255, 0x0255, 0x0207, 0x0207, 0x0207, 0x0207,
0x0270, 0x0270, 0x0270, 0x0270, 0x0236, 0x0236, 0x0236, 0x0236,
0x0263, 0x0263, 0x0263, 0x0263, 0x0245, 0x0245, 0x0245, 0x0245,
0x0254, 0x0254, 0x0254, 0x0254, 0x0226, 0x0226, 0x0226, 0x0226,
0x0262, 0x0262, 0x0262, 0x0262, 0x0235, 0x0235, 0x0235, 0x0235,
0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108,
0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180,
0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116,
0x0161, 0x0161, 0x0161, 0x0161, 0x0161, 0x0161, 0x0161, 0x0161,
0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106,
0x0160, 0x0160, 0x0160, 0x0160, 0x0160, 0x0160, 0x0160, 0x0160,
0x0253, 0x0253, 0x0253, 0x0253, 0x0244, 0x0244, 0x0244, 0x0244,
0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125,
0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152,
0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105,
0x0134, 0x0134, 0x0134, 0x0134, 0x0134, 0x0134, 0x0134, 0x0134,
0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143,
0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150,
0x0124, 0x0124, 0x0124, 0x0124, 0x0124, 0x0124, 0x0124, 0x0124,
0x0142, 0x0142, 0x0142, 0x0142, 0x0142, 0x0142, 0x0142, 0x0142,
0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133,
-448, 0x04ff, 0x04ef, 0x04df, 0x04ee, 0x04cf, 0x04de, 0x04bf,
0x04fb, 0x04ce, 0x04dc, -464, 0x03ec, 0x03ec, 0x03dd, 0x03dd,
0x04fa, 0x04cd, 0x03be, 0x03be, 0x03eb, 0x03eb, 0x039f, 0x039f,
0x03f9, 0x03f9, 0x03ea, 0x03ea, 0x03bd, 0x03bd, 0x03db, 0x03db,
0x038f, 0x038f, 0x03f8, 0x03f8, 0x03cc, 0x03cc, 0x04ae, 0x049e,
0x038e, 0x038e, 0x047f, 0x047e, 0x02f7, 0x02f7, 0x02f7, 0x02f7,
0x02da, 0x02da, 0x02da, 0x02da, 0x03ad, 0x03ad, 0x03bc, 0x03bc,
0x03cb, 0x03cb, 0x03f6, 0x03f6, 0x026f, 0x026f, 0x026f, 0x026f,
0x02e8, 0x02e8, 0x02e8, 0x02e8, 0x025f, 0x025f, 0x025f, 0x025f,
0x029d, 0x029d, 0x029d, 0x029d, 0x02d9, 0x02d9, 0x02d9, 0x02d9,
0x02f5, 0x02f5, 0x02f5, 0x02f5, 0x02e7, 0x02e7, 0x02e7, 0x02e7,
0x02ac, 0x02ac, 0x02ac, 0x02ac, 0x02bb, 0x02bb, 0x02bb, 0x02bb,
0x024f, 0x024f, 0x024f, 0x024f, 0x02f4, 0x02f4, 0x02f4, 0x02f4,
0x03ca, 0x03ca, 0x03e6, 0x03e6, 0x02f3, 0x02f3, 0x02f3, 0x02f3,
0x013f, 0x013f, 0x013f, 0x013f, 0x013f, 0x013f, 0x013f, 0x013f,
0x028d, 0x028d, 0x028d, 0x028d, 0x02d8, 0x02d8, 0x02d8, 0x02d8,
0x012f, 0x012f, 0x012f, 0x012f, 0x012f, 0x012f, 0x012f, 0x012f,
0x01f2, 0x01f2, 0x01f2, 0x01f2, 0x01f2, 0x01f2, 0x01f2, 0x01f2,
0x026e, 0x026e, 0x026e, 0x026e, 0x029c, 0x029c, 0x029c, 0x029c,
0x010f, 0x010f, 0x010f, 0x010f, 0x010f, 0x010f, 0x010f, 0x010f,
0x02c9, 0x02c9, 0x02c9, 0x02c9, 0x025e, 0x025e, 0x025e, 0x025e,
0x01ab, 0x01ab, 0x01ab, 0x01ab, 0x01ab, 0x01ab, 0x01ab, 0x01ab,
0x027d, 0x027d, 0x027d, 0x027d, 0x02d7, 0x02d7, 0x02d7, 0x02d7,
0x014e, 0x014e, 0x014e, 0x014e, 0x014e, 0x014e, 0x014e, 0x014e,
0x02c8, 0x02c8, 0x02c8, 0x02c8, 0x02d6, 0x02d6, 0x02d6, 0x02d6,
0x013e, 0x013e, 0x013e, 0x013e, 0x013e, 0x013e, 0x013e, 0x013e,
0x01b9, 0x01b9, 0x01b9, 0x01b9, 0x01b9, 0x01b9, 0x01b9, 0x01b9,
0x029b, 0x029b, 0x029b, 0x029b, 0x02aa, 0x02aa, 0x02aa, 0x02aa,
0x01ba, 0x01ba, 0x01ba, 0x01ba, 0x01ba, 0x01ba, 0x01ba, 0x01ba,
0x01e5, 0x01e5, 0x01e5, 0x01e5, 0x01e5, 0x01e5, 0x01e5, 0x01e5,
0x01e4, 0x01e4, 0x01e4, 0x01e4, 0x01e4, 0x01e4, 0x01e4, 0x01e4,
0x018c, 0x018c, 0x018c, 0x018c, 0x018c, 0x018c, 0x018c, 0x018c,
0x016d, 0x016d, 0x016d, 0x016d, 0x016d, 0x016d, 0x016d, 0x016d,
0x01e3, 0x01e3, 0x01e3, 0x01e3, 0x01e3, 0x01e3, 0x01e3, 0x01e3,
0x012e, 0x012e, 0x012e, 0x012e, 0x012e, 0x012e, 0x012e, 0x012e,
0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e,
0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e0,
0x015d, 0x015d, 0x015d, 0x015d, 0x015d, 0x015d, 0x015d, 0x015d,
0x01d5, 0x01d5, 0x01d5, 0x01d5, 0x01d5, 0x01d5, 0x01d5, 0x01d5,
0x017c, 0x017c, 0x017c, 0x017c, 0x017c, 0x017c, 0x017c, 0x017c,
0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7,
0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
0x018b, 0x018b, 0x018b, 0x018b, 0x018b, 0x018b, 0x018b, 0x018b,
0x01b8, 0x01b8, 0x01b8, 0x01b8, 0x01b8, 0x01b8, 0x01b8, 0x01b8,
0x01d4, 0x01d4, 0x01d4, 0x01d4, 0x01d4, 0x01d4, 0x01d4, 0x01d4,
0x019a, 0x019a, 0x019a, 0x019a, 0x019a, 0x019a, 0x019a, 0x019a,
0x01a9, 0x01a9, 0x01a9, 0x01a9, 0x01a9, 0x01a9, 0x01a9, 0x01a9,
0x016c, 0x016c, 0x016c, 0x016c, 0x016c, 0x016c, 0x016c, 0x016c,
0x01d3, 0x01d3, 0x01d3, 0x01d3, 0x01d3, 0x01d3, 0x01d3, 0x01d3,
0x017b, 0x017b, 0x017b, 0x017b, 0x017b, 0x017b, 0x017b, 0x017b,
0x015c, 0x015c, 0x015c, 0x015c, 0x015c, 0x015c, 0x015c, 0x015c,
0x01c5, 0x01c5, 0x01c5, 0x01c5, 0x01c5, 0x01c5, 0x01c5, 0x01c5,
0x0199, 0x0199, 0x0199, 0x0199, 0x0199, 0x0199, 0x0199, 0x0199,
0x017a, 0x017a, 0x017a, 0x017a, 0x017a, 0x017a, 0x017a, 0x017a,
0x01a7, 0x01a7, 0x01a7, 0x01a7, 0x01a7, 0x01a7, 0x01a7, 0x01a7,
0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197,
0x03fe, 0x03fe, 0x03fc, 0x03fc, 0x02fd, 0x02fd, 0x02fd, 0x02fd,
0x01ed, 0x01ed, 0x01ed, 0x01ed, 0x01ed, 0x01ed, 0x01ed, 0x01ed,
0x01af, 0x01af, 0x01af, 0x01af, 0x01af, 0x01af, 0x01af, 0x01af,
0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9, 0x01e9,
};
static const short tab15_[] =
{
-16, -32, -48, -64, -80, -96, -112, -128,
-144, -160, 0x0311, 0x0311, 0x0401, 0x0410, 0x0300, 0x0300,
-160, -176, -192, -208, -224, -240, -256, -272,
-288, -304, -320, -336, -352, -368, -384, -400,
-400, -416, -432, -448, -464, -480, -496, -512,
-528, -544, -560, -576, -592, -608, -624, -640,
-640, -656, 0x0491, -672, -688, -704, -720, -736,
0x0428, 0x0482, 0x0418, 0x0481, -752, -768, -784, -800,
0x0427, 0x0472, 0x0464, 0x0417, 0x0455, 0x0471, -800, 0x0436,
0x0463, 0x0445, 0x0454, 0x0426, 0x0462, 0x0416, -816, 0x0435,
0x0361, 0x0361, 0x0453, 0x0444, 0x0325, 0x0325, 0x0352, 0x0352,
0x0315, 0x0315, 0x0351, 0x0351, 0x0405, 0x0450, 0x0334, 0x0334,
0x0343, 0x0343, 0x0324, 0x0324, 0x0342, 0x0342, 0x0333, 0x0333,
0x0241, 0x0241, 0x0241, 0x0241, 0x0314, 0x0314, 0x0304, 0x0304,
0x0223, 0x0223, 0x0223, 0x0223, 0x0232, 0x0232, 0x0232, 0x0232,
0x0340, 0x0340, 0x0303, 0x0303, 0x0213, 0x0213, 0x0213, 0x0213,
0x0231, 0x0231, 0x0231, 0x0231, 0x0230, 0x0230, 0x0230, 0x0230,
0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122, 0x0122,
0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112,
0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121,
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120, 0x0120,
-720, -736, 0x04ee, -752, -768, -784, 0x04fb, -800,
0x04dd, 0x04af, 0x04fa, 0x04be, 0x04eb, 0x04cd, 0x04dc, 0x049f,
0x04f9, 0x04ea, 0x04bd, 0x04db, 0x048f, 0x04f8, 0x04cc, 0x049e,
0x04e9, 0x047f, 0x04f7, 0x04ad, 0x04da, 0x04bc, 0x046f, -800,
0x03cb, 0x03cb, 0x03f6, 0x03f6, 0x048e, 0x04e8, 0x045f, 0x049d,
0x03f5, 0x03f5, 0x037e, 0x037e, 0x03e7, 0x03e7, 0x03ac, 0x03ac,
0x03ca, 0x03ca, 0x03bb, 0x03bb, 0x04d9, 0x048d, 0x034f, 0x034f,
0x03f4, 0x03f4, 0x033f, 0x033f, 0x03f3, 0x03f3, 0x03d8, 0x03d8,
0x03e6, 0x03e6, 0x032f, 0x032f, 0x03f2, 0x03f2, 0x046e, 0x04f0,
0x031f, 0x031f, 0x03f1, 0x03f1, 0x039c, 0x039c, 0x03c9, 0x03c9,
0x035e, 0x035e, 0x03ab, 0x03ab, 0x03ba, 0x03ba, 0x03e5, 0x03e5,
0x037d, 0x037d, 0x03d7, 0x03d7, 0x034e, 0x034e, 0x03e4, 0x03e4,
0x038c, 0x038c, 0x03c8, 0x03c8, 0x033e, 0x033e, 0x036d, 0x036d,
0x03d6, 0x03d6, 0x03e3, 0x03e3, 0x039b, 0x039b, 0x03b9, 0x03b9,
0x032e, 0x032e, 0x03aa, 0x03aa, 0x03e2, 0x03e2, 0x031e, 0x031e,
0x03e1, 0x03e1, 0x040e, 0x04e0, 0x035d, 0x035d, 0x03d5, 0x03d5,
0x037c, 0x037c, 0x03c7, 0x03c7, 0x034d, 0x034d, 0x038b, 0x038b,
0x02d4, 0x02d4, 0x02d4, 0x02d4, 0x03b8, 0x03b8, 0x039a, 0x039a,
0x03a9, 0x03a9, 0x036c, 0x036c, 0x03c6, 0x03c6, 0x033d, 0x033d,
0x02d3, 0x02d3, 0x02d3, 0x02d3, 0x02d2, 0x02d2, 0x02d2, 0x02d2,
0x032d, 0x032d, 0x030d, 0x030d, 0x021d, 0x021d, 0x021d, 0x021d,
0x027b, 0x027b, 0x027b, 0x027b, 0x02b7, 0x02b7, 0x02b7, 0x02b7,
0x02d1, 0x02d1, 0x02d1, 0x02d1, 0x035c, 0x035c, 0x03d0, 0x03d0,
0x02c5, 0x02c5, 0x02c5, 0x02c5, 0x028a, 0x028a, 0x028a, 0x028a,
0x02a8, 0x02a8, 0x02a8, 0x02a8, 0x024c, 0x024c, 0x024c, 0x024c,
0x02c4, 0x02c4, 0x02c4, 0x02c4, 0x026b, 0x026b, 0x026b, 0x026b,
0x02b6, 0x02b6, 0x02b6, 0x02b6, 0x0399, 0x0399, 0x030c, 0x030c,
0x023c, 0x023c, 0x023c, 0x023c, 0x02c3, 0x02c3, 0x02c3, 0x02c3,
0x027a, 0x027a, 0x027a, 0x027a, 0x02a7, 0x02a7, 0x02a7, 0x02a7,
0x02a6, 0x02a6, 0x02a6, 0x02a6, 0x03c0, 0x03c0, 0x030b, 0x030b,
0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2, 0x01c2,
0x022c, 0x022c, 0x022c, 0x022c, 0x025b, 0x025b, 0x025b, 0x025b,
0x02b5, 0x02b5, 0x02b5, 0x02b5, 0x021c, 0x021c, 0x021c, 0x021c,
0x0289, 0x0289, 0x0289, 0x0289, 0x0298, 0x0298, 0x0298, 0x0298,
0x02c1, 0x02c1, 0x02c1, 0x02c1, 0x024b, 0x024b, 0x024b, 0x024b,
0x02b4, 0x02b4, 0x02b4, 0x02b4, 0x026a, 0x026a, 0x026a, 0x026a,
0x023b, 0x023b, 0x023b, 0x023b, 0x0279, 0x0279, 0x0279, 0x0279,
0x01b3, 0x01b3, 0x01b3, 0x01b3, 0x01b3, 0x01b3, 0x01b3, 0x01b3,
0x0297, 0x0297, 0x0297, 0x0297, 0x0288, 0x0288, 0x0288, 0x0288,
0x022b, 0x022b, 0x022b, 0x022b, 0x025a, 0x025a, 0x025a, 0x025a,
0x01b2, 0x01b2, 0x01b2, 0x01b2, 0x01b2, 0x01b2, 0x01b2, 0x01b2,
0x02a5, 0x02a5, 0x02a5, 0x02a5, 0x021b, 0x021b, 0x021b, 0x021b,
0x01b1, 0x01b1, 0x01b1, 0x01b1, 0x01b1, 0x01b1, 0x01b1, 0x01b1,
0x02b0, 0x02b0, 0x02b0, 0x02b0, 0x0269, 0x0269, 0x0269, 0x0269,
0x0296, 0x0296, 0x0296, 0x0296, 0x024a, 0x024a, 0x024a, 0x024a,
0x02a4, 0x02a4, 0x02a4, 0x02a4, 0x0278, 0x0278, 0x0278, 0x0278,
0x0287, 0x0287, 0x0287, 0x0287, 0x023a, 0x023a, 0x023a, 0x023a,
0x01a3, 0x01a3, 0x01a3, 0x01a3, 0x01a3, 0x01a3, 0x01a3, 0x01a3,
0x0159, 0x0159, 0x0159, 0x0159, 0x0159, 0x0159, 0x0159, 0x0159,
0x0195, 0x0195, 0x0195, 0x0195, 0x0195, 0x0195, 0x0195, 0x0195,
0x012a, 0x012a, 0x012a, 0x012a, 0x012a, 0x012a, 0x012a, 0x012a,
0x01a2, 0x01a2, 0x01a2, 0x01a2, 0x01a2, 0x01a2, 0x01a2, 0x01a2,
0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a, 0x011a,
0x01a1, 0x01a1, 0x01a1, 0x01a1, 0x01a1, 0x01a1, 0x01a1, 0x01a1,
0x020a, 0x020a, 0x020a, 0x020a, 0x02a0, 0x02a0, 0x02a0, 0x02a0,
0x0168, 0x0168, 0x0168, 0x0168, 0x0168, 0x0168, 0x0168, 0x0168,
0x0186, 0x0186, 0x0186, 0x0186, 0x0186, 0x0186, 0x0186, 0x0186,
0x0149, 0x0149, 0x0149, 0x0149, 0x0149, 0x0149, 0x0149, 0x0149,
0x0194, 0x0194, 0x0194, 0x0194, 0x0194, 0x0194, 0x0194, 0x0194,
0x0139, 0x0139, 0x0139, 0x0139, 0x0139, 0x0139, 0x0139, 0x0139,
0x0193, 0x0193, 0x0193, 0x0193, 0x0193, 0x0193, 0x0193, 0x0193,
0x0277, 0x0277, 0x0277, 0x0277, 0x0209, 0x0209, 0x0209, 0x0209,
0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158,
0x0185, 0x0185, 0x0185, 0x0185, 0x0185, 0x0185, 0x0185, 0x0185,
0x0129, 0x0129, 0x0129, 0x0129, 0x0129, 0x0129, 0x0129, 0x0129,
0x0167, 0x0167, 0x0167, 0x0167, 0x0167, 0x0167, 0x0167, 0x0167,
0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176,
0x0192, 0x0192, 0x0192, 0x0192, 0x0192, 0x0192, 0x0192, 0x0192,
0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119,
0x0190, 0x0190, 0x0190, 0x0190, 0x0190, 0x0190, 0x0190, 0x0190,
0x0148, 0x0148, 0x0148, 0x0148, 0x0148, 0x0148, 0x0148, 0x0148,
0x0184, 0x0184, 0x0184, 0x0184, 0x0184, 0x0184, 0x0184, 0x0184,
0x0157, 0x0157, 0x0157, 0x0157, 0x0157, 0x0157, 0x0157, 0x0157,
0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175,
0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138,
0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183,
0x0166, 0x0166, 0x0166, 0x0166, 0x0166, 0x0166, 0x0166, 0x0166,
0x0147, 0x0147, 0x0147, 0x0147, 0x0147, 0x0147, 0x0147, 0x0147,
0x0174, 0x0174, 0x0174, 0x0174, 0x0174, 0x0174, 0x0174, 0x0174,
0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108, 0x0108,
0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180,
0x0156, 0x0156, 0x0156, 0x0156, 0x0156, 0x0156, 0x0156, 0x0156,
0x0165, 0x0165, 0x0165, 0x0165, 0x0165, 0x0165, 0x0165, 0x0165,
0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137,
0x0173, 0x0173, 0x0173, 0x0173, 0x0173, 0x0173, 0x0173, 0x0173,
0x0146, 0x0146, 0x0146, 0x0146, 0x0146, 0x0146, 0x0146, 0x0146,
0x0107, 0x0107, 0x0107, 0x0107, 0x0107, 0x0107, 0x0107, 0x0107,
0x0170, 0x0170, 0x0170, 0x0170, 0x0170, 0x0170, 0x0170, 0x0170,
0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106,
0x0160, 0x0160, 0x0160, 0x0160, 0x0160, 0x0160, 0x0160, 0x0160,
0x01ff, 0x01ff, 0x01ff, 0x01ff, 0x01ff, 0x01ff, 0x01ff, 0x01ff,
0x01ef, 0x01ef, 0x01ef, 0x01ef, 0x01ef, 0x01ef, 0x01ef, 0x01ef,
0x01fe, 0x01fe, 0x01fe, 0x01fe, 0x01fe, 0x01fe, 0x01fe, 0x01fe,
0x01df, 0x01df, 0x01df, 0x01df, 0x01df, 0x01df, 0x01df, 0x01df,
0x01fd, 0x01fd, 0x01fd, 0x01fd, 0x01fd, 0x01fd, 0x01fd, 0x01fd,
0x01cf, 0x01cf, 0x01cf, 0x01cf, 0x01cf, 0x01cf, 0x01cf, 0x01cf,
0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc,
0x01de, 0x01de, 0x01de, 0x01de, 0x01de, 0x01de, 0x01de, 0x01de,
0x01ed, 0x01ed, 0x01ed, 0x01ed, 0x01ed, 0x01ed, 0x01ed, 0x01ed,
0x01bf, 0x01bf, 0x01bf, 0x01bf, 0x01bf, 0x01bf, 0x01bf, 0x01bf,
0x01ce, 0x01ce, 0x01ce, 0x01ce, 0x01ce, 0x01ce, 0x01ce, 0x01ce,
0x01ec, 0x01ec, 0x01ec, 0x01ec, 0x01ec, 0x01ec, 0x01ec, 0x01ec,
0x01ae, 0x01ae, 0x01ae, 0x01ae, 0x01ae, 0x01ae, 0x01ae, 0x01ae,
0x010f, 0x010f, 0x010f, 0x010f, 0x010f, 0x010f, 0x010f, 0x010f,
};
static const short tab16_[] =
{
-16, -32, -48, -64, 0x0411, 0x0401, 0x0310, 0x0310,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
-64, -80, -96, 0x04ff, -112, -128, -144, 0x04f2,
-160, 0x041f, 0x04f1, -176, -192, -208, -224, -240,
-240, -256, -272, -288, -304, -320, -336, -352,
-368, -384, -400, -416, -432, -448, 0x0451, -464,
-464, -480, -496, 0x0414, 0x0441, -512, 0x0423, 0x0432,
0x0313, 0x0313, 0x0331, 0x0331, 0x0403, 0x0430, 0x0322, 0x0322,
0x0212, 0x0212, 0x0212, 0x0212, 0x0221, 0x0221, 0x0221, 0x0221,
0x0202, 0x0202, 0x0202, 0x0202, 0x0220, 0x0220, 0x0220, 0x0220,
0x03ef, 0x03ef, 0x03fe, 0x03fe, 0x03df, 0x03df, 0x03fd, 0x03fd,
0x03cf, 0x03cf, 0x03fc, 0x03fc, 0x03bf, 0x03bf, 0x03fb, 0x03fb,
0x02af, 0x02af, 0x02af, 0x02af, 0x03fa, 0x03fa, 0x039f, 0x039f,
0x03f9, 0x03f9, 0x03f8, 0x03f8, 0x028f, 0x028f, 0x028f, 0x028f,
0x027f, 0x027f, 0x027f, 0x027f, 0x02f7, 0x02f7, 0x02f7, 0x02f7,
0x026f, 0x026f, 0x026f, 0x026f, 0x02f6, 0x02f6, 0x02f6, 0x02f6,
0x025f, 0x025f, 0x025f, 0x025f, 0x02f5, 0x02f5, 0x02f5, 0x02f5,
0x014f, 0x014f, 0x014f, 0x014f, 0x014f, 0x014f, 0x014f, 0x014f,
0x01f4, 0x01f4, 0x01f4, 0x01f4, 0x01f4, 0x01f4, 0x01f4, 0x01f4,
0x01f3, 0x01f3, 0x01f3, 0x01f3, 0x01f3, 0x01f3, 0x01f3, 0x01f3,
0x01f0, 0x01f0, 0x01f0, 0x01f0, 0x01f0, 0x01f0, 0x01f0, 0x01f0,
0x023f, 0x023f, 0x023f, 0x023f, -416, -432, -448, -464,
0x012f, 0x012f, 0x012f, 0x012f, 0x012f, 0x012f, 0x012f, 0x012f,
0x010f, 0x010f, 0x010f, 0x010f, 0x010f, 0x010f, 0x010f, 0x010f,
-448, -464, -480, -496, -512, -528, -544, -560,
-576, -592, -608, 0x04e3, -624, -640, -656, -672,
-672, -688, -704, 0x040d, -720, -736, -752, 0x043c,
-768, 0x041c, 0x04c0, -784, 0x03e2, 0x03e2, 0x042e, 0x041e,
0x04d3, 0x042d, 0x04d2, 0x04d1, 0x043b, -784, 0x031d, 0x031d,
0x04c4, 0x046b, 0x04c3, 0x04a7, 0x032c, 0x032c, 0x04c2, 0x04b5,
0x04c1, 0x040c, 0x044b, 0x04b4, 0x046a, 0x04a6, 0x03b3, 0x03b3,
0x045a, 0x04a5, 0x032b, 0x032b, 0x03b2, 0x03b2, 0x031b, 0x031b,
0x03b1, 0x03b1, 0x040b, 0x04b0, 0x0469, 0x0496, 0x044a, 0x04a4,
0x0478, 0x0487, 0x03a3, 0x03a3, 0x043a, 0x0459, 0x032a, 0x032a,
0x0495, 0x0468, 0x03a1, 0x03a1, 0x0486, 0x0477, 0x0394, 0x0394,
0x0449, 0x0457, 0x0367, 0x0367, 0x02a2, 0x02a2, 0x02a2, 0x02a2,
0x021a, 0x021a, 0x021a, 0x021a, 0x030a, 0x030a, 0x03a0, 0x03a0,
0x0339, 0x0339, 0x0393, 0x0393, 0x0358, 0x0358, 0x0385, 0x0385,
0x0229, 0x0229, 0x0229, 0x0229, 0x0292, 0x0292, 0x0292, 0x0292,
0x0376, 0x0376, 0x0309, 0x0309, 0x0219, 0x0219, 0x0219, 0x0219,
0x0291, 0x0291, 0x0291, 0x0291, 0x0390, 0x0390, 0x0348, 0x0348,
0x0384, 0x0384, 0x0375, 0x0375, 0x0338, 0x0338, 0x0383, 0x0383,
0x0366, 0x0366, 0x0328, 0x0328, 0x0282, 0x0282, 0x0282, 0x0282,
0x0347, 0x0347, 0x0374, 0x0374, 0x0218, 0x0218, 0x0218, 0x0218,
0x0281, 0x0281, 0x0281, 0x0281, 0x0280, 0x0280, 0x0280, 0x0280,
0x0308, 0x0308, 0x0356, 0x0356, 0x0237, 0x0237, 0x0237, 0x0237,
0x0273, 0x0273, 0x0273, 0x0273, 0x0365, 0x0365, 0x0346, 0x0346,
0x0227, 0x0227, 0x0227, 0x0227, 0x0272, 0x0272, 0x0272, 0x0272,
0x0364, 0x0364, 0x0355, 0x0355, 0x0207, 0x0207, 0x0207, 0x0207,
0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117,
0x0171, 0x0171, 0x0171, 0x0171, 0x0171, 0x0171, 0x0171, 0x0171,
0x0270, 0x0270, 0x0270, 0x0270, 0x0236, 0x0236, 0x0236, 0x0236,
0x0263, 0x0263, 0x0263, 0x0263, 0x0245, 0x0245, 0x0245, 0x0245,
0x0254, 0x0254, 0x0254, 0x0254, 0x0226, 0x0226, 0x0226, 0x0226,
0x0162, 0x0162, 0x0162, 0x0162, 0x0162, 0x0162, 0x0162, 0x0162,
0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116, 0x0116,
0x0161, 0x0161, 0x0161, 0x0161, 0x0161, 0x0161, 0x0161, 0x0161,
0x0206, 0x0206, 0x0206, 0x0206, 0x0260, 0x0260, 0x0260, 0x0260,
0x0153, 0x0153, 0x0153, 0x0153, 0x0153, 0x0153, 0x0153, 0x0153,
0x0235, 0x0235, 0x0235, 0x0235, 0x0244, 0x0244, 0x0244, 0x0244,
0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125, 0x0125,
0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152, 0x0152,
0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115, 0x0115,
0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105,
0x0134, 0x0134, 0x0134, 0x0134, 0x0134, 0x0134, 0x0134, 0x0134,
0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143, 0x0143,
0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150,
0x0124, 0x0124, 0x0124, 0x0124, 0x0124, 0x0124, 0x0124, 0x0124,
0x0142, 0x0142, 0x0142, 0x0142, 0x0142, 0x0142, 0x0142, 0x0142,
0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133, 0x0133,
0x0104, 0x0104, 0x0104, 0x0104, 0x0104, 0x0104, 0x0104, 0x0104,
0x0140, 0x0140, 0x0140, 0x0140, 0x0140, 0x0140, 0x0140, 0x0140,
0x04ce, -448, 0x03de, 0x03de, 0x03e9, 0x03e9, 0x04ea, 0x04d9,
0x02ee, 0x02ee, 0x02ee, 0x02ee, 0x03ed, 0x03ed, 0x03eb, 0x03eb,
0x02be, 0x02be, 0x02be, 0x02be, 0x02cd, 0x02cd, 0x02cd, 0x02cd,
0x03dc, 0x03dc, 0x03db, 0x03db, 0x02ae, 0x02ae, 0x02ae, 0x02ae,
0x02cc, 0x02cc, 0x02cc, 0x02cc, 0x03ad, 0x03ad, 0x03da, 0x03da,
0x037e, 0x037e, 0x03ac, 0x03ac, 0x02ca, 0x02ca, 0x02ca, 0x02ca,
0x03c9, 0x03c9, 0x037d, 0x037d, 0x025e, 0x025e, 0x025e, 0x025e,
0x01bd, 0x01bd, 0x01bd, 0x01bd, 0x01bd, 0x01bd, 0x01bd, 0x01bd,
0x019e, 0x019e, 0x019e, 0x019e, 0x019e, 0x019e, 0x019e, 0x019e,
0x02bc, 0x02bc, 0x02bc, 0x02bc, 0x02cb, 0x02cb, 0x02cb, 0x02cb,
0x028e, 0x028e, 0x028e, 0x028e, 0x02e8, 0x02e8, 0x02e8, 0x02e8,
0x029d, 0x029d, 0x029d, 0x029d, 0x02e7, 0x02e7, 0x02e7, 0x02e7,
0x02bb, 0x02bb, 0x02bb, 0x02bb, 0x028d, 0x028d, 0x028d, 0x028d,
0x02d8, 0x02d8, 0x02d8, 0x02d8, 0x026e, 0x026e, 0x026e, 0x026e,
0x01e6, 0x01e6, 0x01e6, 0x01e6, 0x01e6, 0x01e6, 0x01e6, 0x01e6,
0x019c, 0x019c, 0x019c, 0x019c, 0x019c, 0x019c, 0x019c, 0x019c,
0x02ab, 0x02ab, 0x02ab, 0x02ab, 0x02ba, 0x02ba, 0x02ba, 0x02ba,
0x02e5, 0x02e5, 0x02e5, 0x02e5, 0x02d7, 0x02d7, 0x02d7, 0x02d7,
0x014e, 0x014e, 0x014e, 0x014e, 0x014e, 0x014e, 0x014e, 0x014e,
0x02e4, 0x02e4, 0x02e4, 0x02e4, 0x028c, 0x028c, 0x028c, 0x028c,
0x01c8, 0x01c8, 0x01c8, 0x01c8, 0x01c8, 0x01c8, 0x01c8, 0x01c8,
0x013e, 0x013e, 0x013e, 0x013e, 0x013e, 0x013e, 0x013e, 0x013e,
0x016d, 0x016d, 0x016d, 0x016d, 0x016d, 0x016d, 0x016d, 0x016d,
0x02d6, 0x02d6, 0x02d6, 0x02d6, 0x029b, 0x029b, 0x029b, 0x029b,
0x02b9, 0x02b9, 0x02b9, 0x02b9, 0x02aa, 0x02aa, 0x02aa, 0x02aa,
0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1, 0x01e1,
0x01d4, 0x01d4, 0x01d4, 0x01d4, 0x01d4, 0x01d4, 0x01d4, 0x01d4,
0x02b8, 0x02b8, 0x02b8, 0x02b8, 0x02a9, 0x02a9, 0x02a9, 0x02a9,
0x017b, 0x017b, 0x017b, 0x017b, 0x017b, 0x017b, 0x017b, 0x017b,
0x02b7, 0x02b7, 0x02b7, 0x02b7, 0x02d0, 0x02d0, 0x02d0, 0x02d0,
0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e, 0x010e,
0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e0, 0x01e0,
0x015d, 0x015d, 0x015d, 0x015d, 0x015d, 0x015d, 0x015d, 0x015d,
0x01d5, 0x01d5, 0x01d5, 0x01d5, 0x01d5, 0x01d5, 0x01d5, 0x01d5,
0x017c, 0x017c, 0x017c, 0x017c, 0x017c, 0x017c, 0x017c, 0x017c,
0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7, 0x01c7,
0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
0x018b, 0x018b, 0x018b, 0x018b, 0x018b, 0x018b, 0x018b, 0x018b,
0x019a, 0x019a, 0x019a, 0x019a, 0x019a, 0x019a, 0x019a, 0x019a,
0x016c, 0x016c, 0x016c, 0x016c, 0x016c, 0x016c, 0x016c, 0x016c,
0x01c6, 0x01c6, 0x01c6, 0x01c6, 0x01c6, 0x01c6, 0x01c6, 0x01c6,
0x013d, 0x013d, 0x013d, 0x013d, 0x013d, 0x013d, 0x013d, 0x013d,
0x015c, 0x015c, 0x015c, 0x015c, 0x015c, 0x015c, 0x015c, 0x015c,
0x01c5, 0x01c5, 0x01c5, 0x01c5, 0x01c5, 0x01c5, 0x01c5, 0x01c5,
0x018a, 0x018a, 0x018a, 0x018a, 0x018a, 0x018a, 0x018a, 0x018a,
0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x01a8,
0x0199, 0x0199, 0x0199, 0x0199, 0x0199, 0x0199, 0x0199, 0x0199,
0x014c, 0x014c, 0x014c, 0x014c, 0x014c, 0x014c, 0x014c, 0x014c,
0x01b6, 0x01b6, 0x01b6, 0x01b6, 0x01b6, 0x01b6, 0x01b6, 0x01b6,
0x017a, 0x017a, 0x017a, 0x017a, 0x017a, 0x017a, 0x017a, 0x017a,
0x015b, 0x015b, 0x015b, 0x015b, 0x015b, 0x015b, 0x015b, 0x015b,
0x0189, 0x0189, 0x0189, 0x0189, 0x0189, 0x0189, 0x0189, 0x0189,
0x0198, 0x0198, 0x0198, 0x0198, 0x0198, 0x0198, 0x0198, 0x0198,
0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179, 0x0179,
0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197, 0x0197,
0x0188, 0x0188, 0x0188, 0x0188, 0x0188, 0x0188, 0x0188, 0x0188,
0x01ec, 0x01ec, 0x01ec, 0x01ec, 0x01ec, 0x01ec, 0x01ec, 0x01ec,
0x01dd, 0x01dd, 0x01dd, 0x01dd, 0x01dd, 0x01dd, 0x01dd, 0x01dd,
};
static const short tab24_[] =
{
-16, -32, -48, 0x04ff, -64, -80, -96, -112,
-128, -144, -160, -176, 0x0411, 0x0401, 0x0410, 0x0400,
0x04ef, 0x04fe, 0x04df, 0x04fd, 0x04cf, 0x04fc, 0x04bf, 0x04fb,
0x03fa, 0x03fa, 0x04af, 0x049f, 0x03f9, 0x03f9, 0x03f8, 0x03f8,
0x048f, 0x047f, 0x03f7, 0x03f7, 0x036f, 0x036f, 0x03f6, 0x03f6,
0x035f, 0x035f, 0x03f5, 0x03f5, 0x034f, 0x034f, 0x03f4, 0x03f4,
0x033f, 0x033f, 0x03f3, 0x03f3, 0x032f, 0x032f, 0x03f2, 0x03f2,
0x03f1, 0x03f1, 0x041f, 0x04f0, -144, -160, -176, -192,
-192, -208, -224, -240, -256, -272, -288, -304,
-320, -336, -352, -368, -384, -400, -416, -432,
-432, -448, -464, -480, -496, -512, -528, -544,
-560, -576, -592, -608, -624, -640, -656, -672,
-672, -688, -704, -720, -736, -752, -768, -784,
-800, -816, -832, -848, -864, 0x0473, -880, 0x0472,
0x0446, 0x0464, 0x0455, 0x0471, 0x0436, 0x0463, 0x0445, 0x0454,
0x0426, 0x0462, 0x0416, 0x0461, -880, 0x0435, 0x0453, 0x0444,
0x0425, 0x0452, 0x0415, -880, 0x0351, 0x0351, 0x0434, 0x0443,
0x0324, 0x0324, 0x0342, 0x0342, 0x0333, 0x0333, 0x0314, 0x0314,
0x0341, 0x0341, 0x0404, 0x0440, 0x0323, 0x0323, 0x0332, 0x0332,
0x0213, 0x0213, 0x0213, 0x0213, 0x0231, 0x0231, 0x0231, 0x0231,
0x0303, 0x0303, 0x0330, 0x0330, 0x0222, 0x0222, 0x0222, 0x0222,
0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112, 0x0112,
0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121,
0x0202, 0x0202, 0x0202, 0x0202, 0x0220, 0x0220, 0x0220, 0x0220,
0x010f, 0x010f, 0x010f, 0x010f, 0x010f, 0x010f, 0x010f, 0x010f,
0x03ee, 0x03ee, 0x03de, 0x03de, 0x03ed, 0x03ed, 0x03ce, 0x03ce,
0x03ec, 0x03ec, 0x03dd, 0x03dd, 0x03be, 0x03be, 0x03eb, 0x03eb,
0x03cd, 0x03cd, 0x03dc, 0x03dc, 0x03ae, 0x03ae, 0x03ea, 0x03ea,
0x03bd, 0x03bd, 0x03db, 0x03db, 0x03cc, 0x03cc, 0x039e, 0x039e,
0x03e9, 0x03e9, 0x03ad, 0x03ad, 0x03da, 0x03da, 0x03bc, 0x03bc,
0x03cb, 0x03cb, 0x038e, 0x038e, 0x03e8, 0x03e8, 0x039d, 0x039d,
0x03d9, 0x03d9, 0x037e, 0x037e, 0x03e7, 0x03e7, 0x03ac, 0x03ac,
0x03ca, 0x03ca, 0x03bb, 0x03bb, 0x038d, 0x038d, 0x03d8, 0x03d8,
0x040e, 0x04e0, 0x030d, 0x030d, 0x02e6, 0x02e6, 0x02e6, 0x02e6,
0x036e, 0x036e, 0x039c, 0x039c, 0x02c9, 0x02c9, 0x02c9, 0x02c9,
0x025e, 0x025e, 0x025e, 0x025e, 0x02ba, 0x02ba, 0x02ba, 0x02ba,
0x02e5, 0x02e5, 0x02e5, 0x02e5, 0x03ab, 0x03ab, 0x037d, 0x037d,
0x02d7, 0x02d7, 0x02d7, 0x02d7, 0x02e4, 0x02e4, 0x02e4, 0x02e4,
0x028c, 0x028c, 0x028c, 0x028c, 0x02c8, 0x02c8, 0x02c8, 0x02c8,
0x034e, 0x034e, 0x032e, 0x032e, 0x023e, 0x023e, 0x023e, 0x023e,
0x026d, 0x026d, 0x026d, 0x026d, 0x02d6, 0x02d6, 0x02d6, 0x02d6,
0x02e3, 0x02e3, 0x02e3, 0x02e3, 0x029b, 0x029b, 0x029b, 0x029b,
0x02b9, 0x02b9, 0x02b9, 0x02b9, 0x02aa, 0x02aa, 0x02aa, 0x02aa,
0x02e2, 0x02e2, 0x02e2, 0x02e2, 0x021e, 0x021e, 0x021e, 0x021e,
0x02e1, 0x02e1, 0x02e1, 0x02e1, 0x025d, 0x025d, 0x025d, 0x025d,
0x02d5, 0x02d5, 0x02d5, 0x02d5, 0x027c, 0x027c, 0x027c, 0x027c,
0x02c7, 0x02c7, 0x02c7, 0x02c7, 0x024d, 0x024d, 0x024d, 0x024d,
0x028b, 0x028b, 0x028b, 0x028b, 0x02b8, 0x02b8, 0x02b8, 0x02b8,
0x02d4, 0x02d4, 0x02d4, 0x02d4, 0x029a, 0x029a, 0x029a, 0x029a,
0x02a9, 0x02a9, 0x02a9, 0x02a9, 0x026c, 0x026c, 0x026c, 0x026c,
0x02c6, 0x02c6, 0x02c6, 0x02c6, 0x023d, 0x023d, 0x023d, 0x023d,
0x02d3, 0x02d3, 0x02d3, 0x02d3, 0x022d, 0x022d, 0x022d, 0x022d,
0x02d2, 0x02d2, 0x02d2, 0x02d2, 0x021d, 0x021d, 0x021d, 0x021d,
0x027b, 0x027b, 0x027b, 0x027b, 0x02b7, 0x02b7, 0x02b7, 0x02b7,
0x02d1, 0x02d1, 0x02d1, 0x02d1, 0x025c, 0x025c, 0x025c, 0x025c,
0x02c5, 0x02c5, 0x02c5, 0x02c5, 0x028a, 0x028a, 0x028a, 0x028a,
0x02a8, 0x02a8, 0x02a8, 0x02a8, 0x0299, 0x0299, 0x0299, 0x0299,
0x024c, 0x024c, 0x024c, 0x024c, 0x02c4, 0x02c4, 0x02c4, 0x02c4,
0x026b, 0x026b, 0x026b, 0x026b, 0x02b6, 0x02b6, 0x02b6, 0x02b6,
0x03d0, 0x03d0, 0x030c, 0x030c, 0x023c, 0x023c, 0x023c, 0x023c,
0x02c3, 0x02c3, 0x02c3, 0x02c3, 0x027a, 0x027a, 0x027a, 0x027a,
0x02a7, 0x02a7, 0x02a7, 0x02a7, 0x022c, 0x022c, 0x022c, 0x022c,
0x02c2, 0x02c2, 0x02c2, 0x02c2, 0x025b, 0x025b, 0x025b, 0x025b,
0x02b5, 0x02b5, 0x02b5, 0x02b5, 0x021c, 0x021c, 0x021c, 0x021c,
0x0289, 0x0289, 0x0289, 0x0289, 0x0298, 0x0298, 0x0298, 0x0298,
0x02c1, 0x02c1, 0x02c1, 0x02c1, 0x024b, 0x024b, 0x024b, 0x024b,
0x03c0, 0x03c0, 0x030b, 0x030b, 0x023b, 0x023b, 0x023b, 0x023b,
0x03b0, 0x03b0, 0x030a, 0x030a, 0x021a, 0x021a, 0x021a, 0x021a,
0x01b4, 0x01b4, 0x01b4, 0x01b4, 0x01b4, 0x01b4, 0x01b4, 0x01b4,
0x026a, 0x026a, 0x026a, 0x026a, 0x02a6, 0x02a6, 0x02a6, 0x02a6,
0x0279, 0x0279, 0x0279, 0x0279, 0x0297, 0x0297, 0x0297, 0x0297,
0x03a0, 0x03a0, 0x0309, 0x0309, 0x0290, 0x0290, 0x0290, 0x0290,
0x01b3, 0x01b3, 0x01b3, 0x01b3, 0x01b3, 0x01b3, 0x01b3, 0x01b3,
0x0188, 0x0188, 0x0188, 0x0188, 0x0188, 0x0188, 0x0188, 0x0188,
0x022b, 0x022b, 0x022b, 0x022b, 0x025a, 0x025a, 0x025a, 0x025a,
0x01b2, 0x01b2, 0x01b2, 0x01b2, 0x01b2, 0x01b2, 0x01b2, 0x01b2,
0x02a5, 0x02a5, 0x02a5, 0x02a5, 0x021b, 0x021b, 0x021b, 0x021b,
0x02b1, 0x02b1, 0x02b1, 0x02b1, 0x0269, 0x0269, 0x0269, 0x0269,
0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196, 0x0196,
0x01a4, 0x01a4, 0x01a4, 0x01a4, 0x01a4, 0x01a4, 0x01a4, 0x01a4,
0x024a, 0x024a, 0x024a, 0x024a, 0x0278, 0x0278, 0x0278, 0x0278,
0x0187, 0x0187, 0x0187, 0x0187, 0x0187, 0x0187, 0x0187, 0x0187,
0x013a, 0x013a, 0x013a, 0x013a, 0x013a, 0x013a, 0x013a, 0x013a,
0x01a3, 0x01a3, 0x01a3, 0x01a3, 0x01a3, 0x01a3, 0x01a3, 0x01a3,
0x0159, 0x0159, 0x0159, 0x0159, 0x0159, 0x0159, 0x0159, 0x0159,
0x0195, 0x0195, 0x0195, 0x0195, 0x0195, 0x0195, 0x0195, 0x0195,
0x012a, 0x012a, 0x012a, 0x012a, 0x012a, 0x012a, 0x012a, 0x012a,
0x01a2, 0x01a2, 0x01a2, 0x01a2, 0x01a2, 0x01a2, 0x01a2, 0x01a2,
0x01a1, 0x01a1, 0x01a1, 0x01a1, 0x01a1, 0x01a1, 0x01a1, 0x01a1,
0x0168, 0x0168, 0x0168, 0x0168, 0x0168, 0x0168, 0x0168, 0x0168,
0x0186, 0x0186, 0x0186, 0x0186, 0x0186, 0x0186, 0x0186, 0x0186,
0x0177, 0x0177, 0x0177, 0x0177, 0x0177, 0x0177, 0x0177, 0x0177,
0x0149, 0x0149, 0x0149, 0x0149, 0x0149, 0x0149, 0x0149, 0x0149,
0x0194, 0x0194, 0x0194, 0x0194, 0x0194, 0x0194, 0x0194, 0x0194,
0x0139, 0x0139, 0x0139, 0x0139, 0x0139, 0x0139, 0x0139, 0x0139,
0x0193, 0x0193, 0x0193, 0x0193, 0x0193, 0x0193, 0x0193, 0x0193,
0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158, 0x0158,
0x0185, 0x0185, 0x0185, 0x0185, 0x0185, 0x0185, 0x0185, 0x0185,
0x0129, 0x0129, 0x0129, 0x0129, 0x0129, 0x0129, 0x0129, 0x0129,
0x0167, 0x0167, 0x0167, 0x0167, 0x0167, 0x0167, 0x0167, 0x0167,
0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176, 0x0176,
0x0192, 0x0192, 0x0192, 0x0192, 0x0192, 0x0192, 0x0192, 0x0192,
0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119, 0x0119,
0x0191, 0x0191, 0x0191, 0x0191, 0x0191, 0x0191, 0x0191, 0x0191,
0x0148, 0x0148, 0x0148, 0x0148, 0x0148, 0x0148, 0x0148, 0x0148,
0x0184, 0x0184, 0x0184, 0x0184, 0x0184, 0x0184, 0x0184, 0x0184,
0x0157, 0x0157, 0x0157, 0x0157, 0x0157, 0x0157, 0x0157, 0x0157,
0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175, 0x0175,
0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138, 0x0138,
0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183,
0x0166, 0x0166, 0x0166, 0x0166, 0x0166, 0x0166, 0x0166, 0x0166,
0x0128, 0x0128, 0x0128, 0x0128, 0x0128, 0x0128, 0x0128, 0x0128,
0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182,
0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118, 0x0118,
0x0147, 0x0147, 0x0147, 0x0147, 0x0147, 0x0147, 0x0147, 0x0147,
0x0174, 0x0174, 0x0174, 0x0174, 0x0174, 0x0174, 0x0174, 0x0174,
0x0181, 0x0181, 0x0181, 0x0181, 0x0181, 0x0181, 0x0181, 0x0181,
0x0208, 0x0208, 0x0208, 0x0208, 0x0280, 0x0280, 0x0280, 0x0280,
0x0156, 0x0156, 0x0156, 0x0156, 0x0156, 0x0156, 0x0156, 0x0156,
0x0165, 0x0165, 0x0165, 0x0165, 0x0165, 0x0165, 0x0165, 0x0165,
0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117, 0x0117,
0x0207, 0x0207, 0x0207, 0x0207, 0x0270, 0x0270, 0x0270, 0x0270,
0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137, 0x0137,
0x0127, 0x0127, 0x0127, 0x0127, 0x0127, 0x0127, 0x0127, 0x0127,
0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106, 0x0106,
0x0160, 0x0160, 0x0160, 0x0160, 0x0160, 0x0160, 0x0160, 0x0160,
0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105, 0x0105,
0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150, 0x0150,
};
static const 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 const 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 const 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 const struct newhuff htc[] =
{
{ /* 1 , 1 , */ 0 , tab_c0 } ,
{ /* 1 , 1 , */ 0 , tab_c1 }
};
#endif

View File

@ -0,0 +1,148 @@
/*
ntom.c: N->M down/up sampling; the setup code.
copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
#define SAFE_NTOM /* Do not depend on off_t*off_t with big values still being in the range... */
#include "mpg123lib_intern.h"
#include "debug.h"
int synth_ntom_set_step(mpg123_handle *fr)
{
long m,n;
m = frame_freq(fr);
n = fr->af.rate;
if(VERBOSE2)
fprintf(stderr,"Init rate converter: %ld->%ld\n",m,n);
if(n > NTOM_MAX_FREQ || m > NTOM_MAX_FREQ || m <= 0 || n <= 0) {
if(NOQUIET) error("NtoM converter: illegal rates");
fr->err = MPG123_BAD_RATE;
return -1;
}
n *= NTOM_MUL;
fr->ntom_step = (unsigned long) n / m;
if(fr->ntom_step > (unsigned long)NTOM_MAX*NTOM_MUL) {
if(NOQUIET) error3("max. 1:%i conversion allowed (%lu vs %lu)!", NTOM_MAX, fr->ntom_step, (unsigned long)8*NTOM_MUL);
fr->err = MPG123_BAD_RATE;
return -1;
}
fr->ntom_val[0] = fr->ntom_val[1] = ntom_val(fr, fr->num);
return 0;
}
/*
The SAFE_NTOM does iterative loops instead of straight multiplication.
The safety is not just about the algorithm closely mimicking the decoder instead of applying some formula,
it is more about avoiding multiplication of possibly big sample offsets (a 32bit off_t could overflow too easily).
*/
unsigned long ntom_val(mpg123_handle *fr, off_t frame)
{
off_t ntm;
#ifdef SAFE_NTOM /* Carry out the loop, without the threatening integer overflow. */
off_t f;
ntm = NTOM_MUL>>1; /* for frame 0 */
for(f=0; f<frame; ++f) /* for frame > 0 */
{
ntm += fr->spf*fr->ntom_step;
ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
}
#else /* Just make one computation with overall sample offset. */
ntm = (NTOM_MUL>>1) + fr->spf*frame*fr->ntom_step;
ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
#endif
return (unsigned long) ntm;
}
/* Set the ntom value for next expected frame to be decoded.
This is for keeping output consistent across seeks. */
void ntom_set_ntom(mpg123_handle *fr, off_t num)
{
fr->ntom_val[1] = fr->ntom_val[0] = ntom_val(fr, num);
}
/* Carry out the ntom sample count operation for this one frame.
No fear of integer overflow here. */
off_t ntom_frame_outsamples(mpg123_handle *fr)
{
/* The do this before decoding the separate channels, so there is only one common ntom value. */
int ntm = fr->ntom_val[0];
ntm += fr->spf*fr->ntom_step;
return ntm/NTOM_MUL;
}
/* Convert frame offset to unadjusted output sample offset. */
off_t ntom_frmouts(mpg123_handle *fr, off_t frame)
{
#ifdef SAFE_NTOM
off_t f;
#endif
off_t soff = 0;
off_t ntm = ntom_val(fr,0);
#ifdef SAFE_NTOM
if(frame <= 0) return 0;
for(f=0; f<frame; ++f)
{
ntm += fr->spf*fr->ntom_step;
soff += ntm/NTOM_MUL;
ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
}
#else
soff = (ntm + frame*(off_t)fr->spf*(off_t)fr->ntom_step)/(off_t)NTOM_MUL;
#endif
return soff;
}
/* Convert input samples to unadjusted output samples. */
off_t ntom_ins2outs(mpg123_handle *fr, off_t ins)
{
off_t soff = 0;
off_t ntm = ntom_val(fr,0);
#ifdef SAFE_NTOM
{
off_t block = fr->spf;
if(ins <= 0) return 0;
do
{
off_t nowblock = ins > block ? block : ins;
ntm += nowblock*fr->ntom_step;
soff += ntm/NTOM_MUL;
ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
ins -= nowblock;
} while(ins > 0);
}
#else
/* Beware of overflows: when off_t is 32bits, the multiplication blows too easily.
Of course, it blows for 64bits, too, in theory, but that's for _really_ large files. */
soff = ((off_t)ntm + (off_t)ins*(off_t)fr->ntom_step)/(off_t)NTOM_MUL;
#endif
return soff;
}
/* Determine frame offset from unadjusted output sample offset. */
off_t ntom_frameoff(mpg123_handle *fr, off_t soff)
{
off_t ioff = 0; /* frames or samples */
off_t ntm = ntom_val(fr,0);
#ifdef SAFE_NTOM
if(soff <= 0) return 0;
for(ioff=0; 1; ++ioff)
{
ntm += fr->spf*fr->ntom_step;
if(ntm/NTOM_MUL > soff) break;
soff -= ntm/NTOM_MUL;
ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
}
return ioff;
#else
ioff = (soff*(off_t)NTOM_MUL-ntm)/(off_t)fr->ntom_step;
return ioff/(off_t)fr->spf;
#endif
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,391 @@
#ifndef MPG123_H_OPTIMIZE
#define MPG123_H_OPTIMIZE
/*
optimize: get a grip on the different optimizations
copyright 2007-2013 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis, taking from mpg123.[hc]
for building mpg123 with one optimization only, you have to choose exclusively between
OPT_GENERIC (generic C code for everyone)
OPT_GENERIC_DITHER (same with dithering for 1to1)
OPT_I386 (Intel i386)
OPT_I486 (Somewhat special code for i486; does not work together with others.)
OPT_I586 (Intel Pentium)
OPT_I586_DITHER (Intel Pentium with dithering/noise shaping for enhanced quality)
OPT_MMX (Intel Pentium and compatibles with MMX, fast, but not the best accuracy)
OPT_3DNOW (AMD 3DNow!, K6-2/3, Athlon, compatibles...)
OPT_3DNOW_VINTAGE
OPT_3DNOWEXT (AMD 3DNow! extended, generally Athlon, compatibles...)
OPT_3DNOWEXT_VINTAGE
OPT_SSE
OPT_SSE_VINTAGE
OPT_ALTIVEC (Motorola/IBM PPC with AltiVec under MacOSX)
OPT_X86_64 (x86-64 / AMD64 / Intel 64)
OPT_AVX
or you define OPT_MULTI and give a combination which makes sense (do not include i486, do not mix altivec and x86).
I still have to examine the dynamics of this here together with REAL_IS_FIXED.
Basic point is: Don't use REAL_IS_FIXED with something else than generic or i386.
Also, one should minimize code size by really ensuring that only functions that are really needed are included.
Currently, all generic functions will be always there (to be safe for fallbacks for advanced decoders).
Strictly, at least the synth_1to1 should not be necessary for single-decoder mode.
*/
/* Runtime optimization interface now here: */
/* Nedit inline Perl script to generate decoder list and name mapping in one place
optimize.c defining I_AM_OPTIMIZE to get the names
perl <<'EOT'
## order is important (autodec first, nodec last)
@names=
(
['autodec', 'auto']
,['generic', 'generic']
,['generic_dither', 'generic_dither']
,['idrei', 'i386']
,['ivier', 'i486']
,['ifuenf', 'i586']
,['ifuenf_dither', 'i586_dither']
,['mmx', 'MMX']
,['dreidnow', '3DNow']
,['dreidnowext', '3DNowExt']
,['altivec', 'AltiVec']
,['sse', 'SSE']
,['x86_64', 'x86-64']
,['arm','ARM']
,['neon','NEON']
,['avx','AVX']
,['dreidnow_vintage', '3DNow_vintage']
,['dreidnowext_vintage', '3DNowExt_vintage']
,['sse_vintage', 'SSE_vintage']
,['nodec', 'nodec']
);
print "enum optdec\n{\n";
for my $n (@names)
{
$name = $n->[0];
$enum = $name eq 'autodec' ? $name = " $name=0" : ",$name";
print "\t$enum\n"
}
print "};\n";
print "##ifdef I_AM_OPTIMIZE\n";
for my $n (@names)
{
my $key = $n->[0];
my $val = $n->[1];
print "static const char dn_$key\[\] = \"$val\";\n";
}
print "static const char* decname[] =\n{\n";
for my $n (@names)
{
my $key = $n->[0];
print "\t".($key eq 'autodec' ? ' ' : ',')."dn_$key\n";
}
print "};\n##endif"
EOT
*/
enum optdec
{
autodec=0
,generic
,generic_dither
,idrei
,ivier
,ifuenf
,ifuenf_dither
,mmx
,dreidnow
,dreidnowext
,altivec
,sse
,x86_64
,arm
,neon
,neon64
,avx
,dreidnow_vintage
,dreidnowext_vintage
,sse_vintage
,nodec
};
#ifdef I_AM_OPTIMIZE
static const char dn_autodec[] = "auto";
static const char dn_generic[] = "generic";
static const char dn_generic_dither[] = "generic_dither";
static const char dn_idrei[] = "i386";
static const char dn_ivier[] = "i486";
static const char dn_ifuenf[] = "i586";
static const char dn_ifuenf_dither[] = "i586_dither";
static const char dn_mmx[] = "MMX";
static const char dn_dreidnow[] = "3DNow";
static const char dn_dreidnowext[] = "3DNowExt";
static const char dn_altivec[] = "AltiVec";
static const char dn_sse[] = "SSE";
static const char dn_x86_64[] = "x86-64";
static const char dn_arm[] = "ARM";
static const char dn_neon[] = "NEON";
static const char dn_neon64[] = "NEON64";
static const char dn_avx[] = "AVX";
static const char dn_dreidnow_vintage[] = "3DNow_vintage";
static const char dn_dreidnowext_vintage[] = "3DNowExt_vintage";
static const char dn_sse_vintage[] = "SSE_vintage";
static const char dn_nodec[] = "nodec";
static const char* decname[] =
{
dn_autodec
,dn_generic
,dn_generic_dither
,dn_idrei
,dn_ivier
,dn_ifuenf
,dn_ifuenf_dither
,dn_mmx
,dn_dreidnow
,dn_dreidnowext
,dn_altivec
,dn_sse
,dn_x86_64
,dn_arm
,dn_neon
,dn_neon64
,dn_avx
,dn_dreidnow_vintage
,dn_dreidnowext_vintage
,dn_sse_vintage
,dn_nodec
};
#endif
enum optcla { nocla=0, normal, mmxsse };
/* - Set up the table of synth functions for current decoder choice. */
int frame_cpu_opt(mpg123_handle *fr, const char* cpu);
/* - Choose, from the synth table, the synth functions to use for current output format/rate. */
int set_synth_functions(mpg123_handle *fr);
/* - Parse decoder name and return numerical code. */
enum optdec dectype(const char* decoder);
/* - Return the default decoder type. */
enum optdec defdec(void);
/* - Return the class of a decoder type (mmxsse or normal). */
enum optcla decclass(const enum optdec);
/* Now comes a whole lot of definitions, for multi decoder mode and single decoder mode.
Because of the latter, it may look redundant at times. */
/* this is included in mpg123.h, which includes config.h */
#ifdef CCALIGN
#define ALIGNED(a) __attribute__((aligned(a)))
#else
#define ALIGNED(a)
#endif
/* Safety catch for invalid decoder choice. */
#ifdef REAL_IS_FIXED
#if (defined OPT_I486) || (defined OPT_I586) || (defined OPT_I586_DITHER) \
|| (defined OPT_MMX) || (defined OPT_SSE) || (defined_OPT_ALTIVEC) \
|| (defined OPT_3DNOW) || (defined OPT_3DNOWEXT) || (defined OPT_X86_64) \
|| (defined OPT_3DNOW_VINTAGE) || (defined OPT_3DNOWEXT_VINTAGE) \
|| (defined OPT_SSE_VINTAGE) \
|| (defined OPT_NEON) || (defined OPT_NEON64) || (defined OPT_AVX) \
|| (defined OPT_GENERIC_DITHER)
#error "Bad decoder choice together with fixed point math!"
#endif
#endif
#if (defined NO_LAYER1 && defined NO_LAYER2)
#define NO_LAYER12
#endif
#ifdef OPT_GENERIC
#ifndef OPT_MULTI
# define defopt generic
#endif
#endif
#ifdef OPT_GENERIC_DITHER
#define OPT_DITHER
#ifndef OPT_MULTI
# define defopt generic_dither
#endif
#endif
/* i486 is special... always alone! */
#ifdef OPT_I486
#define OPT_X86
#define defopt ivier
#ifdef OPT_MULTI
#error "i486 can only work alone!"
#endif
#define FIR_BUFFER_SIZE 128
#define FIR_SIZE 16
#endif
#ifdef OPT_I386
#define OPT_X86
#ifndef OPT_MULTI
# define defopt idrei
#endif
#endif
#ifdef OPT_I586
#define OPT_X86
#ifndef OPT_MULTI
# define defopt ifuenf
#endif
#endif
#ifdef OPT_I586_DITHER
#define OPT_X86
#define OPT_DITHER
#ifndef OPT_MULTI
# define defopt ifuenf_dither
#endif
#endif
/* We still have some special code around MMX tables. */
#ifdef OPT_MMX
#define OPT_MMXORSSE
#define OPT_X86
#ifndef OPT_MULTI
# define defopt mmx
#endif
#endif
#ifdef OPT_SSE
#define OPT_MMXORSSE
#define OPT_MPLAYER
#define OPT_X86
#ifndef OPT_MULTI
# define defopt sse
# define opt_dct36(fr) dct36_sse
#endif
#endif
#ifdef OPT_SSE_VINTAGE
#define OPT_MMXORSSE
#define OPT_MPLAYER
#define OPT_X86
#ifndef OPT_MULTI
# define defopt sse
#endif
#endif
#ifdef OPT_3DNOWEXT
#define OPT_MMXORSSE
#define OPT_MPLAYER
#define OPT_X86
#ifndef OPT_MULTI
# define defopt dreidnowext
#endif
#endif
/* same as above but also using 3DNowExt dct36 */
#ifdef OPT_3DNOWEXT_VINTAGE
#define OPT_MMXORSSE
#define OPT_MPLAYER
#define OPT_X86
#ifndef OPT_MULTI
# define defopt dreidnowext_vintage
# define opt_dct36(fr) dct36_3dnowext
#endif
#endif
#ifdef OPT_MPLAYER
extern const int costab_mmxsse[];
#endif
/* 3dnow used to use synth_1to1_i586 for mono / 8bit conversion - was that intentional? */
/* I'm trying to skip the pentium code here ... until I see that that is indeed a bad idea */
#ifdef OPT_3DNOW
#define OPT_X86
#ifndef OPT_MULTI
# define defopt dreidnow
#endif
#endif
/* same as above but also using 3DNow dct36 */
#ifdef OPT_3DNOW_VINTAGE
#define OPT_X86
#ifndef OPT_MULTI
# define defopt dreidnow_vintage
# define opt_dct36(fr) dct36_3dnow
#endif
#endif
#ifdef OPT_ALTIVEC
#ifndef OPT_MULTI
# define defopt altivec
#endif
#endif
#ifdef OPT_X86_64
#define OPT_MMXORSSE
#ifndef OPT_MULTI
# define defopt x86_64
# define opt_dct36(fr) dct36_x86_64
#endif
#endif
#ifdef OPT_AVX
#define OPT_MMXORSSE
#ifndef OPT_MULTI
# define defopt avx
# define opt_dct36(fr) dct36_avx
#endif
#endif
#ifdef OPT_ARM
#ifndef OPT_MULTI
# define defopt arm
#endif
#endif
#ifdef OPT_NEON
#define OPT_MMXORSSE
#ifndef OPT_MULTI
# define defopt neon
# define opt_dct36(fr) dct36_neon
#endif
#endif
#ifdef OPT_NEON64
#define OPT_MMXORSSE
#ifndef OPT_MULTI
# define defopt neon64
# define opt_dct36(fr) dct36_neon64
#endif
#endif
/* used for multi opt mode and the single 3dnow mode to have the old 3dnow test flag still working */
void check_decoders(void);
/*
Now come two blocks of standard definitions for multi-decoder mode and single-decoder mode.
Most stuff is so automatic that it's indeed generated by some inline shell script.
Remember to use these scripts when possible, instead of direct repetitive hacking.
*/
#ifdef OPT_MULTI
# define defopt nodec
# if (defined OPT_3DNOW_VINTAGE || defined OPT_3DNOWEXT_VINTAGE || defined OPT_SSE || defined OPT_X86_64 || defined OPT_AVX || defined OPT_NEON || defined OPT_NEON64)
# define opt_dct36(fr) ((fr)->cpu_opts.the_dct36)
# endif
#endif /* OPT_MULTI else */
# ifndef opt_dct36
# define opt_dct36(fr) dct36
# endif
#endif /* MPG123_H_OPTIMIZE */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
/*
parse: spawned from common; clustering around stream/frame parsing
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp & Thomas Orgis
*/
#ifndef MPG123_PARSE_H
#define MPG123_PARSE_H
#include "frame.h"
int read_frame_init(mpg123_handle* fr);
int frame_bitrate(mpg123_handle *fr);
long frame_freq(mpg123_handle *fr);
int read_frame_recover(mpg123_handle* fr); /* dead? */
int read_frame(mpg123_handle *fr);
void set_pointer(mpg123_handle *fr, long backstep);
int position_info(mpg123_handle* fr, unsigned long no, long buffsize, unsigned long* frames_left, double* current_seconds, double* seconds_left);
double compute_bpf(mpg123_handle *fr);
long time_to_frame(mpg123_handle *fr, double seconds);
int get_songlen(mpg123_handle *fr,int no);
#endif

View File

@ -0,0 +1,137 @@
/*
reader: reading input data
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis (after code from Michael Hipp)
*/
#ifndef MPG123_READER_H
#define MPG123_READER_H
#include "config.h"
#include "mpg123.h"
#ifndef NO_FEEDER
struct buffy
{
unsigned char *data;
ssize_t size;
ssize_t realsize;
struct buffy *next;
};
struct bufferchain
{
struct buffy* first; /* The beginning of the chain. */
struct buffy* last; /* The end... of the chain. */
ssize_t size; /* Aggregated size of all buffies. */
/* These positions are relative to buffer chain beginning. */
ssize_t pos; /* Position in whole chain. */
ssize_t firstpos; /* The point of return on non-forget() */
/* The "real" filepos is fileoff + pos. */
off_t fileoff; /* Beginning of chain is at this file offset. */
size_t bufblock; /* Default (minimal) size of buffers. */
size_t pool_size; /* Keep that many buffers in storage. */
size_t pool_fill; /* That many buffers are there. */
/* A pool of buffers to re-use, if activated. It's a linked list that is worked on from the front. */
struct buffy *pool;
};
/* Call this before any buffer chain use (even bc_init()). */
void bc_prepare(struct bufferchain *, size_t pool_size, size_t bufblock);
/* Free persistent data in the buffer chain, after bc_reset(). */
void bc_cleanup(struct bufferchain *);
/* Change pool size. This does not actually allocate/free anything on itself, just instructs later operations to free less / allocate more buffers. */
void bc_poolsize(struct bufferchain *, size_t pool_size, size_t bufblock);
/* Return available byte count in the buffer. */
size_t bc_fill(struct bufferchain *bc);
#endif
struct reader_data
{
off_t filelen; /* total file length or total buffer size */
off_t filepos; /* position in file or position in buffer chain */
int filept;
/* Custom opaque I/O handle from the client. */
void *iohandle;
int flags;
long timeout_sec;
ssize_t (*fdread) (mpg123_handle *, void *, size_t);
/* User can replace the read and lseek functions. The r_* are the stored replacement functions or NULL. */
ssize_t (*r_read) (int fd, void *buf, size_t count);
off_t (*r_lseek)(int fd, off_t offset, int whence);
/* These are custom I/O routines for opaque user handles.
They get picked if there's some iohandle set. */
ssize_t (*r_read_handle) (void *handle, void *buf, size_t count);
off_t (*r_lseek_handle)(void *handle, off_t offset, int whence);
/* An optional cleaner for the handle on closing the stream. */
void (*cleanup_handle)(void *handle);
/* These two pointers are the actual workers (default map to POSIX read/lseek). */
ssize_t (*read) (int fd, void *buf, size_t count);
off_t (*lseek)(int fd, off_t offset, int whence);
/* Buffered readers want that abstracted, set internally. */
ssize_t (*fullread)(mpg123_handle *, unsigned char *, ssize_t);
#ifndef NO_FEEDER
struct bufferchain buffer; /* Not dynamically allocated, these few struct bytes aren't worth the trouble. */
#endif
};
/* start to use off_t to properly do LFS in future ... used to be long */
struct reader
{
int (*init) (mpg123_handle *);
void (*close) (mpg123_handle *);
ssize_t (*fullread) (mpg123_handle *, unsigned char *, ssize_t);
int (*head_read) (mpg123_handle *, unsigned long *newhead); /* succ: TRUE, else <= 0 (FALSE or READER_MORE) */
int (*head_shift) (mpg123_handle *, unsigned long *head); /* succ: TRUE, else <= 0 (FALSE or READER_MORE) */
off_t (*skip_bytes) (mpg123_handle *, off_t len); /* succ: >=0, else error or READER_MORE */
int (*read_frame_body)(mpg123_handle *, unsigned char *, int size);
int (*back_bytes) (mpg123_handle *, off_t bytes);
int (*seek_frame) (mpg123_handle *, off_t num);
off_t (*tell) (mpg123_handle *);
void (*rewind) (mpg123_handle *);
void (*forget) (mpg123_handle *);
};
/* Open a file by path or use an opened file descriptor. */
int open_stream(mpg123_handle *, const char *path, int fd);
/* Open an external handle. */
int open_stream_handle(mpg123_handle *, void *iohandle);
/* feed based operation has some specials */
int open_feed(mpg123_handle *);
/* externally called function, returns 0 on success, -1 on error */
int feed_more(mpg123_handle *fr, const unsigned char *in, long count);
void feed_forget(mpg123_handle *fr); /* forget the data that has been read (free some buffers) */
off_t feed_set_pos(mpg123_handle *fr, off_t pos); /* Set position (inside available data if possible), return wanted byte offset of next feed. */
void open_bad(mpg123_handle *);
#define READER_FD_OPENED 0x1
#define READER_ID3TAG 0x2
#define READER_SEEKABLE 0x4
#define READER_BUFFERED 0x8
#define READER_NONBLOCK 0x20
#define READER_HANDLEIO 0x40
#define READER_STREAM 0
#define READER_ICY_STREAM 1
#define READER_FEED 2
/* These two add a little buffering to enable small seeks for peek ahead. */
#define READER_BUF_STREAM 3
#define READER_BUF_ICY_STREAM 4
#ifdef READ_SYSTEM
#define READER_SYSTEM 5
#define READERS 6
#else
#define READERS 5
#endif
#define READER_ERROR MPG123_ERR
#define READER_MORE MPG123_NEED_MORE
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,154 @@
/*
sample.h: The conversion from internal data to output samples of differing formats.
copyright 2007-9 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis, taking WRITE_SAMPLE from decode.c
Later added the end-conversion specific macros here, too.
*/
#ifndef SAMPLE_H
#define SAMPLE_H
/* mpg123lib_intern.h is included already, right? */
/* Special case is fixed point math... which does work, but not that nice yet. */
#ifdef REAL_IS_FIXED
static inline int16_t idiv_signed_rounded(int32_t x, int shift)
{
x >>= (shift - 1);
x += (x & 1);
return (int16_t)(x >> 1);
}
# define REAL_PLUS_32767 ( 32767 << 15 )
# define REAL_MINUS_32768 ( -32768 << 15 )
# define REAL_TO_SHORT(x) (idiv_signed_rounded(x, 15))
/* No better code (yet). */
# define REAL_TO_SHORT_ACCURATE(x) REAL_TO_SHORT(x)
/* This is just here for completeness, it is not used! */
# define REAL_TO_S32(x) (x)
#endif
/* From now on for single precision float... double precision is a possible option once we added some bits. But, it would be rather insane. */
#ifndef REAL_TO_SHORT
#if (defined FORCE_ACCURATE) || (defined ACCURATE_ROUNDING)
/* Define the accurate rounding function. */
# if (defined REAL_IS_FLOAT) && (defined IEEE_FLOAT)
/* This function is only available for IEEE754 single-precision values
This is nearly identical to proper rounding, just -+0.5 is rounded to 0 */
static inline int16_t ftoi16(float x)
{
union
{
float f;
int32_t i;
} u_fi;
u_fi.f = x + 12582912.0f; /* Magic Number: 2^23 + 2^22 */
return (int16_t)u_fi.i;
}
# define REAL_TO_SHORT_ACCURATE(x) ftoi16(x)
# else
/* The "proper" rounding, plain C, a bit slow. */
# define REAL_TO_SHORT_ACCURATE(x) (short)((x)>0.0?(x)+0.5:(x)-0.5)
# endif
#endif
/* Now define the normal rounding. */
# ifdef ACCURATE_ROUNDING
# define REAL_TO_SHORT(x) REAL_TO_SHORT_ACCURATE(x)
# else
/* Non-accurate rounding... simple truncation. Fastest, most LSB errors. */
# define REAL_TO_SHORT(x) (short)(x)
# endif
#endif /* REAL_TO_SHORT */
/* We should add dithering for S32, too? */
#ifndef REAL_TO_S32
# ifdef ACCURATE_ROUNDING
# define REAL_TO_S32(x) (int32_t)((x)>0.0?(x)+0.5:(x)-0.5)
# else
# define REAL_TO_S32(x) (int32_t)(x)
# endif
#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_PLUS_S32
# define REAL_PLUS_S32 2147483647.0
#endif
#ifndef REAL_MINUS_S32
# define REAL_MINUS_S32 -2147483648.0
#endif
/* The actual storage of a decoded sample is separated in the following macros.
We can handle different types, we could also handle dithering here. */
#ifdef NEWOLD_WRITE_SAMPLE
/* This is the old new mpg123 WRITE_SAMPLE, fixed for newer GCC by MPlayer folks.
Makes a huge difference on old machines. */
#if WORDS_BIGENDIAN
#define MANTISSA_OFFSET 1
#else
#define MANTISSA_OFFSET 0
#endif
#define WRITE_SHORT_SAMPLE(samples,sum,clip) { \
union { double dtemp; int itemp[2]; } u; int v; \
u.dtemp = ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0)) + (sum);\
v = u.itemp[MANTISSA_OFFSET] - 0x80000000; \
if( v > 32767) { *(samples) = 0x7fff; (clip)++; } \
else if( v < -32768) { *(samples) = -0x8000; (clip)++; } \
else { *(samples) = v; } \
}
#else
/* Macro to produce a short (signed 16bit) output sample from internal representation,
which may be float, double or indeed some integer for fixed point handling. */
#define WRITE_SHORT_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); }
#endif
/* Same as above, but always using accurate rounding. Would we want softer clipping here, too? */
#define WRITE_SHORT_SAMPLE_ACCURATE(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_ACCURATE(sum); }
/*
32bit signed
We do clipping with the same old borders... but different conversion.
We see here that we need extra work for non-16bit output... we optimized for 16bit.
-0x7fffffff-1 is the minimum 32 bit signed integer value expressed so that MSVC
does not give a compile time warning.
*/
#define WRITE_S32_SAMPLE(samples,sum,clip) \
{ \
real tmpsum = REAL_MUL((sum),S32_RESCALE); \
if( tmpsum > REAL_PLUS_S32 ){ *(samples) = 0x7fffffff; (clip)++; } \
else if( tmpsum < REAL_MINUS_S32 ) { *(samples) = -0x7fffffff-1; (clip)++; } \
else { *(samples) = REAL_TO_S32(tmpsum); } \
}
/* Produce an 8bit sample, via 16bit intermediate. */
#define WRITE_8BIT_SAMPLE(samples,sum,clip) \
{ \
int16_t write_8bit_tmp; \
if( (sum) > REAL_PLUS_32767) { write_8bit_tmp = 0x7fff; (clip)++; } \
else if( (sum) < REAL_MINUS_32768) { write_8bit_tmp = -0x8000; (clip)++; } \
else { write_8bit_tmp = REAL_TO_SHORT(sum); } \
*(samples) = fr->conv16to8[write_8bit_tmp>>AUSHIFT]; \
}
#ifndef REAL_IS_FIXED
#define WRITE_REAL_SAMPLE(samples,sum,clip) *(samples) = ((real)1./SHORT_SCALE)*(sum)
#endif
#endif

View File

@ -0,0 +1,202 @@
/*
stringbuf: mimicking a bit of C++ to more safely handle strings
copyright 2006-17 by the mpg123 project
- free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
*/
#include "mpg123lib_intern.h"
#include "config.h"
#include "mpg123.h"
#include "compat.h"
#include <string.h>
#include "debug.h"
void attribute_align_arg mpg123_init_string(mpg123_string* sb)
{
/* Handing in NULL here is a fatal mistake and rightfully so. */
sb->p = NULL;
sb->size = 0;
sb->fill = 0;
}
void attribute_align_arg mpg123_free_string(mpg123_string* sb)
{
if(!sb)
return;
if(sb->p != NULL) free(sb->p);
mpg123_init_string(sb);
}
int attribute_align_arg mpg123_grow_string(mpg123_string* sb, size_t new)
{
if(!sb)
return 0;
if(sb->size < new) return mpg123_resize_string(sb, new);
else return 1;
}
int attribute_align_arg mpg123_resize_string(mpg123_string* sb, size_t new)
{
if(!sb)
return 0;
debug3("resizing string pointer %p from %lu to %lu", (void*) sb->p, (unsigned long)sb->size, (unsigned long)new);
if(new == 0)
{
if(sb->size && sb->p != NULL) free(sb->p);
mpg123_init_string(sb);
return 1;
}
if(sb->size != new)
{
char* t;
debug("really!");
t = (char*) safe_realloc(sb->p, new*sizeof(char));
debug1("safe_realloc returned %p", (void*) t);
if(t != NULL)
{
sb->p = t;
sb->size = new;
return 1;
}
else return 0;
}
else return 1; /* success */
}
int attribute_align_arg mpg123_copy_string(mpg123_string* from, mpg123_string* to)
{
size_t fill;
char *text;
debug2("called copy_string with %p -> %p", (void*)from, (void*)to);
if(to == NULL)
return 0;
if(from == NULL)
{
fill = 0;
text = NULL;
}
else
{
fill = from->fill;
text = from->p;
}
if(mpg123_resize_string(to, fill))
{
if(fill) /* Avoid memcpy(NULL, NULL, 0) */
memcpy(to->p, text, fill);
to->fill = fill;
return 1;
}
else return 0;
}
int attribute_align_arg mpg123_add_string(mpg123_string* sb, const char* stuff)
{
debug1("adding %s", stuff);
return mpg123_add_substring(sb, stuff, 0, stuff ? strlen(stuff) : 0);
}
int attribute_align_arg mpg123_add_substring(mpg123_string *sb, const char *stuff, size_t from, size_t count)
{
debug("adding a substring");
if(!sb || !stuff)
return 0;
if(sb->fill) /* includes zero byte... */
{
if( (SIZE_MAX - sb->fill >= count) /* Avoid overflow. */
&& (sb->size >= sb->fill+count || mpg123_grow_string(sb, sb->fill+count)) )
{
memcpy(sb->p+sb->fill-1, stuff+from, count);
sb->fill += count;
sb->p[sb->fill-1] = 0; /* Terminate! */
}
else return 0;
}
else
{
if( count < SIZE_MAX && mpg123_grow_string(sb, count+1) )
{
memcpy(sb->p, stuff+from, count);
sb->fill = count+1;
sb->p[sb->fill-1] = 0; /* Terminate! */
}
else return 0;
}
return 1;
}
int attribute_align_arg mpg123_set_substring(mpg123_string* sb, const char* stuff, size_t from, size_t count)
{
if(!sb)
return 0;
sb->fill = 0;
return mpg123_add_substring(sb, stuff, from, count);
}
int attribute_align_arg mpg123_set_string(mpg123_string* sb, const char* stuff)
{
if(!sb)
return 0;
sb->fill = 0;
return mpg123_add_string(sb, stuff);
}
size_t attribute_align_arg mpg123_strlen(mpg123_string *sb, int utf8)
{
size_t i;
size_t bytelen;
/* Notions of empty string. If there's only a single character, it has to be the trailing zero, and if the first is the trailing zero anyway, we got empty. */
if(!sb || sb->fill < 2 || sb->p[0] == 0) return 0;
/* Find the first non-null character from the back.
We already established that the first character is non-null
That at fill-2 has to be null, though. */
for(i=sb->fill-2; i>0; --i)
if(sb->p[i] != 0) break;
/* For simple byte strings, we are done now. */
bytelen = i+1;
if(!utf8) return bytelen;
else
{
/* Work out the actual count of UTF8 bytes.
This employs no particular encoding error checking. */
size_t len = 0;
for(i=0; i<bytelen; ++i)
{
/* Every byte that is not a continuation byte ( 0xc0 == 10xx xxxx ) stands for a character. */
if((sb->p[i] & 0xc0) != 0x80) len++;
}
return len;
}
}
int attribute_align_arg mpg123_chomp_string(mpg123_string *sb)
{
ssize_t i;
if(!sb || !sb->fill) return 0;
/* Ensure that it is zero-terminated. */
sb->p[sb->fill-1] = 0;
for(i=sb->fill-2; i>=0; --i)
{
char *c = sb->p+i;
/* Stop at the first proper character. */
if(*c && *c != '\r' && *c != '\n') break;
else *c = 0;
}
/* initial fill at least 1, so i at least -1,
+2 means nothing happened for fill=1 .
With i=0, we got one non-null character, fill shall be 2
to accomodate the trailing zero. */
sb->fill = (size_t)i+2;
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,196 @@
/*
synth.h: generic synth functions
copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp, generalized by Thomas Orgis
This header is used multiple times to create different variants of these functions.
See decode.c and friends.
Hint: BLOCK, MONO_NAME, MONO2STEREO_NAME, SYNTH_NAME and SAMPLE_T as well as WRITE_SAMPLE do vary.
Thomas looked closely at the decode_1to1, decode_2to1 and decode_4to1 contents, seeing that they are too similar to be separate files.
This is what resulted...
Basically, you need one set of these functions for each output sample type.
That currently means signed short, 8bit or float/double; though unsigned short may come, too.
Define NO_AUTOINCREMENT i386 code that shall not rely on autoincrement.
Actual benefit of this has to be examined; may apply to specific (old) compilers, only.
*/
/* Main synth function, uses the plain dct64 or dct64_i386. */
int SYNTH_NAME(real *bandPtr, int channel, mpg123_handle *fr, int final)
{
#ifndef NO_AUTOINCREMENT
#define BACKPEDAL 0x10 /* We use autoincrement and thus need this re-adjustment for window/b0. */
#define MY_DCT64 dct64
#else
#define BACKPEDAL 0x00 /* i386 code does not need that. */
#define MY_DCT64 dct64_i386
#endif
static const int step = 2;
SAMPLE_T *samples = (SAMPLE_T *) (fr->buffer.data + fr->buffer.fill);
real *b0, **buf; /* (*buf)[0x110]; */
int clip = 0;
int bo1;
#ifndef NO_EQUALIZER
if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
#endif
if(!channel)
{
fr->bo--;
fr->bo &= 0xf;
buf = fr->real_buffs[0];
}
else
{
#ifdef USE_DITHER
/* We always go forward 32 dither points (and back again for the second channel),
(re)sampling the noise the same way as the original signal. */
fr->ditherindex -= 32;
#endif
samples++;
buf = fr->real_buffs[1];
}
#ifdef USE_DITHER
/* We check only once for the overflow of dither index here ...
this wraps differently than the original i586 dither code, in theory (but when DITHERSIZE % BLOCK/2 == 0 it's the same). */
if(DITHERSIZE-fr->ditherindex < 32) fr->ditherindex = 0;
/* And we define a macro for the dither action... */
#define ADD_DITHER(fr,sum) sum+=fr->dithernoise[fr->ditherindex]; fr->ditherindex += 64/BLOCK;
#else
#define ADD_DITHER(fr,sum)
#endif
if(fr->bo & 0x1)
{
b0 = buf[0];
bo1 = fr->bo;
MY_DCT64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr);
}
else
{
b0 = buf[1];
bo1 = fr->bo+1;
MY_DCT64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr);
}
{
register int j;
real *window = fr->decwin + 16 - bo1;
for(j=(BLOCK/4); j; j--, b0+=0x400/BLOCK-BACKPEDAL, window+=0x800/BLOCK-BACKPEDAL, samples+=step)
{
real sum;
#ifndef NO_AUTOINCREMENT
sum = REAL_MUL_SYNTH(*window++, *b0++);
sum -= REAL_MUL_SYNTH(*window++, *b0++);
sum += REAL_MUL_SYNTH(*window++, *b0++);
sum -= REAL_MUL_SYNTH(*window++, *b0++);
sum += REAL_MUL_SYNTH(*window++, *b0++);
sum -= REAL_MUL_SYNTH(*window++, *b0++);
sum += REAL_MUL_SYNTH(*window++, *b0++);
sum -= REAL_MUL_SYNTH(*window++, *b0++);
sum += REAL_MUL_SYNTH(*window++, *b0++);
sum -= REAL_MUL_SYNTH(*window++, *b0++);
sum += REAL_MUL_SYNTH(*window++, *b0++);
sum -= REAL_MUL_SYNTH(*window++, *b0++);
sum += REAL_MUL_SYNTH(*window++, *b0++);
sum -= REAL_MUL_SYNTH(*window++, *b0++);
sum += REAL_MUL_SYNTH(*window++, *b0++);
sum -= REAL_MUL_SYNTH(*window++, *b0++);
#else
sum = REAL_MUL_SYNTH(window[0x0], b0[0x0]);
sum -= REAL_MUL_SYNTH(window[0x1], b0[0x1]);
sum += REAL_MUL_SYNTH(window[0x2], b0[0x2]);
sum -= REAL_MUL_SYNTH(window[0x3], b0[0x3]);
sum += REAL_MUL_SYNTH(window[0x4], b0[0x4]);
sum -= REAL_MUL_SYNTH(window[0x5], b0[0x5]);
sum += REAL_MUL_SYNTH(window[0x6], b0[0x6]);
sum -= REAL_MUL_SYNTH(window[0x7], b0[0x7]);
sum += REAL_MUL_SYNTH(window[0x8], b0[0x8]);
sum -= REAL_MUL_SYNTH(window[0x9], b0[0x9]);
sum += REAL_MUL_SYNTH(window[0xA], b0[0xA]);
sum -= REAL_MUL_SYNTH(window[0xB], b0[0xB]);
sum += REAL_MUL_SYNTH(window[0xC], b0[0xC]);
sum -= REAL_MUL_SYNTH(window[0xD], b0[0xD]);
sum += REAL_MUL_SYNTH(window[0xE], b0[0xE]);
sum -= REAL_MUL_SYNTH(window[0xF], b0[0xF]);
#endif
ADD_DITHER(fr,sum)
WRITE_SAMPLE(samples,sum,clip);
}
{
real sum;
sum = REAL_MUL_SYNTH(window[0x0], b0[0x0]);
sum += REAL_MUL_SYNTH(window[0x2], b0[0x2]);
sum += REAL_MUL_SYNTH(window[0x4], b0[0x4]);
sum += REAL_MUL_SYNTH(window[0x6], b0[0x6]);
sum += REAL_MUL_SYNTH(window[0x8], b0[0x8]);
sum += REAL_MUL_SYNTH(window[0xA], b0[0xA]);
sum += REAL_MUL_SYNTH(window[0xC], b0[0xC]);
sum += REAL_MUL_SYNTH(window[0xE], b0[0xE]);
ADD_DITHER(fr,sum)
WRITE_SAMPLE(samples,sum,clip);
samples += step;
b0-=0x400/BLOCK;
window-=0x800/BLOCK;
}
window += bo1<<1;
for(j=(BLOCK/4)-1; j; j--, b0-=0x400/BLOCK+BACKPEDAL, window-=0x800/BLOCK-BACKPEDAL, samples+=step)
{
real sum;
#ifndef NO_AUTOINCREMENT
sum = -REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
sum -= REAL_MUL_SYNTH(*(--window), *b0++);
#else
sum = -REAL_MUL_SYNTH(window[-0x1], b0[0x0]);
sum -= REAL_MUL_SYNTH(window[-0x2], b0[0x1]);
sum -= REAL_MUL_SYNTH(window[-0x3], b0[0x2]);
sum -= REAL_MUL_SYNTH(window[-0x4], b0[0x3]);
sum -= REAL_MUL_SYNTH(window[-0x5], b0[0x4]);
sum -= REAL_MUL_SYNTH(window[-0x6], b0[0x5]);
sum -= REAL_MUL_SYNTH(window[-0x7], b0[0x6]);
sum -= REAL_MUL_SYNTH(window[-0x8], b0[0x7]);
sum -= REAL_MUL_SYNTH(window[-0x9], b0[0x8]);
sum -= REAL_MUL_SYNTH(window[-0xA], b0[0x9]);
sum -= REAL_MUL_SYNTH(window[-0xB], b0[0xA]);
sum -= REAL_MUL_SYNTH(window[-0xC], b0[0xB]);
sum -= REAL_MUL_SYNTH(window[-0xD], b0[0xC]);
sum -= REAL_MUL_SYNTH(window[-0xE], b0[0xD]);
sum -= REAL_MUL_SYNTH(window[-0xF], b0[0xE]);
sum -= REAL_MUL_SYNTH(window[-0x0], b0[0xF]); /* Is that right? 0x0? Just wondering... */
#endif
ADD_DITHER(fr,sum)
WRITE_SAMPLE(samples,sum,clip);
}
}
if(final) fr->buffer.fill += BLOCK*sizeof(SAMPLE_T);
return clip;
#undef ADD_DITHER
#undef BACKPEDAL
#undef MY_DCT64
}

View File

@ -0,0 +1,345 @@
/*
decode_3dnow.s - 3DNow! optimized synth_1to1()
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Syuuhei Kashiyama
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.
*/
#include "mangle.h"
#ifdef ACCURATE_ROUNDING
#ifndef __APPLE__
.section .rodata
#else
.data
#endif
ALIGN8
max_s16:
.long 1191181824 /* 32767.0 */
.long 1191181824
min_s16:
.long -956301312 /* -32768.0 */
.long -956301312
ftoi_magic:
.long 1262485504 /* 2^23 + 2^22 */
.long 1262485504
#endif
.text
ALIGN16
.globl ASM_NAME(synth_1to1_3dnow_asm)
/* int synth_1to1_3dnow_asm(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int *bo, real *decwin); */
ASM_NAME(synth_1to1_3dnow_asm):
subl $24,%esp
pushl %ebp
pushl %edi
xorl %ebp,%ebp
pushl %esi
pushl %ebx
/* stack old: 0=ebx 4=esi 8=edi 12=ebp 16,20,24,28,32,36=local 40=back 44=bandptr 48=channel 52=out 56=pnt */
/* stack new: 0=ebx 4=esi 8=edi 12=ebp 16,20,24,28,32,36=local 40=back 44=bandptr 48=channel 52=out 56=buffs 60=bo 64=decwin */
#define OUT 52(%esp)
#define CHANNEL 48(%esp)
#define BANDPTR 44(%esp)
#define BUFFS 56(%esp)
#define BO 60(%esp)
#define DECWIN 64(%esp)
#define LOCAL0 16(%esp)
#define LOCAL1 20(%esp)
#define EBXSAVE 24(%esp)
#define LOCAL5 36(%esp)
#ifdef ACCURATE_ROUNDING
#undef _EBX_
#define _EBX_ %eax
GET_GOT
/* FIXME */
#if PIC
movl _EBX_, EBXSAVE
#endif
#endif
movl OUT,%esi
movl %esi,LOCAL0 /* save buffer start (samples pointer) to another local var */
movl CHANNEL,%ebx
movl BO,%esi /* bo address */
movl (%esi),%edx /* bo value */
femms
testl %ebx,%ebx
jne .L26
/* if(!channel) */
decl %edx /* --bo */
andl $15,%edx
movl %edx,(%esi) /* save bo */
movl BUFFS,%ecx
jmp .L27
.L26: /* if(channel) */
addl $2,LOCAL0 /* samples++ */
movl BUFFS,%ecx
addl $2176,%ecx
.L27:
/* edx (and it's lower end) still holds bo value */
testb $1,%dl /* bo & 0x1 */
je .L28
movl %edx,LOCAL5
movl %ecx,%ebx
movl BANDPTR,%esi
movl %edx,%edi
pushl %esi
sall $2,%edi
movl %ebx,%eax
movl %edi,24(%esp) /* LOCAL1, actually */
addl %edi,%eax
pushl %eax
movl %edx,%eax
incl %eax
andl $15,%eax
leal 1088(,%eax,4),%eax
addl %ebx,%eax
pushl %eax
call FUNC(dct64_3dnow)
addl $12,%esp
jmp .L29
.L28:
leal 1(%edx),%esi
movl BANDPTR,%edi
movl %esi,LOCAL5
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 FUNC(dct64_3dnow)
addl $12,%esp
movl %esi,LOCAL1
.L29:
movl DECWIN,%edx
addl $64,%edx
movl $16,%ecx
subl LOCAL1,%edx
movl LOCAL0,%edi
pcmpeqb %mm7,%mm7
pslld $31,%mm7
movq (%edx),%mm0
movq (%ebx),%mm1
ALIGN32
.L33:
#if defined(ACCURATE_ROUNDING) && defined(PIC)
movl EBXSAVE, _EBX_
#endif
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
#ifdef ACCURATE_ROUNDING
pfmin LOCAL_VAR(max_s16),%mm2
pfmax LOCAL_VAR(min_s16),%mm2
pfadd LOCAL_VAR(ftoi_magic),%mm2
#else
pf2id %mm2,%mm2
packssdw %mm2,%mm2
#endif
movd %mm2,%eax
movw %ax,0(%edi)
addl $4,%edi
decl %ecx
jnz .L33
#if defined(ACCURATE_ROUNDING) && defined(PIC)
movl EBXSAVE, _EBX_
#endif
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
#ifdef ACCURATE_ROUNDING
pfmin LOCAL_VAR(max_s16),%mm0
pfmax LOCAL_VAR(min_s16),%mm0
pfadd LOCAL_VAR(ftoi_magic),%mm0
#else
pf2id %mm0,%mm0
packssdw %mm0,%mm0
#endif
movd %mm0,%eax
movw %ax,0(%edi)
incl %ebp
movl LOCAL5,%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
ALIGN32
.L46:
#if defined(ACCURATE_ROUNDING) && defined(PIC)
movl EBXSAVE, _EBX_
#endif
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
pxor %mm7,%mm3
#ifdef ACCURATE_ROUNDING
pfmin LOCAL_VAR(max_s16),%mm3
pfmax LOCAL_VAR(min_s16),%mm3
pfadd LOCAL_VAR(ftoi_magic),%mm3
#else
pf2id %mm3,%mm3
packssdw %mm3,%mm3
#endif
movd %mm3,%eax
movw %ax,(%edi)
addl $4,%edi
decl %ecx
jnz .L46
femms
movl %ebp,%eax
popl %ebx
popl %esi
popl %edi
popl %ebp
addl $24,%esp
ret
#if defined(PIC) && defined(__APPLE__)
.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
L_dct64_3dnow:
.indirect_symbol ASM_NAME(dct64_3dnow)
hlt ; hlt ; hlt ; hlt ; hlt
#endif
NONEXEC_STACK

View File

@ -0,0 +1,13 @@
#include "mangle.h"
#define MPL_DCT64 FUNC(dct64_3dnowext)
#define SYNTH_NAME ASM_NAME(synth_1to1_3dnowext_asm)
#include "synth_sse3d.h"
#if defined(PIC) && defined(__APPLE__)
.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
L_dct64_3dnowext:
.indirect_symbol ASM_NAME(dct64_3dnowext)
hlt ; hlt ; hlt ; hlt ; hlt
#endif
NONEXEC_STACK

Some files were not shown because too many files have changed in this diff Show More