dslinux/user/bitchx/dll/amp Makefile.in amp.h audio.c audio.h audioIO.c audioIO.h audioIO_Linux.c buffer.c config.h.in getbits.c getbits.h getdata.c getdata.h huffman.c huffman.h layer2.c layer2.h layer3.c layer3.h misc2.c misc2.h position.c position.h proto.h transform.c transform.h util.c

stsp stsp at user.in-berlin.de
Sun Jul 2 15:18:33 CEST 2006


Update of /cvsroot/dslinux/dslinux/user/bitchx/dll/amp
In directory antilope:/tmp/cvs-serv9280/dll/amp

Added Files:
	Makefile.in amp.h audio.c audio.h audioIO.c audioIO.h 
	audioIO_Linux.c buffer.c config.h.in getbits.c getbits.h 
	getdata.c getdata.h huffman.c huffman.h layer2.c layer2.h 
	layer3.c layer3.h misc2.c misc2.h position.c position.h 
	proto.h transform.c transform.h util.c 
Log Message:
Adding pristine copy of BitchX so I can branch from it.


--- NEW FILE: getdata.c ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/
 
/* getdata.c  scalefactor & huffman data extraction
 *
 * Created by: tomislav uzelac  Apr 1996
 * Last modified by: tomislav uzelac  Feb 27 1997
 */
#include "amp.h"
#include "audio.h"
#include "getbits.h"
#include "huffman.h"

#define		GETDATA
#include "getdata.h"

/* layer3 scalefactor decoding. should we check for the number
 * of bits read, just in case?
 */
int decode_scalefactors(struct SIDE_INFO *info,struct AUDIO_HEADER *header,int gr,int ch)
{
int sfb,window;
int slen1,slen2;
int i1,i2,i=0;
int j,k;
	if (header->ID==1) {
	/* this is MPEG-1 scalefactors format, quite different than 
	 * the MPEG-2 format. 
	 */
		slen1=t_slen1[info->scalefac_compress[gr][ch]];
		slen2=t_slen2[info->scalefac_compress[gr][ch]];
		i1=3*slen1;
		i2=3*slen2;
		
		if (info->window_switching_flag[gr][ch] && info->block_type[gr][ch]==2) 
		{
			if (info->mixed_block_flag[gr][ch]) 
			{
				for (sfb=0;sfb<8;sfb++) 
				{
					scalefac_l[gr][ch][sfb]=getbits(slen1);	
					i+=slen1;
				}
				for (sfb=3;sfb<6;sfb++) 
				{
					for (window=0;window<3;window++)
						scalefac_s[gr][ch][sfb][window]=getbits(slen1);
					i+=i1;
				}
				for (;sfb<12;sfb++) 
				{
					for (window=0;window<3;window++)
						scalefac_s[gr][ch][sfb][window]=getbits(slen2);
					i+=i2;
				}
			} 
			else 
			{ /* !mixed_block_flag */
				for (sfb=0;sfb<6;sfb++) 
				{
					for (window=0;window<3;window++)
						scalefac_s[gr][ch][sfb][window]=getbits(slen1);
					i+=i1;
				}	
				for (;sfb<12;sfb++) 
				{
					for (window=0;window<3;window++)
						scalefac_s[gr][ch][sfb][window]=getbits(slen2);
					i+=i2;
				}	
			}	
			for (window=0;window<3;window++) 
				scalefac_s[gr][ch][12][window]=0;
		} 
		else 
		{ /* block_type!=2 */
			if ( !info->scfsi[ch][0] || !gr )
			{
				for (sfb=0;sfb<6;sfb++) 
				{
					scalefac_l[gr][ch][sfb]=getbits(slen1);
					i+=slen1;
				}	
			}
			else for (sfb=0;sfb<6;sfb++) 
			{
				scalefac_l[1][ch][sfb]=scalefac_l[0][ch][sfb];
			}	
			if ( !info->scfsi[ch][1] || !gr )
			{
				for (sfb=6;sfb<11;sfb++) 
				{
					scalefac_l[gr][ch][sfb]=getbits(slen1);
					i+=slen1;
				}
			}
			else for (sfb=6;sfb<11;sfb++) 
			{
				scalefac_l[1][ch][sfb]=scalefac_l[0][ch][sfb];				
			}
			if ( !info->scfsi[ch][2] || !gr )
			{
				for (sfb=11;sfb<16;sfb++) 
				{
					scalefac_l[gr][ch][sfb]=getbits(slen2);
					i+=slen2;
				}
			}
			else for (sfb=11;sfb<16;sfb++) 
			{
				scalefac_l[1][ch][sfb]=scalefac_l[0][ch][sfb];				
			}	
			if ( !info->scfsi[ch][3] || !gr )
			{
				for (sfb=16;sfb<21;sfb++) 
				{
					scalefac_l[gr][ch][sfb]=getbits(slen2);
					i+=slen2;
				}	
			}
			else for (sfb=16;sfb<21;sfb++) 
			{
				scalefac_l[1][ch][sfb]=scalefac_l[0][ch][sfb];
			}
			scalefac_l[gr][ch][21]=0;
		}
	} 
	else 
	{ /* ID==0 */
		int index=0,index2,spooky_index;
		int slen[5],nr_of_sfb[5]; /* actually, there's four of each, not five, labelled 1 through 4, but
					   * what's a word of storage compared to one's sanity. so [0] is irellevant.
					   */

		/* ok, so we got 3 indexes. 
		 * spooky_index - indicates whether we use the normal set of slen eqs and nr_of_sfb tables
		 *                or the one for the right channel of intensity stereo coded frame
		 * index        - corresponds to the value of scalefac_compress, as listed in the standard
		 * index2	- 0 for long blocks, 1 for short wo/ mixed_block_flag, 2 for short with it
		 */
		if ( (header->mode_extension==1 || header->mode_extension==3) && ch==1) 
		{ /* right ch... */
			int int_scalefac_compress=info->scalefac_compress[0][ch]>>1;
			intensity_scale=info->scalefac_compress[0][1]&1;
			spooky_index=1;
			if (int_scalefac_compress < 180) 
			{
				slen[1]=int_scalefac_compress/36;
				slen[2]=(int_scalefac_compress%36)/6;
				slen[3]=(int_scalefac_compress%36)%6;
				slen[4]=0;
				info->preflag[0][ch]=0;
				index=0;
			}
			if ( 180 <= int_scalefac_compress && int_scalefac_compress < 244) 
			{
				slen[1]=((int_scalefac_compress-180)%64)>>4;
				slen[2]=((int_scalefac_compress-180)%16)>>2;
				slen[3]=(int_scalefac_compress-180)%4;
				slen[4]=0;
				info->preflag[0][ch]=0;
				index=1;
			}
			if ( 244 <= int_scalefac_compress && int_scalefac_compress < 255) 
			{
				slen[1]=(int_scalefac_compress-244)/3;
				slen[2]=(int_scalefac_compress-244)%3;
				slen[3]=0;
				slen[4]=0;
				info->preflag[0][ch]=0;
				index=2;
			}
		} 
		else 
		{ /* the usual */
			spooky_index=0;
			if (info->scalefac_compress[0][ch] < 400) 
			{
				slen[1]=(info->scalefac_compress[0][ch]>>4)/5;
				slen[2]=(info->scalefac_compress[0][ch]>>4)%5;
				slen[3]=(info->scalefac_compress[0][ch]%16)>>2;
				slen[4]=info->scalefac_compress[0][ch]%4;
				info->preflag[0][ch]=0;
				index=0;
			}
			if (info->scalefac_compress[0][ch] >= 400 && info->scalefac_compress[0][ch] < 500) 
			{
				slen[1]=((info->scalefac_compress[0][ch]-400)>>2)/5;
				slen[2]=((info->scalefac_compress[0][ch]-400)>>2)%5;
				slen[3]=(info->scalefac_compress[0][ch]-400)%4;
				slen[4]=0;
				info->preflag[0][ch]=0;
				index=1;
			} 
			if (info->scalefac_compress[0][ch] >= 500 && info->scalefac_compress[0][ch] < 512) 
			{
				slen[1]=(info->scalefac_compress[0][ch]-500)/3;
				slen[2]=(info->scalefac_compress[0][ch]-500)%3;
				slen[3]=0;
				slen[4]=0;
				info->preflag[0][ch]=1;
				index=2;
			}
		}

		if (info->window_switching_flag[0][ch] && info->block_type[0][ch]==2)
		{
			if (info->mixed_block_flag[0][ch]) 
				index2=2;
			else 
				index2=1;
		}
		else 
			index2=0;

		for (j=1;j<=4;j++) nr_of_sfb[j]=spooky_table[spooky_index][index][index2][j-1];

	/* now we'll do some actual scalefactor extraction, and a little more.
	 * for each scalefactor band we'll set the value of is_max to indicate
	 * illegal is_pos, since with MPEG2 it's not 'hardcoded' to 7.
	 */
		if (!info->window_switching_flag[0][ch] || (info->window_switching_flag[0][ch] && info->block_type[0][ch]!=2)) 
		{
			sfb=0;
			for (j=1;j<=4;j++) 
				for (k=0;k<nr_of_sfb[j];k++) 
				{
					scalefac_l[0][ch][sfb]=getbits(slen[j]);
					i+=slen[j];
					if (ch) is_max[sfb]=(1<<slen[j])-1;
					sfb++;
				}
		} 
		else if (info->block_type[0][ch]==2)
		{
			if (!info->mixed_block_flag[0][ch]) 
			{
				sfb=0;
				for (j=1;j<=4;j++)
					for (k=0;k<nr_of_sfb[j];k+=3) 
					{
						/* we assume here that nr_of_sfb is divisible by 3. it is.
						 */
						scalefac_s[0][ch][sfb][0]=getbits(slen[j]);
						scalefac_s[0][ch][sfb][1]=getbits(slen[j]);
						scalefac_s[0][ch][sfb][2]=getbits(slen[j]);
						i+=3*slen[j];
						if (ch) is_max[sfb+6]=(1<<slen[j])-1;
						sfb++;
					}
			} 
			else 
			{
				/* what we do here is:
				 * 1. assume that for every fs, the two lowest subbands are equal to the
				 *    six lowest scalefactor bands for long blocks/MPEG2. they are.
				 * 2. assume that for every fs, the two lowest subbands are equal to the
				 *    three lowest scalefactor bands for short blocks. they are.
				 */
				sfb=0;
				for (k=0;k<6;k++) 
				{
					scalefac_l[0][ch][sfb]=getbits(slen[1]);
					i+=slen[j];
					if (ch) is_max[sfb]=(1<<slen[1])-1;
					sfb++;
				}
				nr_of_sfb[1]-=6;
				sfb=3;
				for (j=1;j<=4;j++)
					for (k=0;k<nr_of_sfb[j];k+=3) 
					{
						scalefac_s[0][ch][sfb][0]=getbits(slen[j]);
						scalefac_s[0][ch][sfb][1]=getbits(slen[j]);
						scalefac_s[0][ch][sfb][2]=getbits(slen[j]);
						i+=3*slen[j];
						if (ch) is_max[sfb+6]=(1<<slen[j])-1;
						sfb++;
					}
			} 
		}
	}
return i;
}

--- NEW FILE: Makefile.in ---
# Makefile  - amp  audio mpeg player v0.7
# tomislav uzelac  1996,1997

SHELL = @SHELL@

srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
topdir = @topdir@
prefix = @prefix@
exec_prefix = @exec_prefix@

bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = @oldincludedir@

local_dir = $(HOME)

# Where the BitchX binary will be installed.
# "make install" will compile and install the program.
INSTALL_IRC = @INSTALL_IRC@

# Where the BitchX library will be. Generally this is the place that
# you put the scripts, help pages and translation tables. It is
# very important that you set this correctly.
IRCLIB = @IRCLIB@

CC = @CC@
DEFS = @INCLUDES@
LIBS = @LIBS@

# Tcl library.
TCL_LIBS = @TCL_LIBS@

# These are for Tcl support.
TCL_OBJS = @TCL_OBJS@
# You don't have the following, so you'll want to leave this blank.
TCL_SRCS = @TCL_SRCS@

# Set this to -g if you want to be able to debug the client, otherwise
# use -O to have the compiler do some optimization instead.
CFLAGS = @CFLAGS@

# Set this to -s if you want the binary to be stripped.
LDFLAGS = @LDFLAGS@

# These are for the cd device player.
CD_SRCS = @CD_SRCS@
CD_OBJS = @CD_OBJS@

# This is the executable suffix for the target operating system.
EXEEXT = @EXEEXT@

# Extra files.
DEFAULT_CTOOLZ_DIR = @DEFAULT_CTOOLZ_DIR@
DEFAULT_MSGLOGFILE = @DEFAULT_MSGLOGFILE@
DEFAULT_BITCHX_HELP_FILE = @DEFAULT_BITCHX_HELP_FILE@
DEFAULT_SCRIPT_HELP_FILE = @DEFAULT_SCRIPT_HELP_FILE@
DEFAULT_BITCHX_KICK_FILE = @DEFAULT_BITCHX_KICK_FILE@
DEFAULT_BITCHX_QUIT_FILE = @DEFAULT_BITCHX_QUIT_FILE@
DEFAULT_BITCHX_IRCNAME_FILE = @DEFAULT_BITCHX_IRCNAME_FILE@

# Full path of the directory for BitchX help files.
HELPDIR = @HELPDIR@

# Full path of the directory for the BitchX scripts.
INSTALL_SCRIPT = @INSTALL_SCRIPT@

# Default setting for IRCPATH where BitchX will look for
# its script files if the environment variable is undefined.
# Usually, this should contain the same path as used for INSTALL_SCRIPT in
# the Makefile, but it can contain multiple path elements
# separated by colons. The path MUST lead to an existing directory,
# because the 'global' script is expected to be found there.
IRCPATH = @IRCPATH@

# Path for TRANSLATION variable.
TRANSLATION_PATH = @TRANSLATION_PATH@

# This command will be used to install the BitchX help files. If you don't
# want to install them, replace with the following:
# INSTALL_HELP_CMD = @echo The help files have not been installed.
INSTALL_HELP_CMD = @INSTALL_HELP_CMD@

# This is where the optional plugins will be copied to.
PLUGINDIR = @PLUGINDIR@

# Plugin flags.
SHLIB_LD = @SHLIB_LD@
SHLIB_CFLAGS = @SHLIB_CFLAGS@
SHLIB_SUFFIX = @SHLIB_SUFFIX@

# This command will be used to install the BitchX files on Win32/OS2EMX
# systems.
WINNT_INSTALL = @WINNT_INSTALL@

# This program allows you to use screen/xterm's to put new BitchX windows
# on new screen/xterm windows.
INSTALL_WSERV = @INSTALL_WSERV@

# This program allows you to screen BitchX and reattach to it later.
INSTALL_SCRBX = @INSTALL_SCRBX@

# Set gzip and bzip2 options.
GZIP_ENV = @GZIP_ENV@
BZIP2 = @BZIP2@

# Standard programs.
RM = @RM@
LN = @LN_S@
CP = @CP@
MV = @MV@

INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@

VERSION = @VERSION@
_VERSION_ = @_VERSION_@

MAKE_BIN = @MAKE@
MAKE = $(MAKE_BIN) $(MFLAGS)
MFLAGS = \
	'local_dir=$(HOME)'			\
	'INSTALL_IRC=$(INSTALL_IRC)'		\
	'IRCLIB=$(IRCLIB)'			\
	'CC=$(CC)'				\
	'CFLAGS=$(CFLAGS)'			\
	'HELPDIR=$(HELPDIR)'			\
        'INSTALL_WSERV=$(INSTALL_WSERV)'	\
	'IRCPATH=$(IRCPATH)'			\
	'TRANSLATION_PATH=$(TRANSLATION_PATH)'	\
	'LDFLAGS=$(LDFLAGS)'			\
	'LIBS=$(LIBS)'				\
	'LN=$(LN)'				\
	'RM=$(RM)'				\
	'TCL_SRCS=$(TCL_SRCS)'			\
	'TCL_OBJS=$(TCL_OBJS)'			\
	'CD_PLAY=$(CD_PLAY)'			\
	'CD_SRCS=$(CD_SRCS)'			\
	'CD_OBJS=$(CD_OBJS)'			\
	'TCL_LIBS=$(TCL_LIBS)'			\
	'PLUGINDIR=$(PLUGINDIR)'		\
	'_VERSION_=$(_VERSION_)'		\
	'VERSION=$(VERSION)'			\
	'INSTALL_DATA=$(INSTALL_DATA)'		\
	'INSTALL_SCRIPT=$(INSTALL_SCRIPT)'	\
	'EXEEXT=$(EXEEXT)'			\
	'SHLIB_CFLAGS=$(SHLIB_CFLAGS)'		\
	'SHLIB_SUFFIX=$(SHLIB_SUFFIX)'

## Makefile starts here.

OBJ = getbits.o huffman.o layer3.o getdata.o misc2.o\
	transform.o audio.o buffer.o audioIO.o position.o layer2.o util.o

PLUGIN_NAME = amp

all: Makefile amp$(SHLIB_SUFFIX)

Makefile: Makefile.in
	cd $(topdir) && \
	  ./config.status

clean:
	$(RM) *.o core *.a *.dll *~ amp$(SHLIB_SUFFIX) *.def .#*

distclean: clean
	$(RM) *~ config.status config.cache config.log config.h Makefile

../dllinit.o:
	$(CC) -DOS_$(OS) $(DEFS) $(CFLAGS) -o ../dllinit.o -c ../dllinit.c

amp$(SHLIB_SUFFIX): $(OBJ) ../dllinit.o
	$(SHLIB_LD) -o amp$(SHLIB_SUFFIX) $(OBJ) ../dllinit.o

SOURCES = $(OBJECTS:%.o=$(srcdir)/%.c)

OS := $(shell uname -s) 

.c.o:
	$(CC) -DOS_$(OS) $(DEFS) $(CFLAGS) -c $<

depend:
	gcc -MM $(CPPFLAGS) $(DEFS) $(CFLAGS) *.c > .depend

install:
	$(INSTALL) $(PLUGIN_NAME)$(SHLIB_SUFFIX) $(PLUGINDIR)

audio.o: audio.c ../../include/irc.h ../../include/defs.h \
 ../../include/config.h ../../include/../.config.h \
 ../../include/color.h ../../include/bsdglob.h ../../include/irc_std.h \
 ../../include/debug.h ../../include/newio.h ../../include/struct.h \
 ../../include/alist.h ../../include/ircaux.h ../../include/hash.h \
 ../../include/input.h ../../include/module.h ../../include/hook.h \
 ../../include/modval.h amp.h proto.h audio.h getbits.h huffman.h \
 layer2.h layer3.h position.h transform.h misc2.h
audioIO.o: audioIO.c
audioIO_Linux.o: audioIO_Linux.c amp.h ../../include/defs.h proto.h \
 audioIO.h
buffer.o: buffer.c amp.h ../../include/defs.h proto.h transform.h \
 audioIO.h audio.h
getbits.o: getbits.c amp.h ../../include/defs.h proto.h audio.h \
 getbits.h
getdata.o: getdata.c amp.h ../../include/defs.h proto.h audio.h \
 getbits.h huffman.h getdata.h
huffman.o: huffman.c audio.h getbits.h huffman.h
layer2.o: layer2.c amp.h ../../include/defs.h proto.h audio.h \
 getbits.h transform.h layer2.h
layer3.o: layer3.c amp.h ../../include/defs.h proto.h audio.h \
 getbits.h getdata.h huffman.h misc2.h transform.h layer3.h
misc2.o: misc2.c amp.h ../../include/defs.h proto.h audio.h getdata.h \
 huffman.h misc2.h
position.o: position.c amp.h ../../include/defs.h proto.h audio.h \
 getbits.h position.h
transform.o: transform.c audio.h getdata.h misc2.h transform.h
util.o: util.c amp.h ../../include/defs.h proto.h audio.h

--- NEW FILE: proto.h ---
/* From: util.c */
void die(char *, ...);
void warn(char *, ...);
void msg(char *, ...);
void debugSetup(char *);
void debugOptions();

/* From: audioIO_<OSTYPE>.c */
void audioOpen(int frequency, int stereo, int volume);
void audioSetVolume(int);
void audioFlush();
void audioClose();
int  audioWrite(char *, int);
int  getAudioFd();
void audioBufferOn(int);


/* From: buffer.c */
void printout(void);
int  audioBufferOpen(int, int, int);
void audioBufferClose();
void audioBufferWrite(char *, int);
void audioBufferFlush();

/* From: audio.c */
void displayUsage();

--- NEW FILE: amp.h ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/

/* these should not be touched
*/
#define		SYNCWORD	0xfff

#ifndef TRUE
#define		TRUE		1
#endif
#ifndef FALSE
#define		FALSE		0
#endif

/* 
 * version 
 */
#define		MAJOR		0
#define		MINOR		7
#define		PATCH		6


#include "defs.h"
#include "proto.h"

#ifndef MAX
#define MAX(a,b)	((a) > (b) ? (a) : (b))
#endif
#define MAX3(a,b,c)	((a) > (b) ? MAX(a, c) : MAX(b, c))
#ifndef MIN
#define MIN(a,b)	((a) < (b) ? (a) : (b))
#endif


extern int AUDIO_BUFFER_SIZE;

--- NEW FILE: getdata.h ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/
 
/* getdata.h 
 *
 * tomislav uzelac  Apr 1996
 */
 
extern int decode_scalefactors(struct SIDE_INFO *info,struct AUDIO_HEADER *header,int gr,int ch); 

extern int is_max[21];
extern int intensity_scale;

#ifdef GETDATA

static char t_slen1[16]={0,0,0,0,3,1,1,1,2,2,2,3,3,3,4,4};
static char t_slen2[16]={0,1,2,3,0,1,2,3,1,2,3,1,2,3,2,3};

int is_max[21]; /* the maximum value of is_pos. for short blocks is_max[sfb=0] == is_max[6],
	   	 * it's sloppy but i'm sick of waisting storage. blaah...
		 */
int intensity_scale;

int decode_scalefactors(struct SIDE_INFO *info,struct AUDIO_HEADER *header,int gr,int ch);

/* my implementation of MPEG2 scalefactor decoding is, admitably, horrible
 * anyway, just take a look at pg.18 of MPEG2 specs, and you'll know what
 * this is all about
 */
static const char spooky_table[2][3][3][4]={
{
{ {6,5,5,5},   {9,9,9,9},   {6,9,9,9} },
{ {6,5,7,3},   {9,9,12,6},  {6,9,12,6}},
{ {11,10,0,0}, {18,18,0,0}, {15,18,0,0}} 
},
{
{ {7,7,7,0},   {12,12,12,0}, {6,15,12,0}},
{ {6,6,6,3},   {12,9,9,6},   {6,12,9,6}},
{ {8,8,5,0},   {15,12,9,0},  {6,18,9,0}}
}};

#endif /* GETDATA */

--- NEW FILE: util.c ---
/* this file is a part of amp software

	util.c: created by Andrew Richards

*/

#define AMP_UTIL
#include "amp.h"

#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#include "audio.h"

/* die - for terminal conditions prints the error message and exits */
/* can not be suppressed with -q,-quiet	*/
void
die(char *fmt, ...)
{
#if 0
	va_list ap;
	va_start(ap,fmt);
	vfprintf(stderr, fmt, ap);
#endif
	_exit(-1);
}


/* warn - for warning messages. Can be suppressed by -q,-quiet			*/
void
warn(char *fmt, ...)
{
#if 0
	va_list ap;
	va_start(ap,fmt);
	if (!A_QUIET) {
		fprintf(stderr,"Warning: ");
		vfprintf(stderr, fmt, ap);
	}
#endif
}


/* msg - for general output. Can be suppressed by -q,-quiet. Output */
/* goes to stderr so it doesn't conflict with stdout output */
void
msg(char *fmt, ...)
{
#if 0
	va_list ap;
	va_start(ap,fmt);
 
	if (!A_QUIET)
	  if (A_MSG_STDOUT) {
	    vfprintf(stdout, fmt, ap);
	    fflush(stdout);
	  } else {
	    vfprintf(stderr, fmt, ap);
	    fflush(stderr);
	  }
#endif
}


--- NEW FILE: misc2.c ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/
 
/* misc2.c  requantization, stereo processing, reordering(shortbl) and antialiasing butterflies
 *
 * misc.c was created by tomislav uzelac in May 1996, and was completely awful
 * Created by: tomislav uzelac Dec 22 1996
 * some more speed injected, cca. Jun 1 1997
 */
#include <math.h>

#include "amp.h"
#include "audio.h"
#include "getdata.h"
#include "huffman.h"

#define MISC2
#include "misc2.h"

[...1066 lines suppressed...]
		b = x[-7];
                x[-7] = b * Cs[6] - a * Ca[6];
                x[6]  = a * Cs[6] + b * Ca[6];

	        a = x[7];
		b = x[-8];
                x[-8] = b * Cs[7] - a * Ca[7];
                x[7]  = a * Cs[7] + b * Ca[7];
	}
}

/* calculating t_43 instead of having that big table in misc2.h
 */

void calculate_t43(void)
{
int i;
	for (i=0;i<8192;i++)
		t_43[i]=(float)pow((float)i,1.33333333333f);
}

--- NEW FILE: position.h ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/

extern int ffwd(struct AUDIO_HEADER *header, int nframes);
extern int rew(struct AUDIO_HEADER *header, int nframes);

#ifdef POSITION
int ffwd(struct AUDIO_HEADER *header, int nframes);
int rew(struct AUDIO_HEADER *header, int nframes);
#endif

--- NEW FILE: audioIO.c ---
#ifdef OS_AIX
  #include "audioIO_AIX.c"
#endif

#ifdef OS_Linux
  #include "audioIO_Linux.c"
#endif

#ifdef OS_BSD
  #include "audioIO_Linux.c"
#endif

#if defined(OS_IRIX) || defined(OS_IRIX64)
  #include "audioIO_IRIX.c"
#endif

#ifdef OS_HPUX
  #include "audioIO_HPUX.c"
#endif

#ifdef OS_SunOS
  #include "audioIO_SunOS.c"
#endif

#ifdef __BEOS__
  #include "audioIO_BeOS.c"
#endif

--- NEW FILE: huffman.c ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/
 
/* huffman.c  huffman decoding
 *
 * Created by: tomislav uzelac  Mar,Apr 1996
 * Last modified by: tomislav uzelac Mar  8 97
 */
#include "audio.h"
#include "getbits.h"

#define HUFFMAN
#include "huffman.h"

static inline unsigned int viewbits(int n)
{
unsigned int pos,ret_value;

        pos = data >> 3;
        ret_value = buffer[pos] << 24 |
                    buffer[pos+1] << 16 |
                    buffer[pos+2] << 8 |
                    buffer[pos+3];
        ret_value <<= data & 7;
        ret_value >>= 32 - n;

        return ret_value;
}

static inline void sackbits(int n)
{
        data += n;
        data &= 8*BUFFER_SIZE-1;
}

/* huffman_decode() is supposed to be faster now
 * decodes one codeword and returns no. of bits
 */
static inline int huffman_decode(int tbl,int *x,int *y)
{
unsigned int chunk;
register unsigned int *h_tab;
register unsigned int lag = 0;
register unsigned int half_lag;
int len;

	h_tab=tables[tbl];
	chunk=viewbits(19);

	h_tab += h_cue[tbl][chunk >> (19-NC_O)];

	len=(*h_tab>>8)&0x1f;

	/* check for an immediate hit, so we can decode those short codes very fast
	*/
	if ((*h_tab>>(32-len)) != (chunk>>(19-len))) {
		if (chunk >> (19-NC_O) < N_CUE-1)
		  lag=(h_cue[tbl][(chunk >> (19-NC_O))+1] -
		       h_cue[tbl][chunk >> (19-NC_O)]);
		else {
			/* we strongly depend on h_cue[N_CUE-1] to point to
			 * the last entry in the huffman table, so we should
			 * noT get here anyway. if it didn't, we'd have to
			 * have another table with huffman tables lengths, and
			 * it would be a mess. just in case, scream&shout.
			 */ 
			/*printf(" h_cue clobbered. this is a bug. blip.\n");*/
			_exit (-1);
		}
		chunk <<= 32-19;
		chunk |= 0x1ff;

		half_lag = lag >> 1;

		h_tab += half_lag;
		lag -= half_lag;

		while (lag > 1) {
		        half_lag = lag >> 1;

		        if (*h_tab < chunk)
		                h_tab += half_lag;
		        else
		                h_tab -= half_lag;

                        lag -= half_lag;
		}

		len=(*h_tab>>8)&0x1f;
		if ((*h_tab>>(32-len)) != (chunk>>(32-len))) {
		        if (*h_tab > chunk)
		                h_tab--;
		        else 
		                h_tab++;
		  
		        len=(*h_tab>>8)&0x1f;
		}
	}
	sackbits(len);
	*x=(*h_tab>>4)&0xf;
	*y=*h_tab&0xf;
	return len;
}

static inline int _qsign(int x,int *q)
{
int ret_value=0,i;
	for (i=3;i>=0;i--) 
		if ((x>>i) & 1) {
			if (getbits(1)) *q++=-1;
				else *q++=1;
			ret_value++;
		}
		else *q++=0;
	return ret_value;
}		

int decode_huffman_data(struct SIDE_INFO *info,int gr,int ch,int ssize)
{
int l,i,cnt,x,y;
int q[4],r[3],linbits[3],tr[4]={0,0,0,0};
int big_value = info->big_values[gr][ch] << 1;

	for (l=0;l<3;l++) {
		tr[l]=info->table_select[gr][ch][l];
		linbits[l]=t_linbits[info->table_select[gr][ch][l]];
	}

	tr[3]=32+info->count1table_select[gr][ch];

	/* we have to be careful here because big_values are not necessarily
	 * aligned with sfb boundaries
	 */
	if (!info->window_switching_flag[gr][ch] && info->block_type[gr][ch]==0) {

	/* this code needed some cleanup
	*/
		r[0]=t_l[info->region0_count[gr][ch]] + 1;
		if (r[0] > big_value)
			r[0]=r[1]=big_value;
		else {
			r[1]=t_l[ info->region0_count[gr][ch] + info->region1_count[gr][ch] + 1 ] + 1;
			if (r[1] > big_value)
				r[1]=big_value;
		}
		r[2]=big_value;

	} else {

		if (info->block_type[gr][ch]==2 && info->mixed_block_flag[gr][ch]==0) 
			r[0]=3*(t_s[2]+1);
		else 
			r[0]=t_l[7]+1;

		if (r[0] > big_value)
			r[0]=big_value;

		r[1]=r[2]=big_value;
	}

	l=0; cnt=0;
	for (i=0;i<3;i++) {
		for (;l<r[i];l+=2) {
		        int j = linbits[i];

			cnt+=huffman_decode(tr[i],&x,&y);

			if (x==15 && j>0) {
			        x+=getbits(j);
			        cnt+=j;
			}
			if (x) {
			        if (getbits(1)) x=-x;
			        cnt++;
			}
			if (y==15 && j>0) {
			        y+=getbits(j);
			        cnt+=j;
			}
			if (y) {
			        if (getbits(1)) y=-y;
			        cnt++;
			}

			is[ch][l]=x;
			is[ch][l+1]=y;
		}
	}
	while ((cnt < info->part2_3_length[gr][ch]-ssize) && (l<576)) {
		cnt+=huffman_decode(tr[3],&x,&y);
		cnt+=_qsign(x,q);
		for (i=0;i<4;i++) is[ch][l+i]=q[i]; /* ziher je ziher, is[578]*/
		l+=4;
	}

	/*  set position to start of the next gr/ch
	 */
 	if (cnt != info->part2_3_length[gr][ch] - ssize ) {
 		data-=cnt-(info->part2_3_length[gr][ch] - ssize);
 		data&= 8*BUFFER_SIZE - 1;
 	}
	if (l<576) non_zero[ch]=l;
	else non_zero[ch]=576;
	/* zero out everything else
	*/
	for (;l<576;l++) is[ch][l]=0;
	return 1;
}

--- NEW FILE: audio.c ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/

/* audio.c	main amp source file 
 *
 * Created by: tomislav uzelac	Apr 1996 
 * Karl Anders Oygard added the IRIX code, 10 Mar 1997.
 * Ilkka Karvinen fixed /dev/dsp initialization, 11 Mar 1997.
 * Lutz Vieweg added the HP/UX code, 14 Mar 1997.
 * Dan Nelson added FreeBSD modifications, 23 Mar 1997.
 * Andrew Richards complete reorganisation, new features, 25 Mar 1997
 * Edouard Lafargue added sajber jukebox support, 12 May 1997
 */ 



#include "irc.h"
#include "struct.h"
#include "ircaux.h"
#include "input.h"
#include "module.h"
#include "hook.h"
#define INIT_MODULE
#include "modval.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/signal.h>
#include <sys/time.h>

#ifndef __BEOS__
#include <sys/uio.h>
#endif

#include <sys/socket.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#include "amp.h"
#define AUDIO
#include "audio.h"
#include "getbits.h"
#include "huffman.h"
#include "layer2.h"
#include "layer3.h"
#include "position.h"
#include "transform.h"
#include "misc2.h"

int bufferpid = 0;
unsigned long filesize = 0;
unsigned long framesize = 0;


off_t file_size (char *filename)
{
	struct stat statbuf;

	if (!stat(filename, &statbuf))
		return (off_t)(statbuf.st_size);
	else
		return -1;
}

#if 0
void statusDisplay(struct AUDIO_HEADER *header, int frameNo)
{
	return;
}

volatile int intflag = 0;

void (*catchsignal(int signum, void(*handler)()))()
{
	struct sigaction new_sa;
	struct sigaction old_sa;

	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
        
int decodeMPEG(struct AUDIO_HEADER *header)
{
int cnt, g, snd_eof;

	/*
	 * decoder loop **********************************
	 */
	snd_eof=0;
	cnt=0;

	while (!snd_eof) 
	{
		while (!snd_eof && ready_audio()) 
		{
			if ((g=gethdr(header))!=0)
			{
				report_header_error(g);
				snd_eof=1;
				break;
                	}

			if (header->protection_bit==0) 
				getcrc();

#if 0
			statusDisplay(header,cnt);	
#endif
			if (header->layer==1) 
			{
				if (layer3_frame(header,cnt)) 
				{
					yell(" error. blip.");
					return -1;
				}
			} 
			else if (header->layer==2)
			{
				if (layer2_frame(header,cnt)) 
				{
					yell(" error. blip.");
					return -1;
				}
			}
			cnt++;
		}
	}
	return 0;
}


BUILT_IN_DLL(mp3_volume)
{
char *vol;
	if ((vol = next_arg(args, &args)))
	{
		int volume = 0;
		volume = my_atol(vol);
		if (volume > 0 && volume <= 100)
		{
			audioSetVolume(volume);
			bitchsay("Volume is now set to %d", volume);
		}
		else
			bitchsay("Volume is between 0 and 100");
	}
	else
		bitchsay("/mp3vol [1-100]");
}

BUILT_IN_DLL(mp3_play)
{
	if (args && *args)
	{
		if (!fork())
		{
			play(args);
			update_input(UPDATE_ALL);
			_exit(1);
		}
		update_input(UPDATE_ALL);
	}
	else
		bitchsay("/mp3 filename");
}

BUILT_IN_FUNCTION(func_convert_time)
{
int hours, minutes, seconds;
	if (!input)
		return m_strdup(empty_string);
	seconds = my_atol(input);
	hours = seconds / ( 60 * 60 );
	minutes = seconds / 60;
	seconds = seconds % 60;
	return m_sprintf("[%02d:%02d:%02d]", hours, minutes, seconds);
}

int Amp_Init(IrcCommandDll **intp, Function_ptr *global_table)
{
	initialize_module("amp");

	initialise_decoder();	/* initialise decoder */
	A_QUIET = TRUE;
	AUDIO_BUFFER_SIZE=300*1024;
	A_SHOW_CNT=FALSE;
	A_SET_VOLUME=-1;
	A_SHOW_TIME=0;
	A_AUDIO_PLAY=TRUE;
	A_DOWNMIX=FALSE;
	add_module_proc(COMMAND_PROC, "Amp", "mp3", NULL, 0, 0, mp3_play, NULL);
	add_module_proc(COMMAND_PROC, "Amp", "mp3vol", NULL, 0, 0, mp3_volume, NULL);
	add_module_proc(ALIAS_PROC, "Amp", "TIMEDECODE", NULL, 0, 0, func_convert_time, NULL);
	bitchsay("Amp Module loaded. /mp3 <filename> /mp3vol <L> <R> $timedecode(seconds)");
	return 0;
}

/* call this once at the beginning
 */
void initialise_decoder(void)
{
	premultiply();
	imdct_init();
	calculate_t43();
}

/* call this before each file is played
 */
void initialise_globals(void)
{
	append=data=nch=0; 
        f_bdirty=TRUE;
        bclean_bytes=0;

	memset(s,0,sizeof s);
	memset(res,0,sizeof res);
}

void report_header_error(int err)
{
char *s = NULL;
	switch (err) {
		case GETHDR_ERR: 
			s = "error reading mpeg bitstream. exiting.";
			break;
		case GETHDR_NS : 
			s = "this is a file in MPEG 2.5 format, which is not defined" \
			    "by ISO/MPEG. It is \"a special Fraunhofer format\"." \
			    "amp does not support this format. sorry.";
			break;
		case GETHDR_FL1: 
			s = "ISO/MPEG layer 1 is not supported by amp (yet).";
			break;
		case GETHDR_FF : 
			s = "free format bitstreams are not supported. sorry.";
			break;	
		case GETHDR_SYN: 
			s = "oops, we're out of sync.";
			break;
		case GETHDR_EOF: 
		default: 		; /* some stupid compilers need the semicolon */
	}	
	if (s)
		do_hook(MODULE_LIST, "AMP ERROR blip %s", s);
}

/* TODO: there must be a check here to see if the audio device has been opened
 * successfuly. This is a bitch because it requires all 6 or 7 OS-specific functions
 * to be changed. Is anyone willing to do this at all???
 */
int setup_audio(struct AUDIO_HEADER *header)
{
	if (A_AUDIO_PLAY)  
	{
		if (AUDIO_BUFFER_SIZE==0)
			audioOpen(t_sampling_frequency[header->ID][header->sampling_frequency],
					(header->mode!=3 && !A_DOWNMIX),A_SET_VOLUME);
		else
			bufferpid = audioBufferOpen(t_sampling_frequency[header->ID][header->sampling_frequency],
					(header->mode!=3 && !A_DOWNMIX),A_SET_VOLUME);
	}
	return 0;
}

void close_audio(void)
{
	if (A_AUDIO_PLAY)
	{
		if (AUDIO_BUFFER_SIZE!=0)
			audioBufferClose();
		else
			audioClose();
	}
}

int ready_audio(void)
{
	return 1;
}

/* remove the trailing spaces from a string */
static void strunpad(char *str)
{
	int i = strlen(str);

	while ((i > 0) && (str[i-1] == ' '))
		i--;
	str[i] = 0;
}
                    
static void print_id3_tag(FILE *fp, char *buf)
{
	struct id3tag {
		char tag[3];
		char title[30];
		char artist[30];
		char album[30];
		char year[4];
		char comment[30];
		unsigned char genre;
	};
	struct idxtag {
		char tag[3];
		char title[90];
		char artist[50];
		char album[50];
		char comment[50];
	};
	struct id3tag *tag = (struct id3tag *) buf;
	struct idxtag *xtag = (struct idxtag *) buf;
	char title[121]="\0";
	char artist[81]="\0";
	char album[81]="\0";
	char year[5]="\0";
	char comment[81]="\0";

	strncpy(title,tag->title,30);
	strncpy(artist,tag->artist,30);
	strncpy(album,tag->album,30);
	strncpy(year,tag->year,4);
	strncpy(comment,tag->comment,30);
	strunpad(title);
	strunpad(artist);
	strunpad(album);
	strunpad(comment);
	
	if ((fseek(fp, 384, SEEK_END) != -1) && (fread(buf, 256, 1, fp) == 1))
	{
		if (!strncmp(buf, "TXG", 3))
		{
			strncat(title, xtag->title, 90);
			strncat(artist, xtag->artist, 50);
			strncat(album, xtag->album, 50);
			strncat(comment, xtag->comment, 50);
			strunpad(title);
			strunpad(artist);
			strunpad(album);
			strunpad(comment);
		}
	}
	if (!do_hook(MODULE_LIST, "AMP ID3 \"%s\" \"%s\" \"%s\" %s %d %s", title, artist, album, year, tag->genre, comment))
	{
		bitchsay("Title  : %.120s  Artist: %s",title, artist);
		bitchsay("Album  : %.80s  Year: %4s, Genre: %d",album, year, (int)tag->genre);
		bitchsay("Comment: %.80s",comment);
	}
}


/* 
 * TODO: add some kind of error reporting here
 */
void play(char *inFileStr)
{
char *f;
long totalframes = 0;
long tseconds = 0;
struct AUDIO_HEADER header;
int bitrate, fs, g, cnt = 0;

	while ((f = new_next_arg(inFileStr, &inFileStr)))
	{
		if (!f || !*f)
			return;	
		if ((in_file=fopen(f,"r"))==NULL) 
		{
			if (!do_hook(MODULE_LIST, "AMP ERROR open %s", f))
				put_it("Could not open file: %s\n", f);
			continue;
		}



		filesize = file_size(f);
		initialise_globals();

		if ((g=gethdr(&header))!=0) 
		{
			report_header_error(g);
			continue;
		}

		if (header.protection_bit==0) 
			getcrc();

		if (setup_audio(&header)!=0) 
		{
			yell("Cannot set up audio. Exiting");
			continue;
		}
	
		filesize -= sizeof(header);

		switch (header.layer)
		{
			case 1:
			{
				if (layer3_frame(&header,cnt)) 
				{
					yell(" error. blip.");
					continue;
				}
				break;
			} 
			case 2:
			{
				if (layer2_frame(&header,cnt)) 
				{
					yell(" error. blip.");
					continue;
				}
				break;
			}
			default:
				continue;
		}

		bitrate=t_bitrate[header.ID][3-header.layer][header.bitrate_index];
	       	fs=t_sampling_frequency[header.ID][header.sampling_frequency];

	        if (header.ID) 
        		framesize=144000*bitrate/fs;
	       	else 
       			framesize=72000*bitrate/fs;



		totalframes = (filesize / (framesize + 1)) - 1;
		tseconds = (totalframes * 1152/
		    t_sampling_frequency[header.ID][header.sampling_frequency]);
                
		if (A_AUDIO_PLAY)
		{
			char *p = strrchr(f, '/');
			if (!p) p = f; else p++;
			if (!do_hook(MODULE_LIST, "AMP PLAY %lu %lu %s", tseconds, filesize, p))
				bitchsay("Playing: %s\n", p);
		}

		/*
		 * 
		 */
		if (!(fseek(in_file, 0, SEEK_END)))
		{
			char id3_tag[256];
			if (!fseek(in_file, -128, SEEK_END) && (fread(id3_tag,128, 1, in_file) == 1))
			{
				if (!strncmp(id3_tag, "TAG", 3))
					print_id3_tag(in_file, id3_tag);
			}
			fseek(in_file,0,SEEK_SET);
		}
		decodeMPEG(&header);
		do_hook(MODULE_LIST, "AMP CLOSE %s", f);
		close_audio();
		fclose(in_file);
	}
}


--- NEW FILE: huffman.h ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/
 
/* huffman.h  
 * 	      
 * Created by: tomislav uzelac  Mar 1996
 * Last edited by: tomislav uzelac  Mar  8 97
 */
 
extern int decode_huffman_data(struct SIDE_INFO *info,int gr,int ch,int ssize);

extern int non_zero[2];
extern int t_linbits[32];

#ifdef HUFFMAN

static inline unsigned int viewbits(int n);
static inline void sackbits(int n);
static inline int huffman_decode(int tbl,int *x,int *y);
static inline int _qsign(int x,int *q);
int decode_huffman_data(struct SIDE_INFO *info,int gr,int ch,int ssize);

int non_zero[2]; /* this is 2*bigvalues+4*count1, i guess...*/

#define N_CUE 16
#define NC_O  4

int t_linbits[32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13};
 
/* these are the huffman tables, rearranged for lookup
*/
unsigned int h0[1]={0x0};
unsigned int h1[4]={0x311, 0x20000301, 0x40000210, 0x80000100};
unsigned int h2[9]={0x622, 0x4000602, 0x8000512, 0x10000521, 0x18000520, 0x20000311, 0x40000301, 0x60000310,
 0x80000100};
unsigned int h3[9]={ 0x622, 0x4000602, 0x8000512, 0x10000521, 0x18000520, 0x20000310, 0x40000211, 0x80000201,
 0xc0000200};
unsigned int h5[16]={0x833, 0x1000823, 0x2000732, 0x4000631, 0x8000713, 0xa000703, 0xc000730, 0xe000722,
 0x10000612, 0x14000621, 0x18000602, 0x1c000620, 0x20000311, 0x40000301, 0x60000310, 0x80000100};
unsigned int h6[16]={0x733, 0x2000703, 0x4000623, 0x8000632, 0xc000630, 0x10000513, 0x18000531, 0x20000522,
 0x28000502, 0x30000412, 0x40000421, 0x50000420, 0x60000301, 0x80000211, 0xc0000310, 0xe0000300};
unsigned int h7[36]={ 0xa55, 0x400a45, 0x800a54, 0xc00a53, 0x1000935, 0x1800944, 0x2000925, 0x2800952,
 0x3000815, 0x4000851, 0x5000905, 0x5800934, 0x6000850, 0x7000943, 0x7800933, 0x8000824,
 0x9000842, 0xa000714, 0xc000741, 0xe000740, 0x10000804, 0x11000823, 0x12000832, 0x13000803,
 0x14000713, 0x16000731, 0x18000730, 0x1a000722, 0x1c000612, 0x20000521, 0x28000602, 0x2c000620,
 0x30000411, 0x40000301, 0x60000310, 0x80000100};
unsigned int h8[36]={0xb55, 0x200b54, 0x400a45, 0x800953, 0x1000a35, 0x1400a44, 0x1800925, 0x2000952,
 0x2800905, 0x3000815, 0x4000851, 0x5000934, 0x5800943, 0x6000950, 0x6800933, 0x7000824,
 0x8000842, 0x9000814, 0xa000741, 0xc000804, 0xd000840, 0xe000823, 0xf000832, 0x10000813,
 0x11000831, 0x12000803, 0x13000830, 0x14000622, 0x18000602, 0x1c000620, 0x20000412, 0x30000421,
 0x40000211, 0x80000301, 0xa0000310, 0xc0000200};
unsigned int h9[36]={ 0x955, 0x800945, 0x1000835, 0x2000853, 0x3000954, 0x3800905, 0x4000844, 0x5000825,
 0x6000852, 0x7000815, 0x8000751, 0xa000734, 0xc000743, 0xe000850, 0xf000804, 0x10000724,
 0x12000742, 0x14000733, 0x16000740, 0x18000614, 0x1c000641, 0x20000623, 0x24000632, 0x28000513,
 0x30000531, 0x38000603, 0x3c000630, 0x40000522, 0x48000502, 0x50000412, 0x60000421, 0x70000420,
 0x80000311, 0xa0000301, 0xc0000310, 0xe0000300};
unsigned int h10[64]={ 0xb77, 0x200b67, 0x400b76, 0x600b57, 0x800b75, 0xa00b66, 0xc00a47, 0x1000a74,
 0x1400a56, 0x1800a65, 0x1c00a37, 0x2000a73, 0x2400a46, 0x2800b55, 0x2a00b54, 0x2c00a63,
 0x3000927, 0x3800972, 0x4000a64, 0x4400a07, 0x4800970, 0x5000962, 0x5800a45, 0x5c00a35,
 0x6000906, 0x6800a53, 0x6c00a44, 0x7000817, 0x8000871, 0x9000936, 0x9800926, 0xa000a25,
 0xa400a52, 0xa800915, 0xb000951, 0xb800a34, 0xbc00a43, 0xc000816, 0xd000861, 0xe000860,
 0xf000905, 0xf800950, 0x10000924, 0x10800942, 0x11000933, 0x11800904, 0x12000814, 0x13000841,
 0x14000840, 0x15000823, 0x16000832, 0x17000803, 0x18000713, 0x1a000731, 0x1c000730, 0x1e000722,
 0x20000612, 0x24000621, 0x28000602, 0x2c000620, 0x30000411, 0x40000301, 0x60000310, 0x80000100};
unsigned int h11[64]={ 0xa77, 0x400a67, 0x800a76, 0xc00a75, 0x1000a66, 0x1400a47, 0x1800a74, 0x1c00b57,
 0x1e00b55, 0x2000a56, 0x2400a65, 0x2800937, 0x3000973, 0x3800946, 0x4000a45, 0x4400a54,
 0x4800a35, 0x4c00a53, 0x5000827, 0x6000872, 0x7000964, 0x7800907, 0x8000771, 0xa000817,
 0xb000870, 0xc000836, 0xd000863, 0xe000860, 0xf000944, 0xf800925, 0x10000952, 0x10800905,
 0x11000815, 0x12000762, 0x14000826, 0x15000806, 0x16000716, 0x18000761, 0x1a000851, 0x1b000834,
 0x1c000850, 0x1d000943, 0x1d800933, 0x1e000824, 0x1f000842, 0x20000814, 0x21000841, 0x22000804,
 0x23000840, 0x24000723, 0x26000732, 0x28000613, 0x2c000631, 0x30000703, 0x32000730, 0x34000622,
 0x38000521, 0x40000412, 0x50000502, 0x58000520, 0x60000311, 0x80000301, 0xa0000310, 0xc0000200};
unsigned int h12[64]={ 0xa77, 0x400a67, 0x800976, 0x1000957, 0x1800975, 0x2000966, 0x2800947, 0x3000974,
 0x3800965, 0x4000856, 0x5000837, 0x6000973, 0x6800955, 0x7000827, 0x8000872, 0x9000846,
 0xa000864, 0xb000817, 0xc000871, 0xd000907, 0xd800970, 0xe000836, 0xf000863, 0x10000845,
 0x11000854, 0x12000844, 0x13000906, 0x13800905, 0x14000726, 0x16000762, 0x18000761, 0x1a000816,
 0x1b000860, 0x1c000835, 0x1d000853, 0x1e000825, 0x1f000852, 0x20000715, 0x22000751, 0x24000734,
 0x26000743, 0x28000850, 0x29000804, 0x2a000724, 0x2c000742, 0x2e000714, 0x30000633, 0x34000641,
 0x38000623, 0x3c000632, 0x40000740, 0x42000703, 0x44000630, 0x48000513, 0x50000531, 0x58000522,
 0x60000412, 0x70000421, 0x80000502, 0x88000520, 0x90000400, 0xa0000311, 0xc0000301, 0xe0000310};
unsigned int h13[256]={
 0x13fe, 0x33fc, 0x52fd, 0x91ed, 0x110ff, 0x210ef, 0x310df, 0x410ee,
 0x510cf, 0x610de, 0x710bf, 0x810fb, 0x910ce, 0xa10dc, 0xb11af, 0xb91e9,
 0xc0fec, 0xe0fdd, 0x1010fa, 0x1110cd, 0x120fbe, 0x140feb, 0x160f9f, 0x180ff9,
 0x1a0fea, 0x1c0fbd, 0x1e0fdb, 0x200f8f, 0x220ff8, 0x240fcc, 0x2610ae, 0x27109e,
 0x280f8e, 0x2a107f, 0x2b107e, 0x2c0ef7, 0x300eda, 0x340fad, 0x360fbc, 0x380fcb,
 0x3a0ff6, 0x3c0e6f, 0x400ee8, 0x440e5f, 0x480e9d, 0x4c0ed9, 0x500ef5, 0x540ee7,
 0x580eac, 0x5c0ebb, 0x600e4f, 0x640ef4, 0x680fca, 0x6a0fe6, 0x6c0ef3, 0x700d3f,
 0x780e8d, 0x7c0ed8, 0x800d2f, 0x880df2, 0x900e6e, 0x940e9c, 0x980d0f, 0xa00ec9,
 0xa40e5e, 0xa80dab, 0xb00e7d, 0xb40ed7, 0xb80d4e, 0xc00ec8, 0xc40ed6, 0xc80d3e,
 0xd00db9, 0xd80e9b, 0xdc0eaa, 0xe00c1f, 0xf00cf1, 0x1000cf0, 0x1100dba, 0x1180de5,
 0x1200de4, 0x1280d8c, 0x1300d6d, 0x1380de3, 0x1400ce2, 0x1500d2e, 0x1580d0e, 0x1600c1e,
 0x1700ce1, 0x1800de0, 0x1880d5d, 0x1900dd5, 0x1980d7c, 0x1a00dc7, 0x1a80d4d, 0x1b00d8b,
 0x1b80db8, 0x1c00dd4, 0x1c80d9a, 0x1d00da9, 0x1d80d6c, 0x1e00cc6, 0x1f00c3d, 0x2000dd3,
 0x2080d7b, 0x2100c2d, 0x2200cd2, 0x2300c1d, 0x2400cb7, 0x2500d5c, 0x2580dc5, 0x2600d99,
 0x2680d7a, 0x2700cc3, 0x2800da7, 0x2880d97, 0x2900c4b, 0x2a00bd1, 0x2c00c0d, 0x2d00cd0,
 0x2e00c8a, 0x2f00ca8, 0x3000c4c, 0x3100cc4, 0x3200c6b, 0x3300cb6, 0x3400b3c, 0x3600b2c,
 0x3800bc2, 0x3a00b5b, 0x3c00cb5, 0x3d00c89, 0x3e00b1c, 0x4000bc1, 0x4200c98, 0x4300c0c,
 0x4400bc0, 0x4600cb4, 0x4700c6a, 0x4800ca6, 0x4900c79, 0x4a00b3b, 0x4c00bb3, 0x4e00c88,
 0x4f00c5a, 0x5000b2b, 0x5200ca5, 0x5300c69, 0x5400ba4, 0x5600c78, 0x5700c87, 0x5800b94,
 0x5a00c77, 0x5b00c76, 0x5c00ab2, 0x6000a1b, 0x6400ab1, 0x6800b0b, 0x6a00bb0, 0x6c00b96,
 0x6e00b4a, 0x7000b3a, 0x7200ba3, 0x7400b59, 0x7600b95, 0x7800a2a, 0x7c00aa2, 0x8000a1a,
 0x8400aa1, 0x8800b0a, 0x8a00b68, 0x8c00aa0, 0x9000b86, 0x9200b49, 0x9400a93, 0x9800b39,
 0x9a00b58, 0x9c00b85, 0x9e00b67, 0xa000a29, 0xa400a92, 0xa800b57, 0xaa00b75, 0xac00a38,
 0xb000a83, 0xb400b66, 0xb600b47, 0xb800b74, 0xba00b56, 0xbc00b65, 0xbe00b73, 0xc000919,
 0xc800991, 0xd000a09, 0xd400a90, 0xd800a48, 0xdc00a84, 0xe000a72, 0xe400b46, 0xe600b64,
 0xe800928, 0xf000982, 0xf800918, 0x10000a37, 0x10400a27, 0x10800917, 0x11000971, 0x11800a55,
 0x11c00a07, 0x12000a70, 0x12400a36, 0x12800a63, 0x12c00a45, 0x13000a54, 0x13400a26, 0x13800a62,
 0x13c00a35, 0x14000881, 0x15000908, 0x15800980, 0x16000916, 0x16800961, 0x17000906, 0x17800960,
 0x18000a53, 0x18400a44, 0x18800925, 0x19000952, 0x19800905, 0x1a000815, 0x1b000851, 0x1c000934,
 0x1c800943, 0x1d000950, 0x1d800924, 0x1e000942, 0x1e800933, 0x1f000814, 0x20000741, 0x22000804,
 0x23000840, 0x24000823, 0x25000832, 0x26000713, 0x28000731, 0x2a000703, 0x2c000730, 0x2e000722,
 0x30000612, 0x34000621, 0x38000602, 0x3c000620, 0x40000411, 0x50000401, 0x60000310, 0x80000100};
unsigned int h15[256]={ 0xdff, 0x80def, 0x100dfe, 0x180ddf, 0x200cee, 0x300dfd, 0x380dcf, 0x400dfc,
 0x480dde, 0x500ded, 0x580dbf, 0x600cfb, 0x700dce, 0x780dec, 0x800cdd, 0x900caf,
 0xa00cfa, 0xb00cbe, 0xc00ceb, 0xd00ccd, 0xe00cdc, 0xf00c9f, 0x1000cf9, 0x1100cea,
 0x1200cbd, 0x1300cdb, 0x1400c8f, 0x1500cf8, 0x1600ccc, 0x1700c9e, 0x1800ce9, 0x1900c7f,
 0x1a00cf7, 0x1b00cad, 0x1c00cda, 0x1d00cbc, 0x1e00c6f, 0x1f00dae, 0x1f80d0f, 0x2000bcb,
 0x2200bf6, 0x2400c8e, 0x2500ce8, 0x2600c5f, 0x2700c9d, 0x2800bf5, 0x2a00b7e, 0x2c00be7,
 0x2e00bac, 0x3000bca, 0x3200bbb, 0x3400cd9, 0x3500c8d, 0x3600b4f, 0x3800bf4, 0x3a00b3f,
 0x3c00bf3, 0x3e00bd8, 0x4000be6, 0x4200b2f, 0x4400bf2, 0x4600c6e, 0x4700cf0, 0x4800b1f,
 0x4a00bf1, 0x4c00b9c, 0x4e00bc9, 0x5000b5e, 0x5200bab, 0x5400bba, 0x5600be5, 0x5800b7d,
 0x5a00bd7, 0x5c00b4e, 0x5e00be4, 0x6000b8c, 0x6200bc8, 0x6400b3e, 0x6600b6d, 0x6800bd6,
 0x6a00be3, 0x6c00b9b, 0x6e00bb9, 0x7000b2e, 0x7200baa, 0x7400be2, 0x7600b1e, 0x7800be1,
 0x7a00c0e, 0x7b00ce0, 0x7c00b5d, 0x7e00bd5, 0x8000b7c, 0x8200bc7, 0x8400b4d, 0x8600b8b,
 0x8800ad4, 0x8c00bb8, 0x8e00b9a, 0x9000ba9, 0x9200b6c, 0x9400bc6, 0x9600b3d, 0x9800ad3,
 0x9c00ad2, 0xa000b2d, 0xa200b0d, 0xa400a1d, 0xa800a7b, 0xac00ab7, 0xb000ad1, 0xb400b5c,
 0xb600bd0, 0xb800ac5, 0xbc00a8a, 0xc000aa8, 0xc400a4c, 0xc800ac4, 0xcc00a6b, 0xd000ab6,
 0xd400b99, 0xd600b0c, 0xd800a3c, 0xdc00ac3, 0xe000a7a, 0xe400aa7, 0xe800aa6, 0xec00bc0,
 0xee00b0b, 0xf0009c2, 0xf800a2c, 0xfc00a5b, 0x10000ab5, 0x10400a1c, 0x10800a89, 0x10c00a98,
 0x11000ac1, 0x11400a4b, 0x11800ab4, 0x11c00a6a, 0x12000a3b, 0x12400a79, 0x128009b3, 0x13000a97,
 0x13400a88, 0x13800a2b, 0x13c00a5a, 0x140009b2, 0x14800aa5, 0x14c00a1b, 0x150009b1, 0x15800ab0,
 0x15c00a69, 0x16000a96, 0x16400a4a, 0x16800aa4, 0x16c00a78, 0x17000a87, 0x17400a3a, 0x178009a3,
 0x18000959, 0x18800995, 0x1900092a, 0x198009a2, 0x1a00091a, 0x1a8009a1, 0x1b000a0a, 0x1b400aa0,
 0x1b800968, 0x1c000986, 0x1c800949, 0x1d000994, 0x1d800939, 0x1e000993, 0x1e800a77, 0x1ec00a09,
 0x1f000958, 0x1f800985, 0x20000929, 0x20800967, 0x21000976, 0x21800992, 0x22000891, 0x23000919,
 0x23800990, 0x24000948, 0x24800984, 0x25000957, 0x25800975, 0x26000938, 0x26800983, 0x27000966,
 0x27800947, 0x28000828, 0x29000882, 0x2a000818, 0x2b000881, 0x2c000974, 0x2c800908, 0x2d000980,
 0x2d800956, 0x2e000965, 0x2e800937, 0x2f000973, 0x2f800946, 0x30000827, 0x31000872, 0x32000864,
 0x33000817, 0x34000855, 0x35000871, 0x36000907, 0x36800970, 0x37000836, 0x38000863, 0x39000845,
 0x3a000854, 0x3b000826, 0x3c000862, 0x3d000816, 0x3e000906, 0x3e800960, 0x3f000835, 0x40000761,
 0x42000853, 0x43000844, 0x44000725, 0x46000752, 0x48000715, 0x4a000751, 0x4c000805, 0x4d000850,
 0x4e000734, 0x50000743, 0x52000724, 0x54000742, 0x56000733, 0x58000641, 0x5c000714, 0x5e000704,
 0x60000623, 0x64000632, 0x68000740, 0x6a000703, 0x6c000613, 0x70000631, 0x74000630, 0x78000522,
 0x80000512, 0x88000521, 0x90000502, 0x98000520, 0xa0000311, 0xc0000401, 0xd0000410, 0xe0000300};
unsigned int h16[256]={ 0xbef, 0x200bfe, 0x400bdf, 0x600bfd, 0x800bcf, 0xa00bfc, 0xc00bbf, 0xe00bfb,
 0x1000aaf, 0x1400bfa, 0x1600b9f, 0x1800bf9, 0x1a00bf8, 0x1c00a8f, 0x2000a7f, 0x2400af7,
 0x2800a6f, 0x2c00af6, 0x30008ff, 0x4000a5f, 0x4400af5, 0x480094f, 0x50009f4, 0x58009f3,
 0x60009f0, 0x6800a3f, 0x6c010ce, 0x6c111ec, 0x6c191dd, 0x6c20fde, 0x6c40fe9, 0x6c610ea,
 0x6c710d9, 0x6c80eee, 0x6cc0fed, 0x6ce0feb, 0x6d00ebe, 0x6d40ecd, 0x6d80fdc, 0x6da0fdb,
 0x6dc0eae, 0x6e00ecc, 0x6e40fad, 0x6e60fda, 0x6e80f7e, 0x6ea0fac, 0x6ec0eca, 0x6f00fc9,
 0x6f20f7d, 0x6f40e5e, 0x6f80dbd, 0x70008f2, 0x800092f, 0x880090f, 0x900081f, 0xa0008f1,
 0xb000d9e, 0xb080ebc, 0xb0c0ecb, 0xb100e8e, 0xb140ee8, 0xb180e9d, 0xb1c0ee7, 0xb200ebb,
 0xb240e8d, 0xb280ed8, 0xb2c0e6e, 0xb300de6, 0xb380d9c, 0xb400eab, 0xb440eba, 0xb480ee5,
 0xb4c0ed7, 0xb500d4e, 0xb580ee4, 0xb5c0e8c, 0xb600dc8, 0xb680d3e, 0xb700d6d, 0xb780ed6,
 0xb7c0e9b, 0xb800eb9, 0xb840eaa, 0xb880de1, 0xb900dd4, 0xb980eb8, 0xb9c0ea9, 0xba00d7b,
 0xba80eb7, 0xbac0ed0, 0xbb00ce3, 0xbc00d0e, 0xbc80de0, 0xbd00d5d, 0xbd80dd5, 0xbe00d7c,
 0xbe80dc7, 0xbf00d4d, 0xbf80d8b, 0xc000d9a, 0xc080d6c, 0xc100dc6, 0xc180d3d, 0xc200d5c,
 0xc280dc5, 0xc300c0d, 0xc400d8a, 0xc480da8, 0xc500d99, 0xc580d4c, 0xc600db6, 0xc680d7a,
 0xc700c3c, 0xc800d5b, 0xc880d89, 0xc900c1c, 0xca00cc0, 0xcb00d98, 0xcb80d79, 0xcc00be2,
 0xce00c2e, 0xcf00c1e, 0xd000cd3, 0xd100c2d, 0xd200cd2, 0xd300cd1, 0xd400c3b, 0xd500d97,
 0xd580d88, 0xd600b1d, 0xd800cc4, 0xd900c6b, 0xda00cc3, 0xdb00ca7, 0xdc00b2c, 0xde00cc2,
 0xdf00cb5, 0xe000cc1, 0xe100c0c, 0xe200c4b, 0xe300cb4, 0xe400c6a, 0xe500ca6, 0xe600bb3,
 0xe800c5a, 0xe900ca5, 0xea00b2b, 0xec00bb2, 0xee00b1b, 0xf000bb1, 0xf200c0b, 0xf300cb0,
 0xf400c69, 0xf500c96, 0xf600c4a, 0xf700ca4, 0xf800c78, 0xf900c87, 0xfa00ba3, 0xfc00c3a,
  0xfd00c59, 0xfe00b2a, 0x10000c95, 0x10100c68, 0x10200ba1, 0x10400c86, 0x10500c77, 0x10600b94,
 0x10800c49, 0x10900c57, 0x10a00b67, 0x10c00aa2, 0x11000a1a, 0x11400b0a, 0x11600ba0, 0x11800b39,
 0x11a00b93, 0x11c00b58, 0x11e00b85, 0x12000a29, 0x12400a92, 0x12800b76, 0x12a00b09, 0x12c00a19,
 0x13000a91, 0x13400b90, 0x13600b48, 0x13800b84, 0x13a00b75, 0x13c00b38, 0x13e00b83, 0x14000b66,
 0x14200b28, 0x14400a82, 0x14800b47, 0x14a00b74, 0x14c00a18, 0x15000a81, 0x15400a80, 0x15800b08,
 0x15a00b56, 0x15c00a37, 0x16000a73, 0x16400b65, 0x16600b46, 0x16800a27, 0x16c00a72, 0x17000b64,
 0x17200b55, 0x17400a07, 0x17800917, 0x18000971, 0x18800a70, 0x18c00a36, 0x19000a63, 0x19400a45,
 0x19800a54, 0x19c00a26, 0x1a000962, 0x1a800916, 0x1b000961, 0x1b800a06, 0x1bc00a60, 0x1c000953,
 0x1c800a35, 0x1cc00a44, 0x1d000925, 0x1d800952, 0x1e000851, 0x1f000915, 0x1f800905, 0x20000934,
 0x20800943, 0x21000950, 0x21800924, 0x22000942, 0x22800933, 0x23000814, 0x24000841, 0x25000904,
 0x25800940, 0x26000823, 0x27000832, 0x28000713, 0x2a000731, 0x2c000803, 0x2d000830, 0x2e000722,
 0x30000612, 0x34000621, 0x38000602, 0x3c000620, 0x40000411, 0x50000401, 0x60000310, 0x80000100};
unsigned int h24[256]={ 0x8ef, 0x10008fe, 0x20008df, 0x30008fd, 0x40008cf, 0x50008fc, 0x60008bf, 0x70008fb,
 0x80007fa, 0xa0008af, 0xb00089f, 0xc0007f9, 0xe0007f8, 0x1000088f, 0x1100087f, 0x120007f7,
 0x1400076f, 0x160007f6, 0x1800075f, 0x1a0007f5, 0x1c00074f, 0x1e0007f4, 0x2000073f, 0x220007f3,
 0x2400072f, 0x260007f2, 0x280007f1, 0x2a00081f, 0x2b0008f0, 0x2c00090f, 0x2c800bee, 0x2ca00bde,
 0x2cc00bed, 0x2ce00bce, 0x2d000bec, 0x2d200bdd, 0x2d400bbe, 0x2d600beb, 0x2d800bcd, 0x2da00bdc,
 0x2dc00bae, 0x2de00bea, 0x2e000bbd, 0x2e200bdb, 0x2e400bcc, 0x2e600b9e, 0x2e800be9, 0x2ea00bad,
 0x2ec00bda, 0x2ee00bbc, 0x2f000bcb, 0x2f200b8e, 0x2f400be8, 0x2f600b9d, 0x2f800bd9, 0x2fa00b7e,
 0x2fc00be7, 0x2fe00bac, 0x300004ff, 0x40000bca, 0x40200bbb, 0x40400b8d, 0x40600bd8, 0x40800c0e,
 0x40900ce0, 0x40a00b0d, 0x40c00ae6, 0x41000b6e, 0x41200b9c, 0x41400ac9, 0x41800a5e, 0x41c00aba,
 0x42000ae5, 0x42400bab, 0x42600b7d, 0x42800ad7, 0x42c00ae4, 0x43000a8c, 0x43400ac8, 0x43800b4e,
 0x43a00b2e, 0x43c00a3e, 0x44000a6d, 0x44400ad6, 0x44800ae3, 0x44c00a9b, 0x45000ab9, 0x45400aaa,
 0x45800ae2, 0x45c00a1e, 0x46000ae1, 0x46400a5d, 0x46800ad5, 0x46c00a7c, 0x47000ac7, 0x47400a4d,
 0x47800a8b, 0x47c00ab8, 0x48000ad4, 0x48400a9a, 0x48800aa9, 0x48c00a6c, 0x49000ac6, 0x49400a3d,
 0x49800ad3, 0x49c00a2d, 0x4a000ad2, 0x4a400a1d, 0x4a800a7b, 0x4ac00ab7, 0x4b000ad1, 0x4b400a5c,
 0x4b800ac5, 0x4bc00a8a, 0x4c000aa8, 0x4c400a99, 0x4c800a4c, 0x4cc00ac4, 0x4d000a6b, 0x4d400ab6,
 0x4d800bd0, 0x4da00b0c, 0x4dc00a3c, 0x4e000ac3, 0x4e400a7a, 0x4e800aa7, 0x4ec00a2c, 0x4f000ac2,
 0x4f400a5b, 0x4f800ab5, 0x4fc00a1c, 0x50000a89, 0x50400a98, 0x50800ac1, 0x50c00a4b, 0x51000bc0,
 0x51200b0b, 0x51400a3b, 0x51800bb0, 0x51a00b0a, 0x51c00a1a, 0x520009b4, 0x52800a6a, 0x52c00aa6,
 0x53000a79, 0x53400a97, 0x53800ba0, 0x53a00b09, 0x53c00a90, 0x540009b3, 0x54800988, 0x55000a2b,
 0x55400a5a, 0x558009b2, 0x56000aa5, 0x56400a1b, 0x56800ab1, 0x56c00a69, 0x57000996, 0x578009a4,
 0x58000a4a, 0x58400a78, 0x58800987, 0x5900093a, 0x598009a3, 0x5a000959, 0x5a800995, 0x5b00092a,
  0x5b8009a2, 0x5c0009a1, 0x5c800968, 0x5d000986, 0x5d800977, 0x5e000949, 0x5e800994, 0x5f000939,
 0x5f800993, 0x60000958, 0x60800985, 0x61000929, 0x61800967, 0x62000976, 0x62800992, 0x63000919,
 0x63800991, 0x64000948, 0x64800984, 0x65000957, 0x65800975, 0x66000938, 0x66800983, 0x67000966,
 0x67800928, 0x68000982, 0x68800918, 0x69000947, 0x69800974, 0x6a000981, 0x6a800a08, 0x6ac00a80,
 0x6b000956, 0x6b800965, 0x6c000917, 0x6c800a07, 0x6cc00a70, 0x6d000873, 0x6e000937, 0x6e800927,
 0x6f000872, 0x70000846, 0x71000864, 0x72000855, 0x73000871, 0x74000836, 0x75000863, 0x76000845,
 0x77000854, 0x78000826, 0x79000862, 0x7a000816, 0x7b000861, 0x7c000906, 0x7c800960, 0x7d000835,
 0x7e000853, 0x7f000844, 0x80000825, 0x81000852, 0x82000815, 0x83000905, 0x83800950, 0x84000751,
 0x86000834, 0x87000843, 0x88000724, 0x8a000742, 0x8c000733, 0x8e000714, 0x90000741, 0x92000804,
 0x93000840, 0x94000723, 0x96000732, 0x98000613, 0x9c000631, 0xa0000703, 0xa2000730, 0xa4000622,
 0xa8000512, 0xb0000521, 0xb8000602, 0xbc000620, 0xc0000411, 0xd0000401, 0xe0000410, 0xf0000400};
unsigned int hA[16]={ 0x6b0, 0x40006f0, 0x80006d0, 0xc0006e0, 0x10000670, 0x14000650, 0x18000590, 0x20000560,
 0x28000530, 0x300005a0, 0x380005c0, 0x40000420, 0x50000410, 0x60000440, 0x70000480, 0x80000100};
unsigned int hB[16]={  0x4f0, 0x100004e0, 0x200004d0, 0x300004c0, 0x400004b0, 0x500004a0, 0x60000490, 0x70000480,
 0x80000470, 0x90000460, 0xa0000450, 0xb0000440, 0xc0000430, 0xd0000420, 0xe0000410, 0xf0000400};

/* now the cues, remember to change these tables if you change N_CUE
*/
unsigned char h_cue[34][N_CUE]={
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3},
{0,3,5,5,6,6,7,7,8,8,8,8,8,8,8,8},
{0,3,5,5,6,6,6,6,7,7,7,7,8,8,8,8},
{0,8,12,12,13,13,14,14,15,15,15,15,15,15,15,15},
{0,8,12,12,13,13,14,14,15,15,15,15,15,15,15,15},
{0,5,7,9,10,11,12,12,13,13,13,13,14,14,15,15},
{0,20,29,32,33,33,34,34,35,35,35,35,35,35,35,35},
{0,23,30,31,32,32,32,32,33,33,34,34,35,35,35,35},
{0,15,21,24,27,29,30,31,32,32,33,33,34,34,35,35},
{0,42,56,60,61,61,62,62,63,63,63,63,63,63,63,63},
{0,30,45,53,57,58,60,60,61,61,62,62,63,63,63,63},
{0,23,37,46,50,54,56,57,58,60,61,61,62,62,63,63},
{0,203,238,248,252,253,254,254,255,255,255,255,255,255,255,255},
{0,132,178,205,223,233,240,245,248,250,252,252,253,254,255,255},
{0,132,178,205,223,233,240,245,248,250,252,252,253,254,255,255},
{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
{0,162,231,248,252,253,254,254,255,255,255,255,255,255,255,255},
{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
{0,13,22,58,59,131,177,209,226,238,245,249,252,253,254,255},
{0,4,7,9,11,12,13,14,15,15,15,15,15,15,15,15},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
};

/* h4->h5, h14->h15 as suggested by Fraunhofer
 * tomislav Aug 21 1997
 */
unsigned int *tables[34]={h0,h1,h2,h3,h5,h5,h6,h7,h8,h9,h10,h11,h12,h13,h15,h15,
	h16,h16,h16,h16,h16,h16,h16,h16,h24,h24,h24,h24,h24,h24,h24,h24,hA,hB};
#endif /* HUFFMAN */

--- NEW FILE: position.c ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/
/* position.c 	ffwd/rew within a stream
 *
 * Creted by: Tomislav Uzelac, May 10 1997
 */
#include "amp.h"
#include "audio.h"
#include "getbits.h"

#define POSITION
#include "position.h"

/* Returns the number of frames actually skipped, -1 on error.
 *
 * Values in header are not changed if retval!=nframes.
 * This is not necessary because gethdr() doesn't clobber
 * the contents of header, but I don't want to rely on that. 
 */
int ffwd(struct AUDIO_HEADER *header, int nframes)
{
int cnt=0,g;
int hsize,bitrate,fs,mean_frame_size;
struct AUDIO_HEADER tmp;
	memcpy(&tmp,header,sizeof(tmp));

	while (cnt < nframes) {
	        if (tmp.ID)
        	        if (tmp.mode==3) hsize=21;
                	else hsize=36;
        	else
                	if (tmp.mode==3) hsize=13;
               	 	else  hsize=21;
                if (tmp.protection_bit==0) hsize+=2;
		if ((g=dummy_getinfo(hsize)))  /* dummy_getinfo: reads hsize-4 bytes */
			switch (g) {
                        case GETHDR_EOF: return cnt;
			case GETHDR_ERR:
			default:	return -1;
                        }

	        bitrate=t_bitrate[tmp.ID][3-tmp.layer][tmp.bitrate_index];
        	fs=t_sampling_frequency[tmp.ID][tmp.sampling_frequency];		
	        if (tmp.ID) mean_frame_size=144000*bitrate/fs;
	        else mean_frame_size=72000*bitrate/fs;
		fillbfr(mean_frame_size + tmp.padding_bit - hsize);

		if ((g=gethdr(&tmp))) 
			switch (g) {
			case GETHDR_EOF: return cnt;
			case GETHDR_ERR:
			default:	return -1;
			}
		cnt++;
	}	

	memcpy(header,&tmp,sizeof(tmp));		
	return cnt;
}

/* Mostly the same as ffwd. Some streams might be 'tough', i.e.
 * the ones switching bitrates.
 */
int rew(struct AUDIO_HEADER *header, int nframes)
{
int cnt=0;
int bitrate,fs,mean_frame_size;
struct AUDIO_HEADER tmp;
	memcpy(&tmp,header,sizeof(tmp));

	while (cnt < nframes) {
		/* ffwd/rew functions are to be called right after the header has been parsed
		 * so we have to go back one frame + 4 bytes + 1 byte (in case padding was used).
		 */
	        bitrate=t_bitrate[tmp.ID][3-tmp.layer][tmp.bitrate_index];
        	fs=t_sampling_frequency[tmp.ID][tmp.sampling_frequency];		
	        if (tmp.ID) mean_frame_size=144000*bitrate/fs;
	        else mean_frame_size=72000*bitrate/fs;

		if (rewind_stream(mean_frame_size) !=0) {
			memcpy(header,&tmp,sizeof(tmp));
			return cnt;
		}
		if ((gethdr(&tmp))) return -1; 
		cnt++;
	}
	/* We have to make sure that the bit reservoir contains enough data.
	 * Hopefully, layer3_frame will take care of that.
	 */
	f_bdirty=TRUE;
	bclean_bytes=0;

	memcpy(header,&tmp,sizeof(tmp));		
	return cnt;
}

/* TODO: after the gethdr function is enhanced with the counter to count
 * the number of bytes to search for the next syncword, make the call to
 * gethdr() from rew() have that counter something like (frame_size-1) so
 * that we don't go back again and again to the same header. (not very important)
 */

--- NEW FILE: audioIO.h ---
/* AUSUZ should be the amount of data your audio device will accept after it
 * has said it is ready to receive data. ie when the device is ready for data it
 * will accept it without blocking. It must also be a multiple of 128
 */

#ifdef OS_AIX
  #define AUSIZ 32768
#endif

#ifdef OS_Linux
extern int AUSIZ;
#endif

#ifdef OS_BSD
  #define AUSIZ 32768
#endif

#if defined(OS_IRIX) || defined(OS_IRIX64)
  #define AUSIZ 32768
#endif

#ifdef OS_HPUX
  #define AUSIZ 4096
#endif

#ifdef OS_SunOS
  #define AUSIZ 4096
#endif

--- NEW FILE: config.h.in ---
/* config.h.in.  Generated automatically from configure.in by autoheader.  */

/* Define to empty if the keyword does not work.  */
#undef const

/* Define if you don't have vprintf but do have _doprnt.  */
#undef HAVE_DOPRNT

/* Define if you have <sys/wait.h> that is POSIX.1 compatible.  */
#undef HAVE_SYS_WAIT_H

/* Define if you have the vprintf function.  */
#undef HAVE_VPRINTF

/* Define as __inline if that's what the C compiler calls it.  */
#undef inline

/* Define to `long' if <sys/types.h> doesn't define.  */
#undef off_t

/* Define if you have the ANSI C header files.  */
#undef STDC_HEADERS

/* Define if you can safely include both <sys/time.h> and <time.h>.  */
#undef TIME_WITH_SYS_TIME

/* Define if you have the select function.  */
#undef HAVE_SELECT

/* Define if you have the <fcntl.h> header file.  */
#undef HAVE_FCNTL_H

/* Define if you have the <sys/ioctl.h> header file.  */
#undef HAVE_SYS_IOCTL_H

/* Define if you have the <sys/time.h> header file.  */
#undef HAVE_SYS_TIME_H

/* Define if you have the <unistd.h> header file.  */
#undef HAVE_UNISTD_H

--- NEW FILE: transform.h ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/
 
/* transform.h  tables galore
 *
 * Created by: tomislav uzelac  May 1996
 * Last modified by: tomislav uzelac  Mar  1 97
 */
extern void imdct_init();
extern void imdct(int win_type,int sb,int ch);
extern void poly(int ch,int i);
extern void premultiply();

extern short sample_buffer[18][32][2];
extern float res[32][18];
extern float s[2][32][18];

#ifdef TRANSFORM

void imdct_init();
void imdct(int win_type,int sb,int ch);
void poly(int ch,int i);
void premultiply();

short sample_buffer[18][32][2];
float s[2][32][18];
float res[32][18];
float win[4][36];

static const float t_sin[4][36]={{
   -0.032160,    0.103553,   -0.182543,    0.266729,   -0.353554,    0.440377,
   -0.524563,    0.603553,   -0.674947,    0.736575,   -0.786566,    0.823400,
   -0.845957,    0.853554,   -0.845957,    0.823399,   -0.786566,    0.736575,
   -0.674947,    0.603553,   -0.524564,    0.440378,   -0.353553,    0.266729,
   -0.182544,    0.103553,   -0.032160,   -0.029469,    0.079459,   -0.116293,
    0.138851,   -0.146446,    0.138851,   -0.116293,    0.079459,   -0.029469
},{
   -0.032160,    0.103553,   -0.182543,    0.266729,   -0.353554,    0.440377,
   -0.524563,    0.603553,   -0.674947,    0.736575,   -0.786566,    0.823400,
   -0.845957,    0.853554,   -0.845957,    0.823399,   -0.786566,    0.736575,
   -0.675590,    0.608761,   -0.537300,    0.461749,   -0.382683,    0.300706,
   -0.214588,    0.120590,   -0.034606,   -0.026554,    0.049950,   -0.028251,
    0.000000,    0.000000,    0.000000,    0.000000,    0.000000,    0.000000
},{
   -0.103553,    0.353554,   -0.603553,    0.786566,   -0.853554,    0.786566,
   -0.603553,    0.353553,   -0.103553,   -0.079459,    0.146446,   -0.079459,
    0.000000,    0.000000,    0.000000,    0.000000,    0.000000,    0.000000,
    0.000000,    0.000000,    0.000000,    0.000000,    0.000000,    0.000000,
    0.000000,    0.000000,    0.000000,    0.000000,    0.000000,    0.000000,
    0.000000,    0.000000,    0.000000,    0.000000,    0.000000,    0.000000
},{
    0.000000,    0.000000,    0.000000,    0.000000,    0.000000,    0.000000,
   -0.127432,    0.379410,   -0.608182,    0.792598,   -0.915976,    0.967944,
   -0.953717,    0.923880,   -0.887011,    0.843391,   -0.793353,    0.737277,
   -0.674947,    0.603553,   -0.524564,    0.440378,   -0.353553,    0.266729,
   -0.182544,    0.103553,   -0.032160,   -0.029469,    0.079459,   -0.116293,
    0.138851,   -0.146446,    0.138851,   -0.116293,    0.079459,   -0.029469
}};

static const float t_2cos[4][18]={
{ -0.174311,  -0.517638,  -0.845237,  -1.147153,  -1.414214,  -1.638304, -1.812616,  -1.931852,  -1.992389,  
   0.174311,   0.517638,   0.845237,   1.147153,   1.414214,   1.638304, 1.812616,   1.931852,   1.992389},
{ -0.174311,  -0.517638,  -0.845237,  -1.147153,  -1.414214,  -1.638304, -1.812616,  -1.931852,  -1.992389,
   0.174311,   0.517638,   0.845237,   1.147153,   1.414214,   1.638304, 1.812616,   1.931852,   1.992389},
{ -0.517638, -1.41421, -1.93185, 0.517638, 1.41421, 1.93185,0,0,0,0,0,0,0,0,0,0,0,0},
{ -0.174311,  -0.517638,  -0.845237,  -1.147153,  -1.414214,  -1.638304, -1.812616,  -1.931852,  -1.992389,
   0.174311,   0.517638,   0.845237,   1.147153,   1.414214,   1.638304, 1.812616,   1.931852,   1.992389}
};

static const float b1 = 1.997590912; static const float b2 = 1.990369453; static const float b3 = 1.978353019;
static const float b4 = 1.961570560; static const float b5 = 1.940062506; static const float b6 = 1.913880671;
static const float b7 = 1.883088130; static const float b8 = 1.847759065; static const float b9 = 1.807978586;
static const float b10= 1.763842529; static const float b11= 1.715457220; static const float b12= 1.662939225;
static const float b13= 1.606415063; static const float b14= 1.546020907; static const float b15= 1.481902251;
static const float b16= 1.414213562; static const float b17= 1.343117910; static const float b18= 1.268786568;
static const float b19= 1.191398609; static const float b20= 1.111140466; static const float b21= 1.028205488;
static const float b22= 0.942793474; static const float b23= 0.855110187; static const float b24= 0.765366865;
static const float b25= 0.673779707; static const float b26= 0.580569355; static const float b27= 0.485960360;
static const float b28= 0.390180644; static const float b29= 0.293460949; static const float b30= 0.196034281;
static const float b31= 0.098135349;

static float t_dewindow[17][32] =	{{
 0.000000000 ,-0.000442505 , 0.003250122 ,-0.007003784 , 0.031082153 ,-0.078628540 , 0.100311279 ,-0.572036743 ,
 1.144989014 , 0.572036743 , 0.100311279 , 0.078628540 , 0.031082153 , 0.007003784 , 0.003250122 , 0.000442505 ,
 0.000000000 ,-0.000442505 , 0.003250122 ,-0.007003784 , 0.031082153 ,-0.078628540 , 0.100311279 ,-0.572036743 ,
 1.144989014 , 0.572036743 , 0.100311279 , 0.078628540 , 0.031082153 , 0.007003784 , 0.003250122 , 0.000442505 ,
},{
-0.000015259 ,-0.000473022 , 0.003326416 ,-0.007919312 , 0.030517578 ,-0.084182739 , 0.090927124 ,-0.600219727 ,
 1.144287109 , 0.543823242 , 0.108856201 , 0.073059082 , 0.031478882 , 0.006118774 , 0.003173828 , 0.000396729 ,
-0.000015259 ,-0.000473022 , 0.003326416 ,-0.007919312 , 0.030517578 ,-0.084182739 , 0.090927124 ,-0.600219727 ,
 1.144287109 , 0.543823242 , 0.108856201 , 0.073059082 , 0.031478882 , 0.006118774 , 0.003173828 , 0.000396729 ,
},{
-0.000015259 ,-0.000534058 , 0.003387451 ,-0.008865356 , 0.029785156 ,-0.089706421 , 0.080688477 ,-0.628295898 ,
 1.142211914 , 0.515609741 , 0.116577148 , 0.067520142 , 0.031738281 , 0.005294800 , 0.003082275 , 0.000366211 ,
-0.000015259 ,-0.000534058 , 0.003387451 ,-0.008865356 , 0.029785156 ,-0.089706421 , 0.080688477 ,-0.628295898 ,
 1.142211914 , 0.515609741 , 0.116577148 , 0.067520142 , 0.031738281 , 0.005294800 , 0.003082275 , 0.000366211 ,
},{
-0.000015259 ,-0.000579834 , 0.003433228 ,-0.009841919 , 0.028884888 ,-0.095169067 , 0.069595337 ,-0.656219482 ,
 1.138763428 , 0.487472534 , 0.123474121 , 0.061996460 , 0.031845093 , 0.004486084 , 0.002990723 , 0.000320435 ,
-0.000015259 ,-0.000579834 , 0.003433228 ,-0.009841919 , 0.028884888 ,-0.095169067 , 0.069595337 ,-0.656219482 ,
 1.138763428 , 0.487472534 , 0.123474121 , 0.061996460 , 0.031845093 , 0.004486084 , 0.002990723 , 0.000320435 ,
},{
-0.000015259 ,-0.000625610 , 0.003463745 ,-0.010848999 , 0.027801514 ,-0.100540161 , 0.057617187 ,-0.683914185 ,
 1.133926392 , 0.459472656 , 0.129577637 , 0.056533813 , 0.031814575 , 0.003723145 , 0.002899170 , 0.000289917 ,
-0.000015259 ,-0.000625610 , 0.003463745 ,-0.010848999 , 0.027801514 ,-0.100540161 , 0.057617187 ,-0.683914185 ,
 1.133926392 , 0.459472656 , 0.129577637 , 0.056533813 , 0.031814575 , 0.003723145 , 0.002899170 , 0.000289917 ,
},{
-0.000015259 ,-0.000686646 , 0.003479004 ,-0.011886597 , 0.026535034 ,-0.105819702 , 0.044784546 ,-0.711318970 ,
 1.127746582 , 0.431655884 , 0.134887695 , 0.051132202 , 0.031661987 , 0.003005981 , 0.002792358 , 0.000259399 ,
-0.000015259 ,-0.000686646 , 0.003479004 ,-0.011886597 , 0.026535034 ,-0.105819702 , 0.044784546 ,-0.711318970 ,
 1.127746582 , 0.431655884 , 0.134887695 , 0.051132202 , 0.031661987 , 0.003005981 , 0.002792358 , 0.000259399 ,
},{
-0.000015259 ,-0.000747681 , 0.003479004 ,-0.012939453 , 0.025085449 ,-0.110946655 , 0.031082153 ,-0.738372803 ,
 1.120223999 , 0.404083252 , 0.139450073 , 0.045837402 , 0.031387329 , 0.002334595 , 0.002685547 , 0.000244141 ,
-0.000015259 ,-0.000747681 , 0.003479004 ,-0.012939453 , 0.025085449 ,-0.110946655 , 0.031082153 ,-0.738372803 ,
 1.120223999 , 0.404083252 , 0.139450073 , 0.045837402 , 0.031387329 , 0.002334595 , 0.002685547 , 0.000244141 ,
},{
-0.000030518 ,-0.000808716 , 0.003463745 ,-0.014022827 , 0.023422241 ,-0.115921021 , 0.016510010 ,-0.765029907 ,
 1.111373901 , 0.376800537 , 0.143264771 , 0.040634155 , 0.031005859 , 0.001693726 , 0.002578735 , 0.000213623 ,
-0.000030518 ,-0.000808716 , 0.003463745 ,-0.014022827 , 0.023422241 ,-0.115921021 , 0.016510010 ,-0.765029907 ,
 1.111373901 , 0.376800537 , 0.143264771 , 0.040634155 , 0.031005859 , 0.001693726 , 0.002578735 , 0.000213623 ,
},{
-0.000030518 ,-0.000885010 , 0.003417969 ,-0.015121460 , 0.021575928 ,-0.120697021 , 0.001068115 ,-0.791213989 ,
 1.101211548 , 0.349868774 , 0.146362305 , 0.035552979 , 0.030532837 , 0.001098633 , 0.002456665 , 0.000198364 ,
-0.000030518 ,-0.000885010 , 0.003417969 ,-0.015121460 , 0.021575928 ,-0.120697021 , 0.001068115 ,-0.791213989 ,
 1.101211548 , 0.349868774 , 0.146362305 , 0.035552979 , 0.030532837 , 0.001098633 , 0.002456665 , 0.000198364 ,
},{
-0.000030518 ,-0.000961304 , 0.003372192 ,-0.016235352 , 0.019531250 ,-0.125259399 ,-0.015228271 ,-0.816864014 ,
 1.089782715 , 0.323318481 , 0.148773193 , 0.030609131 , 0.029937744 , 0.000549316 , 0.002349854 , 0.000167847 ,
-0.000030518 ,-0.000961304 , 0.003372192 ,-0.016235352 , 0.019531250 ,-0.125259399 ,-0.015228271 ,-0.816864014 ,
 1.089782715 , 0.323318481 , 0.148773193 , 0.030609131 , 0.029937744 , 0.000549316 , 0.002349854 , 0.000167847 ,
},{
-0.000030518 ,-0.001037598 , 0.003280640 ,-0.017349243 , 0.017257690 ,-0.129562378 ,-0.032379150 ,-0.841949463 ,
 1.077117920 , 0.297210693 , 0.150497437 , 0.025817871 , 0.029281616 , 0.000030518 , 0.002243042 , 0.000152588 ,
-0.000030518 ,-0.001037598 , 0.003280640 ,-0.017349243 , 0.017257690 ,-0.129562378 ,-0.032379150 ,-0.841949463 ,
 1.077117920 , 0.297210693 , 0.150497437 , 0.025817871 , 0.029281616 , 0.000030518 , 0.002243042 , 0.000152588 ,
},{
-0.000045776 ,-0.001113892 , 0.003173828 ,-0.018463135 , 0.014801025 ,-0.133590698 ,-0.050354004 ,-0.866363525 ,
 1.063217163 , 0.271591187 , 0.151596069 , 0.021179199 , 0.028533936 ,-0.000442505 , 0.002120972 , 0.000137329 ,
-0.000045776 ,-0.001113892 , 0.003173828 ,-0.018463135 , 0.014801025 ,-0.133590698 ,-0.050354004 ,-0.866363525 ,
 1.063217163 , 0.271591187 , 0.151596069 , 0.021179199 , 0.028533936 ,-0.000442505 , 0.002120972 , 0.000137329 ,
},{
-0.000045776 ,-0.001205444 , 0.003051758 ,-0.019577026 , 0.012115479 ,-0.137298584 ,-0.069168091 ,-0.890090942 ,
 1.048156738 , 0.246505737 , 0.152069092 , 0.016708374 , 0.027725220 ,-0.000869751 , 0.002014160 , 0.000122070 ,
-0.000045776 ,-0.001205444 , 0.003051758 ,-0.019577026 , 0.012115479 ,-0.137298584 ,-0.069168091 ,-0.890090942 ,
 1.048156738 , 0.246505737 , 0.152069092 , 0.016708374 , 0.027725220 ,-0.000869751 , 0.002014160 , 0.000122070 ,
},{
-0.000061035 ,-0.001296997 , 0.002883911 ,-0.020690918 , 0.009231567 ,-0.140670776 ,-0.088775635 ,-0.913055420 ,
 1.031936646 , 0.221984863 , 0.151962280 , 0.012420654 , 0.026840210 ,-0.001266479 , 0.001907349 , 0.000106812 ,
-0.000061035 ,-0.001296997 , 0.002883911 ,-0.020690918 , 0.009231567 ,-0.140670776 ,-0.088775635 ,-0.913055420 ,
 1.031936646 , 0.221984863 , 0.151962280 , 0.012420654 , 0.026840210 ,-0.001266479 , 0.001907349 , 0.000106812 ,
},{
-0.000061035 ,-0.001388550 , 0.002700806 ,-0.021789551 , 0.006134033 ,-0.143676758 ,-0.109161377 ,-0.935195923 ,
 1.014617920 , 0.198059082 , 0.151306152 , 0.008316040 , 0.025909424 ,-0.001617432 , 0.001785278 , 0.000106812 ,
-0.000061035 ,-0.001388550 , 0.002700806 ,-0.021789551 , 0.006134033 ,-0.143676758 ,-0.109161377 ,-0.935195923 ,
 1.014617920 , 0.198059082 , 0.151306152 , 0.008316040 , 0.025909424 ,-0.001617432 , 0.001785278 , 0.000106812 ,
},{
-0.000076294 ,-0.001480103 , 0.002487183 ,-0.022857666 , 0.002822876 ,-0.146255493 ,-0.130310059 ,-0.956481934 ,
 0.996246338 , 0.174789429 , 0.150115967 , 0.004394531 , 0.024932861 ,-0.001937866 , 0.001693726 , 0.000091553 ,
-0.000076294 ,-0.001480103 , 0.002487183 ,-0.022857666 , 0.002822876 ,-0.146255493 ,-0.130310059 ,-0.956481934 ,
 0.996246338 , 0.174789429 , 0.150115967 , 0.004394531 , 0.024932861 ,-0.001937866 , 0.001693726 , 0.000091553 ,
},{
-0.000076294 ,-0.001586914 , 0.002227783 ,-0.023910522 ,-0.000686646 ,-0.148422241 ,-0.152206421 ,-0.976852417 ,
 0.976852417 , 0.152206421 , 0.148422241 , 0.000686646 , 0.023910522 ,-0.002227783 , 0.001586914 , 0.000076294 ,
-0.000076294 ,-0.001586914 , 0.002227783 ,-0.023910522 ,-0.000686646 ,-0.148422241 ,-0.152206421 ,-0.976852417 ,
 0.976852417 , 0.152206421 , 0.148422241 , 0.000686646 , 0.023910522 ,-0.002227783 , 0.001586914 , 0.000076294 ,
}			};
#endif /* TRANSFORM */

--- NEW FILE: buffer.c ---
/* this file is a part of amp software

   buffer.c: written by Andrew Richards  <A.Richards at phys.canterbury.ac.nz>
             (except printout())

   Last modified by:
   Karl Anders Oygard added flushing of audio buffers, 13 May 1997

*/
#include "amp.h"
#include "transform.h"

#include <sys/types.h>
#include <sys/signal.h>
#ifdef HAVE_MLOCK
#ifdef OS_Linux
#include <sys/mman.h>
#endif
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "audioIO.h"
#include "audio.h"

#if !defined(OS_Linux) && !defined(AUSIZ)
#define AUSIZ 32768
#endif

struct ringBuffer {		/* A ring buffer to store the data in */
	char *bufferPtr;	/* buffer pointer */
	int inPos, outPos;	/* positions for reading and writing */
};


static int buffer_fd;
static int control_fd;

/* little endian systems do not require any byte swapping whatsoever. 
 * big endian systems require byte swapping when writing .wav files, 
 * but not when playing directly
 */

/* This is a separate (but inlined) function to make it easier to implement */
/* a threaded buffer */

inline void audioBufferWrite(char *buf,int bytes)
{
        write(buffer_fd, buf, bytes);
}

void printout(void)
{
int j;

        if (nch==2)
                j=32 * 18 * 2;
        else
                j=32 * 18;

       if (AUDIO_BUFFER_SIZE==0)
               audioWrite((char*)sample_buffer, j * sizeof(short));
       else
               audioBufferWrite((char*)sample_buffer, j * sizeof(short));
}

int AUDIO_BUFFER_SIZE;

#define bufferSize(A) (((A)->inPos+AUDIO_BUFFER_SIZE-(A)->outPos) % AUDIO_BUFFER_SIZE)
#define bufferFree(A) (AUDIO_BUFFER_SIZE-1-bufferSize(A))

void 
initBuffer(struct ringBuffer *buffer)
{
	buffer->bufferPtr=malloc(AUDIO_BUFFER_SIZE);
	if (buffer->bufferPtr==NULL) 
		_exit(-1);
#ifdef HAVE_MLOCK
	mlock(buffer->bufferPtr,AUDIO_BUFFER_SIZE);
#endif
	buffer->inPos = 0;
	buffer->outPos = 0;
}

void
freeBuffer(struct ringBuffer *buffer)
{
#ifdef HAVE_MLOCK
  munlock(buffer->bufferPtr,AUDIO_BUFFER_SIZE);
#endif
	free(buffer->bufferPtr);
}

/* This just sends some bogus data on the control pipe, which will cause */
/* the reader to flush its buffer. */

void
audioBufferFlush()
{
	if (AUDIO_BUFFER_SIZE!=0) 
	{
		int dummy;

		/* We could use the control pipe for passing commands to the */
		/* audio player process, but so far we haven't bothered. */

        	write(control_fd, &dummy, sizeof dummy);
	} else
		audioFlush();
}


/* The decoded data are stored in a the ring buffer until they can be sent */
/* to the audio device. Variables are named in relation to the buffer */
/* ie writes are writes from the codec to the buffer and reads are reads */
/* from the buffer to the audio device */

int
audioBufferOpen(int frequency, int stereo, int volume)
{
	struct ringBuffer audioBuffer;
	
	int inFd,outFd,ctlFd,cnt,pid;
	int inputFinished=FALSE;
	int percentFull;
	fd_set inFdSet,outFdSet;
	fd_set *outFdPtr; 
	struct timeval timeout;
	int filedes[2];
	int controldes[2];
	
	
	if (pipe(filedes) || pipe(controldes)) 
	{
		perror("pipe");
		exit(-1);
	}
	if ((pid=fork())!=0) 
	{  
		/* if we are the parent */
		control_fd=controldes[1];
		close(filedes[0]);
		buffer_fd=filedes[1];
		close(controldes[0]);
		return(pid);	        /* return the pid */
	}
	
	
	/* we are the child */
	close(filedes[1]);
	inFd=filedes[0];
	close(controldes[1]);
	ctlFd=controldes[0];
	audioOpen(frequency,stereo,volume);
	outFd=getAudioFd();
	initBuffer(&audioBuffer);
	
	while(1) 
	{
		timeout.tv_sec=0;
		timeout.tv_usec=0;
		FD_ZERO(&inFdSet);
		FD_ZERO(&outFdSet);
		FD_SET(ctlFd,&inFdSet);
		FD_SET(outFd,&outFdSet);
		
		if (bufferSize(&audioBuffer)<AUSIZ) 
		{					/* is the buffer too empty */
			outFdPtr = NULL;		/* yes, don't try to write */
			if (inputFinished)		/* no more input, buffer exhausted -> exit */
				break;
		} else
			outFdPtr=&outFdSet;															/* no, select on write */
		
		/* check we have at least AUSIZ bytes left (don't want <1k bits) */
		if ((bufferFree(&audioBuffer)>=AUSIZ) && !inputFinished)
			FD_SET(inFd,&inFdSet);

/* The following selects() are basically all that is left of the system
   dependent code outside the audioIO_*&c files. These selects really
   need to be moved into the audioIO_*.c files and replaced with a
   function like audioIOReady(inFd, &checkIn, &checkAudio, wait) where
   it checks the status of the input or audio output if checkIn or
   checkAudio are set and returns with checkIn or checkAudio set to TRUE
   or FALSE depending on whether or not data is available. If wait is
   FALSE the function should return immediately, if wait is TRUE the
   process should BLOCK until the required condition is met. NB: The
   process MUST relinquish the CPU during this check or it will gobble
   up all the available CPU which sort of defeats the purpose of the
   buffer.

   This is tricky for people who don't have file descriptors (and
   select) to do the job. In that case a buffer implemented using
   threads should work. The way things are set up now a threaded version
   shouldn't be to hard to implement. When I get some time... */

		/* check if we can read or write */
		if (select(MAX3(inFd,outFd,ctlFd)+1,&inFdSet,outFdPtr,NULL,NULL) > -1) 
		{
			if (outFdPtr && FD_ISSET(outFd,outFdPtr)) 
			{							/* need to write */
				int bytesToEnd = AUDIO_BUFFER_SIZE - audioBuffer.outPos;

				percentFull=100*bufferSize(&audioBuffer)/AUDIO_BUFFER_SIZE;
				if (AUSIZ>bytesToEnd) 
				{
					cnt = audioWrite(audioBuffer.bufferPtr + audioBuffer.outPos, bytesToEnd);
					cnt += audioWrite(audioBuffer.bufferPtr, AUSIZ - bytesToEnd);
					audioBuffer.outPos = AUSIZ - bytesToEnd;
				} 
				else 
				{
					cnt = audioWrite(audioBuffer.bufferPtr + audioBuffer.outPos, AUSIZ);
					audioBuffer.outPos += AUSIZ;
				}

			}
			if (FD_ISSET(inFd,&inFdSet)) 
			{								 /* need to read */
			        cnt = read(inFd, audioBuffer.bufferPtr + audioBuffer.inPos, MIN(AUSIZ, AUDIO_BUFFER_SIZE - audioBuffer.inPos));
				if (cnt >= 0) 
				{
					audioBuffer.inPos = (audioBuffer.inPos + cnt) % AUDIO_BUFFER_SIZE;

					if (cnt==0)
						inputFinished=TRUE;
				} 
				else 
					_exit(-1);
			}
			if (FD_ISSET(ctlFd,&inFdSet)) 
			{
				int dummy;

			        cnt = read(ctlFd, &dummy, sizeof dummy);
				if (cnt >= 0) 
				{
					audioBuffer.inPos = audioBuffer.outPos = 0;
					audioFlush();
				} 
				else 
					_exit(-1);
			}
		} 
		else 
			_exit(-1);
	}
	close(inFd);
	audioClose();
	exit(0);
	return 0; /* just to get rid of warnings */
}

void
audioBufferClose()
{
	/* Close the buffer pipe and wait for the buffer process to close */
	close(buffer_fd);
	waitpid(0,0,0);
}

--- NEW FILE: getbits.h ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/
 
/* getbits.h
 *
 * Created by: tomislav uzelac  Apr 1996
 */

/* gethdr() error codes
*/
#define GETHDR_ERR 0x1
#define GETHDR_NS  0x2
#define GETHDR_FL1 0x4
#define GETHDR_FL2 0x8
#define GETHDR_FF  0x10
#define GETHDR_SYN 0x20
#define GETHDR_EOF 0x30

/* buffer for the 'bit reservoir'
*/
#define BUFFER_SIZE     4096
#define BUFFER_AUX      2048
extern unsigned char buffer[];
extern int append,data,f_bdirty,bclean_bytes;
  
/* exports
*/
extern int fillbfr(unsigned int advance);
extern unsigned int getbits(int n);
extern int gethdr(struct AUDIO_HEADER *header);
extern void getcrc();
extern void getinfo(struct AUDIO_HEADER *header,struct SIDE_INFO *info);
extern int dummy_getinfo(int n);
extern int rewind_stream(int nbytes);


#ifdef GETBITS

/* buffer, AUX is used in case of input buffer "overflow", and its contents
 * are copied to the beginning of the buffer
*/
unsigned char buffer[BUFFER_SIZE+BUFFER_AUX+1];

/* buffer pointers: append counts in bytes, data in bits
 */
int append,data;

/* bit reservoir stuff. f_bdirty must be set to TRUE when starting play!
 */
int f_bdirty,bclean_bytes;
 
/* internal buffer, _bptr holds the position in _bits_
 */
static unsigned char _buffer[32];
static int _bptr;


/* buffer and bit manipulation functions
 */
static inline int _fillbfr(unsigned int size);
static inline int readsync();
static inline int get_input(unsigned char* bp, unsigned int size);
static inline unsigned int _getbits(int n);
int fillbfr(unsigned int advance);
unsigned int getbits(int n);
int dummy_getinfo(int n);
int rewind_stream(int nbytes);

/* header and side info parsing stuff 
 */
static inline void parse_header(struct AUDIO_HEADER *header);
static inline int header_sanity_check(struct AUDIO_HEADER *header);

int gethdr(struct AUDIO_HEADER *header);
void getcrc();
void getinfo(struct AUDIO_HEADER *header,struct SIDE_INFO *info);  

#endif /* GETBITS */


--- NEW FILE: getbits.c ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/
 
/* getbits.c  bit level routines, input buffer
 * 
 * Created by: tomislav uzelac  Apr 1996 
 * better synchronization, tomislav uzelac, Apr 23 1997
 */
#include "amp.h"
#include "audio.h"

#define	GETBITS
#include "getbits.h"

#include <string.h>

/* 
 * buffer and bit manipulation functions ***************************************
 */
static inline int _fillbfr(unsigned int size)
{
	_bptr=0;
        return get_input(_buffer, size);
}

static inline int readsync()
{
	_bptr=0;
	_buffer[0]=_buffer[1];
	_buffer[1]=_buffer[2];
	_buffer[2]=_buffer[3];
	return get_input(&_buffer[3],1);
}

static inline unsigned int _getbits(int n)
{
unsigned int pos,ret_value;

        pos = _bptr >> 3;
	ret_value = _buffer[pos] << 24 |
		    _buffer[pos+1] << 16 |
		    _buffer[pos+2] << 8 |
		    _buffer[pos+3];
        ret_value <<= _bptr & 7;
        ret_value >>= 32 - n;
        _bptr += n;
        return ret_value;
}       

int fillbfr(unsigned int advance)
{
int overflow,retval;

        retval=get_input(&buffer[append], advance);
	
	if ( append + advance >= BUFFER_SIZE) {
		overflow = append + advance - BUFFER_SIZE;
		memcpy (buffer,&buffer[BUFFER_SIZE], overflow);
		if (overflow < 4) memcpy(&buffer[BUFFER_SIZE],buffer,4);
		append = overflow;
	} else {
		if (append==0) memcpy(&buffer[BUFFER_SIZE],buffer,4);
		append+=advance;
	}
	return retval;
}

unsigned int getbits(int n)
{
        if (n) {
        unsigned int pos,ret_value;

                pos = data >> 3;
                ret_value = buffer[pos] << 24 |
                        buffer[pos+1] << 16 |
                        buffer[pos+2] << 8 |
                        buffer[pos+3];
                ret_value <<= data & 7;
                ret_value >>= 32 - n;

                data += n;
                data &= (8*BUFFER_SIZE)-1;

                return ret_value;
        } else
                return 0;
}

/*
 * header and side info parsing stuff ******************************************
 */
static inline void parse_header(struct AUDIO_HEADER *header) 
{
        header->ID=_getbits(1);
        header->layer=_getbits(2);
        header->protection_bit=_getbits(1);
        header->bitrate_index=_getbits(4);
        header->sampling_frequency=_getbits(2);
        header->padding_bit=_getbits(1);
        header->private_bit=_getbits(1);
        header->mode=_getbits(2);
        header->mode_extension=_getbits(2);
        if (!header->mode) header->mode_extension=0;
        header->copyright=_getbits(1);
        header->original=_getbits(1);
        header->emphasis=_getbits(2);
}

static inline int header_sanity_check(struct AUDIO_HEADER *header)
{
	if ( 	header->layer==0 ||
		header->bitrate_index==15 ||
		header->sampling_frequency==3) return -1;

	/* an additional check to make shure that stuffing never gets mistaken
 	 * for a syncword. This rules out some legal layer1 streams, but who
 	 * cares about layer1 anyway :-). I must get this right sometime.
	 */
	if ( header->ID==1 && header->layer==3 && header->protection_bit==1) return -1;
	return 0;
}


int gethdr(struct AUDIO_HEADER *header)
{
int s,retval;
struct AUDIO_HEADER tmp;

	/* TODO: add a simple byte counter to check only first, say, 1024
	 * bytes for a new header and then return GETHDR_SYN
	 */
	if ((retval=_fillbfr(4))!=0) return retval;

	for(;;) {
		while ((s=_getbits(12)) != 0xfff) {
			if (s==0xffe) {
				parse_header(&tmp);
				if (header_sanity_check(&tmp)==0) return GETHDR_NS;
			}
			if ((retval=readsync())!=0) return retval;
		}
	
		parse_header(&tmp);
		if (header_sanity_check(&tmp)!=0) {
			if ((retval=readsync())!=0) return retval;
		} else break;
	}

	if (tmp.layer==3) return GETHDR_FL1;
	/* if (tmp.layer==2) return GETHDR_FL2; */
	if (tmp.bitrate_index==0) return GETHDR_FF;

	memcpy(header,&tmp,sizeof(tmp));
	return 0;
}

/* dummy function, to get crc out of the way
*/
void getcrc()
{
	_fillbfr(2);
	_getbits(16);
}

/* sizes of side_info:
 * MPEG1   1ch 17    2ch 32
 * MPEG2   1ch  9    2ch 17
 */
void getinfo(struct AUDIO_HEADER *header,struct SIDE_INFO *info)
{
int gr,ch,scfsi_band,region,window;
int nch;	
	if (header->mode==3) {
		nch=1;
		if (header->ID) {
			_fillbfr(17);
			info->main_data_begin=_getbits(9);
			_getbits(5);
		} else {
			_fillbfr(9);
			info->main_data_begin=_getbits(8);
			_getbits(1);
		}
	} else {
		nch=2;
                if (header->ID) {
			_fillbfr(32);
                        info->main_data_begin=_getbits(9);
                        _getbits(3);
                } else {
			_fillbfr(17);
                        info->main_data_begin=_getbits(8);
                        _getbits(2);
                }
	}

	if (header->ID) for (ch=0;ch<nch;ch++)
		for (scfsi_band=0;scfsi_band<4;scfsi_band++)
			info->scfsi[ch][scfsi_band]=_getbits(1);

	for (gr=0;gr<(header->ID ? 2:1);gr++)
		for (ch=0;ch<nch;ch++) {
			info->part2_3_length[gr][ch]=_getbits(12);
			info->big_values[gr][ch]=_getbits(9);
			info->global_gain[gr][ch]=_getbits(8);
			if (header->ID) info->scalefac_compress[gr][ch]=_getbits(4);
			else info->scalefac_compress[gr][ch]=_getbits(9);
			info->window_switching_flag[gr][ch]=_getbits(1);

			if (info->window_switching_flag[gr][ch]) {
				info->block_type[gr][ch]=_getbits(2);
				info->mixed_block_flag[gr][ch]=_getbits(1);

				for (region=0;region<2;region++)
					info->table_select[gr][ch][region]=_getbits(5);
				info->table_select[gr][ch][2]=0;

				for (window=0;window<3;window++)
					info->subblock_gain[gr][ch][window]=_getbits(3);
			} else {
				for (region=0;region<3;region++)
					info->table_select[gr][ch][region]=_getbits(5);

				info->region0_count[gr][ch]=_getbits(4);
				info->region1_count[gr][ch]=_getbits(3);
				info->block_type[gr][ch]=0;
			}

			if (header->ID) info->preflag[gr][ch]=_getbits(1);
			info->scalefac_scale[gr][ch]=_getbits(1);
			info->count1table_select[gr][ch]=_getbits(1);
		}
	return;
}

int dummy_getinfo(int n)
{
	n-=4;
        if ( fseek(in_file,n,SEEK_CUR) != 0)
	{
                if (feof(in_file)) 
                	return GETHDR_EOF;
                else 
                	return GETHDR_ERR;
	}
	return 0;
}

int rewind_stream(int nbytes)
{
	nbytes+=5;
	if (fseek(in_file, -nbytes, SEEK_CUR) != 0) 
	{
		/* what if we need to be at the very beginning? */
		nbytes--;
		if (fseek(in_file, -nbytes, SEEK_CUR) != 0) 
			return GETHDR_ERR;
	}
	return 0;
}

static inline int get_input(unsigned char* bp, unsigned int size)
{
#ifdef LINUX_REALTIME
        return prefetch_get_input(bp,size);
#else /* LINUX_REALTIME */
	if ( fread( bp , 1, size, in_file) != size) 
	{
                if (feof(in_file)) 
                	return GETHDR_EOF;
                else 
                	return GETHDR_ERR;
	}
	return 0;
#endif /* LINUX_REALTIME */
}

--- NEW FILE: transform.c ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/
 
/* transform.c  imdct and polyphase(DCT) transforms
 *
 * Created by: tomislav uzelac  May 1996
 * Karl Anders Oygard optimized this for speed, Mar 13 97
 * Some optimisations based on ideas from Michael Hipp's mpg123 package
 */

/*
 * Comments for this file:
 *
 * The polyphase algorithm is clearly the most cpu consuming part of mpeg 1
 * layer 3 decoding.  Thus, there has been some effort to optimise this
 * particular algorithm.  Currently, everything has been kept in straight C
 * with no assembler optimisations, but in order to provide efficient paths
 * for different architectures, alternative implementations of some
 * critical sections has been done.  You may want to experiment with these,
[...1484 lines suppressed...]
	u_div[ch]=u_div[ch] ? 0 : 1;

#if defined(PENTIUM_RDTSC)
	__asm__(".byte 0x0f,0x31" : "=a" (cnt2), "=d" (cnt4));
			
	if (cnt2-cnt1 < min_cycles) {
	  min_cycles = cnt2-cnt1;
	  /*printf("%d, %d cycles, %d\n", cnt3-cnt1, min_cycles, start);*/
	}
#endif
}

void premultiply()
{
  int i,t;

  for (i = 0; i < 17; ++i)
    for (t = 0; t < 32; ++t)
      t_dewindow[i][t] *= 16383.5f;
}

--- NEW FILE: layer2.h ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/
/* layer2.h
 * Tomislav Uzelac - cca. Feb 1996
 */


extern int layer2_frame(struct AUDIO_HEADER *header,int cnt);

#ifdef LAYER2

int layer2_frame(struct AUDIO_HEADER *header,int cnt);
float requantize_sample(unsigned short s4,unsigned short nlevels,float c,float d,float factor);
void convert_samplecode(unsigned int samplecode,unsigned int nlevels,unsigned short* sb_sample_buf);

char t_nbal0[27]={4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2};
char t_nbal1[30]={4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2};
char t_nbal2[8] ={4,4,3,3,3,3,3,3};
char t_nbal3[12]={4,4,3,3,3,3,3,3,3,3,3,3};
char t_nbalMPG2[30]={4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};

char t_alloc0[27][16] = {	/* table B.2a ISO/IEC 11172-3 */
{0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17},
{0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17},
{0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,17},
{0,1,2,17},
{0,1,2,17},
{0,1,2,17}};

char t_alloc1[30][16] = {        /* table B.2b ISO/IEC 11172-3 */
{0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17},
{0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17},
{0,1,3,5,6,7,8,9,10,11,12,13,14,15,16,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,3,4,5,6,17},
{0,1,2,17},
{0,1,2,17},
{0,1,2,17},
{0,1,2,17},
{0,1,2,17},
{0,1,2,17},
{0,1,2,17}};

char t_alloc2[8][16] = {       /* table B.2c ISO/IEC 11172-3 */
{0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16},
{0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16},
{0,1,2,4,5,6,7,127},
{0,1,2,4,5,6,7,127},
{0,1,2,4,5,6,7,127},
{0,1,2,4,5,6,7,127},
{0,1,2,4,5,6,7,127},
{0,1,2,4,5,6,7,127}};

char t_alloc3[12][16] = {       /* table B.2d ISO/IEC 11172-3 */
{0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16},
{0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16},
{0,1,2,4,5,6,7,127},
{0,1,2,4,5,6,7,127},
{0,1,2,4,5,6,7,127},
{0,1,2,4,5,6,7,127},
{0,1,2,4,5,6,7,127},
{0,1,2,4,5,6,7,127},
{0,1,2,4,5,6,7,127},
{0,1,2,4,5,6,7,127},
{0,1,2,4,5,6,7,127},
{0,1,2,4,5,6,7,127}};

char t_allocMPG2[30][16] = {	/* table B.1. ISO/IEC 13818-3 */
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
{0,1,2,4,5,6,7,8},
{0,1,2,4,5,6,7,8},
{0,1,2,4,5,6,7,8},
{0,1,2,4,5,6,7,8},
{0,1,2,4,5,6,7,8},
{0,1,2,4,5,6,7,8},
{0,1,2,4,5,6,7,8},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4},
{0,1,2,4}};

double t_scalefactor[64] = {
2.00000000000000, 1.58740105196820, 1.25992104989487,
1.00000000000000, 0.79370052598410, 0.62996052494744, 0.50000000000000,
0.39685026299205, 0.31498026247372, 0.25000000000000, 0.19842513149602,
0.15749013123686, 0.12500000000000, 0.09921256574801, 0.07874506561843,
0.06250000000000, 0.04960628287401, 0.03937253280921, 0.03125000000000,
0.02480314143700, 0.01968626640461, 0.01562500000000, 0.01240157071850,
0.00984313320230, 0.00781250000000, 0.00620078535925, 0.00492156660115,
0.00390625000000, 0.00310039267963, 0.00246078330058, 0.00195312500000,
0.00155019633981, 0.00123039165029, 0.00097656250000, 0.00077509816991,
0.00061519582514, 0.00048828125000, 0.00038754908495, 0.00030759791257,
0.00024414062500, 0.00019377454248, 0.00015379895629, 0.00012207031250,
0.00009688727124, 0.00007689947814, 0.00006103515625, 0.00004844363562,
0.00003844973907, 0.00003051757813, 0.00002422181781, 0.00001922486954,
0.00001525878906, 0.00001211090890, 0.00000961243477, 0.00000762939453,
0.00000605545445, 0.00000480621738, 0.00000381469727, 0.00000302772723,
0.00000240310869, 0.00000190734863, 0.00000151386361, 0.00000120155435,
1E-20};

double t_c[18] = { 0,
		 1.33333333333, 1.60000000000, 1.14285714286,
                 1.77777777777, 1.06666666666, 1.03225806452,
                 1.01587301587, 1.00787401575, 1.00392156863,
                 1.00195694716, 1.00097751711, 1.00048851979,
                 1.00024420024, 1.00012208522, 1.00006103888,
                 1.00003051851, 1.00001525902 };
                 
double t_d[18] = {0,
   0.500000000,  0.500000000,  0.250000000,  0.500000000,
   0.125000000,  0.062500000,  0.031250000,  0.015625000,
   0.007812500,  0.003906250,  0.001953125,  0.0009765625,
   0.00048828125,0.00024414063,0.00012207031,
   0.00006103516,0.00003051758 };

float t_dd[18]={ -1, -0.5, -0.5, -0.75, -0.5, -0.875, -0.9375, -0.96875, -0.984375,
-0.992188, -0.996094, -0.998047, -0.999023, -0.999512, -0.999756, -0.999878, -0.999939,
-0.999969};
   
char t_grouping[18]={0,3,5,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0};

/*
int t_nlevels[18] = {0,3,5,7,9,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535};
*/
int t_nlevels[18] = {0,3,7,7,15,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535};


float t_nli[18]={ 0, 0.5, 0.25, 0.25, 0.125, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125, 0.00390625,
0.00195313, 0.000976563, 0.000488281, 0.000244141, 0.00012207, 6.10352e-05, 3.05176e-05}; 

int t_bpc[18] = {0,5,7,3,10,4,5,6,7,8,9,10,11,12,13,14,15,16};

#endif /* LAYER2 */

--- NEW FILE: audio.h ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/

/* audio.h  some global variables
 *
 * Created by: tomislav uzelac Mar/Apr, Jul 96
 */

#include <stdio.h>

struct AUDIO_HEADER {
	int ID;
	int layer;
	int protection_bit;
	int bitrate_index;
	int sampling_frequency;
	int padding_bit;
	int private_bit;
	int mode;
	int mode_extension;
	int copyright;
	int original;
	int emphasis;
};

struct SIDE_INFO {
	int main_data_begin;
	int scfsi[2][4];
	int part2_3_length[2][2];
	int big_values[2][2];
	int global_gain[2][2];
	int scalefac_compress[2][2];
	int window_switching_flag[2][2];
	int block_type[2][2];
	int mixed_block_flag[2][2];
	int table_select[2][2][3];
	int subblock_gain[2][2][3];
	int region0_count[2][2];
	int region1_count[2][2];
	int preflag[2][2];
	int scalefac_scale[2][2];
	int count1table_select[2][2];
};


/* global stuff 
*/

extern FILE *in_file;

extern void statusDisplay(struct AUDIO_HEADER *header, int frameNo);
extern void initialise_globals(void);
extern void report_header_error(int err);

extern int scalefac_l[2][2][22];
extern int scalefac_s[2][2][13][3];
extern int t_b8_l[2][3][22];
extern int t_b8_s[2][3][13];
extern short t_bitrate[2][3][15];

extern int is[2][578];
extern float xr[2][32][18];

extern int *t_l,*t_s;
extern int nch;
extern int t_sampling_frequency[2][3];

extern int A_QUIET,A_SHOW_CNT;
extern int A_WRITE_TO_AUDIO;
extern short pcm_sample[64];
extern int A_AUDIO_PLAY;
extern int A_SET_VOLUME,A_SHOW_TIME;
extern int A_DOWNMIX;
extern int A_SHUFFLE;

extern int stop_flag;
extern int quit_flag;

/* ...
*/

#ifdef AUDIO

FILE *in_file;
 
int scalefac_l[2][2][22];
int scalefac_s[2][2][13][3];

int is[2][578];
float xr[2][32][18];

int *t_l,*t_s;
int nch;
int t_sampling_frequency[2][3] = {
{ 22050 , 24000 , 16000},
{ 44100 , 48000 , 32000}
};

/* GUI control stuff */
int send_fd;
int receive_fd;

int stop_flag;
int quit_flag;

int A_QUIET,A_SHOW_CNT;
int A_AUDIO_PLAY;
int A_SET_VOLUME, A_SHOW_TIME;
int A_SHUFFLE;
int A_DOWNMIX;

short pcm_sample[64];

short t_bitrate[2][3][15] = {{
{0,32,48,56,64,80,96,112,128,144,160,176,192,224,256},
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160},
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160}
},{
{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448},
{0,32,48,56,64,80,96,112,128,160,192,224,256,320,384},
{0,32,40,48,56,64,80,96,112,128,160,192,224,256,320}
}};

/* the last sfb is given implicitly on pg.28. of the standard. scalefactors 
 * for that one are 0, pretab also 
 */
/* leftmost index denotes ID, so first three tables are for MPEG2 (header->ID==0)
 * and the other three are for MPEG1 (header->ID==1)
 */
/* 22.05, 24, 16 */
int t_b8_l[2][3][22]={{ /* table B.8b ISO/IEC 11172-3 */
{5,11,17,23,29,35,43,53,65,79,95,115,139,167,199,237,283,335,395,463,521,575},
{5,11,17,23,29,35,43,53,65,79,95,113,135,161,193,231,277,331,393,463,539,575},
{5,11,17,23,29,35,43,53,65,79,95,115,139,167,199,237,283,335,395,463,521,575}
},{
{3,7,11,15,19,23,29,35,43,51,61,73,89,109,133,161,195,237,287,341,417,575},
{3,7,11,15,19,23,29,35,41,49,59,71,87,105,127,155,189,229,275,329,383,575},
{3,7,11,15,19,23,29,35,43,53,65,81,101,125,155,193,239,295,363,447,549,575}
}};   
int t_b8_s[2][3][13]={{ /* table B.8b ISO/IEC 11172-3 */
{3,7,11,17,23,31,41,55,73,99,131,173,191},
{3,7,11,17,25,35,47,61,79,103,135,179,191},
{3,7,11,17,25,35,47,61,79,103,133,173,191}
},{
{3,7,11,15,21,29,39,51,65,83,105,135,191},
{3,7,11,15,21,27,37,49,63,79,99,125,191},
{3,7,11,15,21,29,41,57,77,103,137,179,191}
}};

int  args(int argc,char **argv);
void initialise_decoder(void);
int decodeMPEG(struct AUDIO_HEADER *header);
void initialise_globals(void);
void report_header_error(int err);
int  setup_audio(struct AUDIO_HEADER *header);
void close_audio(void);
int ready_audio(void);

void play(char *inFileStr);

#endif /* AUDIO */


--- NEW FILE: layer3.h ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/

/* layer3.h
 *
 * Created by: tomislav uzelac  Mar  1 97
 * Last modified by:
 */

extern int layer3_frame(struct AUDIO_HEADER *header,int cnt);

#ifdef LAYER3

int layer3_frame(struct AUDIO_HEADER *header,int cnt);

#endif /* LAYER3 */

--- NEW FILE: audioIO_Linux.c ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997

	Origional code by: tomislav uzelac
	Modified by:
	* Dan Nelson - BSD mods.
	* Andrew Richards - moved code from audio.c and added mixer support etc

 */

/* Support for Linux and BSD sound devices */

#include "amp.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include "audioIO.h"

#ifdef HAVE_MACHINE_SOUNDCARD_H
#include <machine/soundcard.h>
#elif defined(HAVE_LINUX_SOUNDCARD_H)
#include <linux/soundcard.h>
#elif defined(HAVE_SYS_SOUNDCARD_H)
#include <sys/soundcard.h>
#else
#define NO_SOUNCARD_H
#endif

#ifndef NO_SOUNCARD_H
/* optimal fragment size */

int AUSIZ = 0;

/* declare these static to effectively isolate the audio device */

static int audio_fd;
static int mixer_fd;
static int volumeIoctl;

/* audioOpen() */
/* should open the audio device, perform any special initialization		 */
/* Set the frequency, no of channels and volume. Volume is only set if */
/* it is not -1 */

void
audioOpen(int frequency, int stereo, int volume)
{
	int supportedMixers, play_format=AFMT_S16_LE;

	if ((audio_fd = open ("/dev/dsp", O_WRONLY, 0)) == -1)
		die("Unable to open the audio device\n");

	if (ioctl(audio_fd, SNDCTL_DSP_SETFMT,&play_format) < 0)
		die("Unable to set required audio format\n");
	if ((mixer_fd=open("/dev/mixer",O_RDWR)) == -1)
		warn("Unable to open mixer device\n");

	if (ioctl(mixer_fd, SOUND_MIXER_READ_DEVMASK, &supportedMixers) == -1) {
		warn("Unable to get mixer info assuming master volume\n");
		volumeIoctl=SOUND_MIXER_WRITE_VOLUME;
	} else {
		if ((supportedMixers & SOUND_MASK_PCM) != 0)
			volumeIoctl=SOUND_MIXER_WRITE_PCM;
		else
			volumeIoctl=0;
	}

	/* Set 1 or 2 channels */
	stereo=(stereo ? 1 : 0);

	if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
		die("Unable to set stereo/mono\n");

	/* Set the output frequency */
	if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &frequency) < 0)
		die("Unable to set frequency: %d\n",frequency);

	if (volume != -1)
		audioSetVolume(volume);

	if (ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &AUSIZ) == -1)
		die("Unable to get fragment size\n");
}


/* audioSetVolume - only code this if your system can change the volume while */
/*									playing. sets the output volume 0-100 */

void
audioSetVolume(int volume)
{

	volume=(volume<<8)+volume;
	if ((mixer_fd != -1) && (volumeIoctl!=0))
		if (ioctl(mixer_fd, volumeIoctl, &volume) < 0)
			warn("Unable to set sound volume\n");
}


/* audioFlush() */
/* should flush the audio device */

inline void
audioFlush()
{

	if (ioctl(audio_fd, SNDCTL_DSP_RESET, 0) == -1)
		die("Unable to reset audio device\n");
}


/* audioClose() */
/* should close the audio device and perform any special shutdown */

void
audioClose()
{
	close(audio_fd);
	if (mixer_fd != -1)
		close(mixer_fd);
}


/* audioWrite */
/* writes count bytes from buffer to the audio device */
/* returns the number of bytes actually written */

inline int
audioWrite(char *buffer, int count)
{
	return(write(audio_fd,buffer,count));
}


/* Let buffer.c have the audio descriptor so it can select on it. This means	*/
/* that the program is dependent on a file descriptor to work. Should really */
/* move the select's etc (with inlines of course) in here so that this is the */
/* ONLY file which has hardware dependent audio stuff in it										*/

int
getAudioFd()
{
	return(audio_fd);
}
#endif

--- NEW FILE: layer2.c ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/

/* layer2.c   MPEG audio layer2 support
 *
 * Created by: Tomislav Uzelac  Mar 1996
 * merged with amp, May 19 1997
 */
#include "amp.h"
#include "audio.h"
#include "getbits.h"
#include "transform.h"

#define LAYER2
#include "layer2.h"

int layer2_frame(struct AUDIO_HEADER *header,int cnt)
{
int i,s,sb,ch,gr,bitrate,bound = 0;
char (*nbal)[] = &t_nbal0,(*bit_alloc_index)[][16] = &t_alloc0;

unsigned char allocation[2][32];
unsigned char scfsi[2][32];
float scalefactor[2][32][3];
float subband_sample[2][32][36];
int sblimit = 0,nlevels,grouping; 

float  c,d;
int no_of_bits,mpi;				
unsigned short sb_sample_buf[3];	

int hsize,fs,mean_frame_size;

	hsize=4;
	if (header->protection_bit==0) hsize+=2;

	bitrate=t_bitrate[header->ID][3-header->layer][header->bitrate_index];
        fs=t_sampling_frequency[header->ID][header->sampling_frequency];
        if (header->ID) mean_frame_size=144000*bitrate/fs;
        else mean_frame_size=72000*bitrate/fs;

	/* layers 1 and 2 do not have a 'bit reservoir'
	 */
	append=data=0;

	fillbfr(mean_frame_size + header->padding_bit - hsize);

	switch (header->mode)
		{
		case 0 : 
		case 2 : nch=2; bound=32; bitrate=bitrate/2;  
			break;
		case 3 : nch=1; bound=32; 
			break;
		case 1 : nch=2; bitrate=bitrate/2; bound=(header->mode_extension+1)*4; 
		}
		
	if (header->ID==1) switch (header->sampling_frequency) {
		case 0 : switch (bitrate)	/* 0 = 44.1 kHz */
				{
				case 56  :
				case 64  :
				case 80  : bit_alloc_index=&t_alloc0;
					   nbal=&t_nbal0;
					   sblimit=27;
					   break;
				case 96  :
				case 112 :
				case 128 :
				case 160 :
				case 192 : bit_alloc_index=&t_alloc1;
					   nbal=&t_nbal1;
					   sblimit=30;  
					   break;
				case 32  :
				case 48  : bit_alloc_index=&t_alloc2;
					   nbal=&t_nbal2;
					   sblimit=8;
					   break;
				default  : /*printf(" bit alloc info no gud ");*/
				}
				break;
		case 1 : switch (bitrate)	/* 1 = 48 kHz */
				{
				case 56  : 
				case 64  :
				case 80  :
				case 96  :
				case 112 :
				case 128 :
				case 160 :
				case 192 : bit_alloc_index=&t_alloc0;
					   nbal=&t_nbal0;
					   sblimit=27;
					   break;
				case 32  :
				case 48  : bit_alloc_index=&t_alloc2;
					   nbal=&t_nbal2;
					   sblimit=8;
					   break;
				default  : /*printf(" bit alloc info no gud ");*/
				}
				break;
		case 2 : switch (bitrate)	/* 2 = 32 kHz */
				{
			case 56  :
                        case 64  :
                        case 80  : bit_alloc_index=&t_alloc0;
                                   nbal=&t_nbal0;
                                   sblimit=27;
                                   break;
                        case 96  :
                        case 112 :
                        case 128 :
                        case 160 :
                        case 192 : bit_alloc_index=&t_alloc1;
                                   nbal=&t_nbal1;
                                   sblimit=30;
                                   break;
			case 32  :
			case 48  : bit_alloc_index=&t_alloc3;
                                   nbal=&t_nbal3;
                                   sblimit=12;
				   break;
			default  : /*printf("bit alloc info not ok\n");*/
			}
	                break;                                                    
		default  : /*printf("sampling freq. not ok/n");*/
	} else {
		bit_alloc_index=&t_allocMPG2;
		nbal=&t_nbalMPG2;
		sblimit=30;
	}

/*
 * bit allocation per subband per channel decoding *****************************
 */

	if (bound==32) bound=sblimit;	/* bound=32 means there is no intensity stereo */
	 
	for (sb=0;sb<bound;sb++)
		for (ch=0;ch<nch;ch++)
			allocation[ch][sb]=getbits((*nbal)[sb]);

	for (sb=bound;sb<sblimit;sb++)
		allocation[1][sb] = allocation[0][sb] = getbits((*nbal)[sb]);


/*
 * scfsi ***********************************************************************
 */

	for (sb=0;sb<sblimit;sb++)
		for (ch=0;ch<nch;ch++)
			if (allocation[ch][sb]!=0) scfsi[ch][sb]=getbits(2);
			else scfsi[ch][sb]=0;

/*
 * scalefactors ****************************************************************
 */

	for (sb=0;sb<sblimit;sb++)
	for (ch=0;ch<nch;ch++)
		if (allocation[ch][sb]!=0) {
			scalefactor[ch][sb][0]=t_scalefactor[getbits(6)];
			switch (scfsi[ch][sb])
			{
			case 0: scalefactor[ch][sb][1]=t_scalefactor[getbits(6)];
				scalefactor[ch][sb][2]=t_scalefactor[getbits(6)];
				break;
			case 1: scalefactor[ch][sb][2]=t_scalefactor[getbits(6)];
				scalefactor[ch][sb][1]=scalefactor[ch][sb][0];
				break;
			case 2: scalefactor[ch][sb][1]=scalefactor[ch][sb][0];
				scalefactor[ch][sb][2]=scalefactor[ch][sb][0];
				break;
			case 3: scalefactor[ch][sb][2]=t_scalefactor[getbits(6)];
				scalefactor[ch][sb][1]=scalefactor[ch][sb][2];
			}		 	
		} 
		else scalefactor[ch][sb][0]=scalefactor[ch][sb][1]=\
			scalefactor[ch][sb][2]=0.0;


/*
 * samples *********************************************************************
 */

	for (gr=0;gr<12;gr++) {
		/*
		 * normal ********************************
		 */
   	
		for (sb=0;sb<bound;sb++)
		for (ch=0;ch<nch;ch++)
		if (allocation[ch][sb]!=0) {
			mpi=(*bit_alloc_index)[sb][allocation[ch][sb]];	
			no_of_bits=t_bpc[mpi];
			c=t_c[mpi];
			d=t_d[mpi];
			grouping=t_grouping[mpi];
			nlevels=t_nlevels[mpi];

			if (grouping) {
				int samplecode=getbits(no_of_bits);
				convert_samplecode(samplecode,grouping,sb_sample_buf);

                        	for (s=0;s<3;s++)
                                	subband_sample[ch][sb][3*gr+s]=requantize_sample (sb_sample_buf[s],nlevels,c,d,scalefactor[ch][sb][gr/4]);
			} else {
				for (s=0;s<3;s++) sb_sample_buf[s]=getbits(no_of_bits);
				
				for (s=0;s<3;s++) { 
					/*subband_sample[ch][sb][3*gr+s]=requantize_sample (sb_sample_buf[s],nlevels,c,d,scalefactor[ch][sb][gr/4]);*/
					subband_sample[ch][sb][3*gr+s]=(t_dd[mpi]+sb_sample_buf[s]*t_nli[mpi])*c*scalefactor[ch][sb][gr>>2];
				}
			}
	    	} else 
			for (s=0;s<3;s++) subband_sample[ch][sb][3*gr+s]=0;


		/*
		 * joint stereo ********************************************
		 */
      
		for (sb=bound;sb<sblimit;sb++)
   		if (allocation[0][sb]!=0) {
			/*ispravka!
			*/
			mpi=(*bit_alloc_index)[sb][allocation[0][sb]];	
			no_of_bits=t_bpc[mpi];
			c=t_c[mpi];
			d=t_d[mpi];
			grouping=t_grouping[mpi];
			nlevels=t_nlevels[mpi];	
	    	   
			if (grouping) {
				int samplecode=getbits(no_of_bits);
				convert_samplecode(samplecode,grouping,sb_sample_buf);

				for (s=0;s<3;s++) {
					subband_sample[0][sb][3*gr+s]=requantize_sample (sb_sample_buf[s],nlevels,c,d,scalefactor[0][sb][gr/4]);
					subband_sample[1][sb][3*gr+s]=subband_sample[0][sb][3*gr+s];
				}
			} else {
				for (s=0;s<3;s++) sb_sample_buf[s]=getbits(no_of_bits);

				for (s=0;s<3;s++) { 
					subband_sample[0][sb][3*gr+s]=subband_sample[1][sb][3*gr+s]=\
						(t_dd[mpi]+sb_sample_buf[s]*t_nli[mpi])*c*scalefactor[0][sb][gr>>2];
				}
			}

		} else for (s=0;s<3;s++) {
			subband_sample[0][sb][3*gr+s]=0;
			subband_sample[1][sb][3*gr+s]=0;
		}

		/*
		 * the rest *******************************************
		 */
		for (sb=sblimit;sb<32;sb++)
			for (ch=0;ch<nch;ch++)

				for (s=0;s<3;s++) subband_sample[ch][sb][3*gr+s]=0;
	}	

	/*
	 * this is, in fact, horrible, but I had to adjust it to amp/mp3. The hack to make downmixing
	 * work is as ugly as possible.
	 */

	if (A_DOWNMIX && header->mode!=3) {
		for (ch=0;ch<nch;ch++) 
			for (sb=0;sb<32;sb++)
				for (i=0;i<36;i++)
					subband_sample[0][sb][i]=(subband_sample[0][sb][i]+subband_sample[1][sb][i])*0.5f;
		nch=1;
	}

	for (ch=0;ch<nch;ch++) {
		for (sb=0;sb<32;sb++) 
			for (i=0;i<18;i++) res[sb][i]=subband_sample[ch][sb][i]; 
	   	for (i=0;i<18;i++)
			poly(ch,i);
	}
	printout();
	for (ch=0;ch<nch;ch++) {
                for (sb=0;sb<32;sb++)
                        for (i=0;i<18;i++) res[sb][i]=subband_sample[ch][sb][i+18];
                for (i=0;i<18;i++)
                        poly(ch,i);
        }
        printout();

	if (A_DOWNMIX && header->mode!=3) nch=2;

	return 0;
}                        
/****************************************************************************/	
/****************************************************************************/

void convert_samplecode(unsigned int samplecode,unsigned int nlevels,unsigned short* sb_sample_buf)
{
int i;

	for (i=0;i<3;i++) {
		*sb_sample_buf=samplecode%nlevels;
		samplecode=samplecode/nlevels;
		sb_sample_buf++;
	}
}

float requantize_sample(unsigned short s4,unsigned short nlevels,float c,float d,float factor)
{
register float s,s2,s3;
s3=-1.0+s4*2.0/(nlevels+1);
s2=c*(s3+d);
s=factor*s2;
return s;
} 

--- NEW FILE: misc2.h ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/
 
/* misc2.h  
 *
 * Created by: tomislav uzelac  May 1996
 * Last modified by: tomislav uzelac Jan  8 1997
 */
#ifndef _MISC2_H_
#define _MISC2_H_
void requantize_mono(int, int, struct SIDE_INFO *, struct AUDIO_HEADER *);
void requantize_ms(int, struct SIDE_INFO *, struct AUDIO_HEADER *);
void requantize_downmix(int, struct SIDE_INFO *, struct AUDIO_HEADER *);

void alias_reduction(int);
void calculate_t43(void);

extern int no_of_imdcts[];

#ifdef MISC2

#define i_sq2   0.707106781188
#define IS_ILLEGAL 0xfeed

static inline float fras_l(int,int,int,int,int);
static inline float fras_s(int,int,int,int);
static inline float fras2(int,float);
static int find_isbound(int isbound[3],int gr,struct SIDE_INFO *info,struct AUDIO_HEADER *header);
static inline void stereo_s(int l,float a[2],int pos,int ms_flag,int is_pos,struct AUDIO_HEADER *header);
static inline void stereo_l(int l,float a[2],int ms_flag,int is_pos,struct AUDIO_HEADER *header);

#endif
#endif


--- NEW FILE: layer3.c ---
/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/

/* layer3.c  layer3 audio decoding
 *
 * Created by: tomislav uzelac  Mar  1 97
 * Last modified by: 
 */
#include "amp.h"
#include "audio.h"
#include "getbits.h"
#include "getdata.h"
#include "huffman.h"
#include "misc2.h"
#include "transform.h"

#define LAYER3
#include "layer3.h"

/* this function decodes one layer3 audio frame, except for the header decoding
 * which is done in main() [audio.c]. returns 0 if everything is ok.
 */
int layer3_frame(struct AUDIO_HEADER *header,int cnt)
{
static struct SIDE_INFO info;

int gr,ch,sb,i;
int mean_frame_size,bitrate,fs,hsize,ssize;

/* we need these later, hsize is the size of header+side_info
*/
	if (header->ID) 
		if (header->mode==3) {
			nch=1;
			hsize=21;
		} else {
			nch=2;
			hsize=36;
		}
	else
		if (header->mode==3) {
			nch=1;
			hsize=13;
		} else {
			nch=2;
			hsize=21;
		}

/* crc increases hsize by 2
*/
	if (header->protection_bit==0) hsize+=2;


/* read layer3 specific side_info
*/
        getinfo(header,&info);


/* MPEG2 only has one granule
*/
	bitrate=t_bitrate[header->ID][3-header->layer][header->bitrate_index];
	fs=t_sampling_frequency[header->ID][header->sampling_frequency];
        if (header->ID) mean_frame_size=144000*bitrate/fs;
        else mean_frame_size=72000*bitrate/fs;


/* check if mdb is too big for the first few frames. this means that
 * a part of the stream could be missing. We must still fill the buffer
 *
 * don't forget to (re)initialise bclean_bytes to 0, and f_bdirty to FALSE!!!
 */
	if (f_bdirty) 
	{
		if (info.main_data_begin > bclean_bytes) 
		{
			fillbfr(mean_frame_size + header->padding_bit - hsize);
			bclean_bytes+=mean_frame_size + header->padding_bit - hsize;
			/* warn(" frame %d discarded, incomplete main_data\n",cnt); */
			return 0;
		} 
		else 
		{
			/* re-initialise */
			f_bdirty=FALSE;
			bclean_bytes=0;
		}
	}	
/* now update the data 'pointer' (counting in bits) according to
 * the main_data_begin information
 */
        data = 8 * ((append - info.main_data_begin) & (BUFFER_SIZE-1));


/* read into the buffer all bytes up to the start of next header
*/
        fillbfr(mean_frame_size + header->padding_bit - hsize);


/* these two should go away
*/
	t_l=&t_b8_l[header->ID][header->sampling_frequency][0];
	t_s=&t_b8_s[header->ID][header->sampling_frequency][0];

/* decode the scalefactors and huffman data
 * this part needs to be enhanced for error robustness
 */
	for (gr=0;gr < ((header->ID) ? 2 : 1);gr++) {
		for (ch=0;ch<nch;ch++) {
			ssize=decode_scalefactors(&info,header,gr,ch);
			decode_huffman_data(&info,gr,ch,ssize);
		}
		
	/* requantization, stereo processing, reordering(shortbl)
	*/

		if (A_DOWNMIX && nch==2) 
			requantize_downmix(gr,&info,header);
		else 
		{
			if (header->mode!=1 || (header->mode==1 && header->mode_extension==0))
			{
				for (ch=0;ch<nch;ch++) 
					requantize_mono(gr,ch,&info,header);
			}
			else 
				requantize_ms(gr,&info,header);
		}
	/* just which window?
	*/

	/* this is a very temporary, very ugly hack. 
	*/
		if (A_DOWNMIX) nch=1;

		for (ch=0; ch < (A_DOWNMIX ? 1:nch) ;ch++) {
		int win_type; /* same as in the standard, long=0, start=1 ,.... */
		int window_switching_flag = info.window_switching_flag[gr][ch];
		int block_type = info.block_type[gr][ch];
		int mixed_block_flag = info.mixed_block_flag[gr][ch];

		/* antialiasing butterflies
		*/
			if (!(window_switching_flag &&
			      block_type==2))
                                alias_reduction(ch);

			if (window_switching_flag &&
			    block_type==2 &&
			    mixed_block_flag)
				win_type=0;
			else
			        if (!window_switching_flag) win_type=0;
				else win_type=block_type;

		/* imdct ...
		*/
			for (sb=0;sb<2;sb++)
				imdct(win_type,sb,ch);

			if (window_switching_flag &&
			    block_type==2 &&
			    mixed_block_flag)
				win_type=2;

		/* no_of_imdcts tells us how many subbands from the top are all zero
		 * it is set by the requantize functions in misc2.c
		 */
			for (sb=2;sb<no_of_imdcts[ch];sb++)
				imdct(win_type,sb,ch);

			for (;sb<32;sb++) 
				for (i=0;i<18;i++) {
					res[sb][i]=s[ch][sb][i];
					s[ch][sb][i]=0.0f;
				}
	
		/* polyphase filterbank
		*/
			/* if (nch == 2) this was a bug, tomislav */
			        for (i=0;i<18;i++)
				        poly(ch,i);
		}

		printout();

		/* this is part2 of a particularily ugly hack. this should vanish as soon as nch isn't
		   a global variable anymore
		*/
		if (A_DOWNMIX && header->mode!=3) nch=2;

	}    /*  for (gr... */ 

	/* return status: 0 for ok, errors will be added
	*/
	return 0;
} 





More information about the dslinux-commit mailing list