Commit 13411a9c authored by Led's avatar Led

0.7.0

parent 82ba78e0
......@@ -79,6 +79,9 @@ rm <string name>
save <string name>
saves the current playlist to _name_.m3u in the playlist directory
repeat <int state>
set repeat state to _state_, _state_ should be 0 or 1
search <string type> <string what>
same as "find" but searches for any song that contain _what_
......@@ -86,7 +89,10 @@ shuffle
shuffles the current playlist
status
reports current status of player, one of the folloowing:
reports current status of player, and volume level.
volume level is printed first (0-100).
repeat status is printed second (0 or 1).
then player status, one of the following:
"stop" - player is stopped
"play <int song> <int elapsed>:<time total>"
- playing _song_ with _elapses_ seconds, and the song
......@@ -99,3 +105,6 @@ stop
update
searches mp3 directory for new music and removes old music from the db
volume <int change>
change volume by amount _change_
ver 0.7.0 (2003/6/20)
1) use mad instead of mpg123 for mp3 decoding
2) volume support
3) repeate playlist support
4) use autoconf/automake (i.e. "configure")
5) configurable max connections
ver 0.6.2 (2003/6/11)
1) Buffer support for ogg
2) new config file options: "connection_timeout" and "mpg123_ignore_junk"
3) new commands: "next", "previous", and "listall"
Thanks to Nicklas Hofer for "next" and "previous" patches!
4) Search by filename
5) bug fix for pause when playing mp3's
......
Music Player Daemon - FAQ
By: Nick Texidor
Q) How do I install mpd.
A) The usual way :^). untar the archive file, run 'make' (or 'make ogg' for
ogg vorbis support). Then, as su, 'make install'.
Q) How do I run mpd.
A) Change to the path mpd was installed to, i.e. /usr/local/mpd. Type
'mpd <port> <mp3/ogg directory> <playlist directory> <log file> <error file>'
i.e. mpd 2100 /mnt/jukebox /usr/local/mpd/playlists /usr/local/mpd/mpd.log /usr/local/mpd/mpd.error
Once mpd starts, it will explore your MP3/Ogg directory.
Q) How do I tell mpd to play music?
A) You can use a telnet interface (telnet <machine-name> <port>), or you
can download phpMp and queue songs via a web interface.
Q) How do I use telnet to play music using mpd?
A) login to the telnet session (telnet <machine-name> <port>). You
should see 'OK MPD 0.x.x' (where x is a number).
To queue songs to play, you use the command ADD, i.e.:
add "/path/to/song/song.mp3"
This should respond with 'OK'. If it says that it's an invalid mp3
file, then check the path. The path is relative to your current path.
To check the playlist, type PLAYLIST and press enter. To start
the playlist, type PLAY n (where n is a number from the
playlist, 0 would start playing from the top of the playlist).
Other commands include:
clear - to clear the playlist
pause - to pause playback
lsinfo <directory [optional]> - list contents of directory
save <file name> - saves the current playlist
shuffle - shuffles the playlist
find album|artist|title <search string> - Searches the specified field for
requested string
stop - Stop playing
update - Updates the MP3/Ogg Directory
Q) How do I start mpd automatically at boot time
A) Currently, there isn't a "nice" way of doing this. You can start it
as root (beware!) by entering 'mpd 2100 /mnt/jukebox /usr/local/mpd/playlists/usr/local/mpd/mpd.log /usr/local/mpd/mpd.error'
into your /etc/rc.d/rc.local file.
Q) What do I need to use mpd?
A) 1) mpg123 (or preferably mpg321)
and/or
2) ogg, vorbis, and libao (make sure you have the libogg, libvorbis, and libao
development and library packages installed for your distro. For Red Hat, the
rpm's are libogg, libogg-devel, libvorbis, libvorbis-devel, libao, and i
libao-devel)
Q) I queued a song to the playlist, but when mpd played it, it
didn't play properly
A) hmm, we haven't gotten to the bottom of this yet! It seems some
headers cause some mp3's to not play properly, and instead, appears to
play the track at very highspeed resulting in squeaking. This appears
to be a problem with mpg123. mpg321 has better results, but the track
seems to be distorted, while xmms plays the track without any problems.
Q) How can I get mpd to start playing music automatically when it starts
up
A) This can be done with a bit of jiggery pokery using the rc.local
script. After the command to start mpd, you can automate a telnet
session to load a playlist and issue a shuffle command. (Alternately,
hassle Warren to implement such a wonder feature) :^)
(From Warren - something is coming sonn)
Q) Can I send the output from mpd to IceCast/ShoutCast
A) No. Again, if you email your favourite mpd author, he may be able to
implement this little beaut of a feature! :^)
(if you have a gazillion US dollars to donate to warren's legal defense,
this feature can be implemented more quickly).
......@@ -3,14 +3,10 @@
Requirements
------------
mpg123 - http://www.mpg123.de (MPD has been tested with 0.59q and 0.59r)
(mpg123 is included with many distributions and supports many platforms)
or
mpg321 - http://mpg321.sourceforge.net
(debian and other distributions substitute mpg123 with mpg321, if so, make
sure mpg123 is symlinked to mpg321)
libao - http://www.vorbis.com/download_unix.psp
(This comes with most/all distrobutions. Make sure you have both
the ao libs and development packages for your distrobution installed.
For Red Hat 8.0, the neccessary packages are: libao and libao-devel)
Optional
--------
......@@ -21,11 +17,6 @@ ogg and vorbis libs as well as the development packages for your
distrobution installed. For Red Hat 8.0, the neccessary packages are:
libogg, libogg-devel, libvorbis, and libvorbis-devel).
libao - http://www.xiph.org/ogg/vorbis/ (You need this for ogg vorbis)
(This also comes with most/all distrobutions. Make sure you have both
the libao libs and development packages for your distrobution installed.
For Red Hat 8.0, the neccessary packages are: libao and libao-devel)
Download
--------
......@@ -42,25 +33,19 @@ $ tar zxvf mpd-x.x.x.tar.gz
$ cd mpd-x.x.x
3) compile
3) Run configure script (this will determine what dependencies you have)
$ make
NOTE: for Ogg Vorbis support run make with the "ogg" target:
$ make ogg
$ ./configure
NOTE: to recompile you must remove the compiled files with:
4) Compile
$ make clean
$ make
Install
Install (Optional)
-------
1) copy "mpd" to a directory in path (Optional)
(as root)
$ cp mpd /usr/local/bin
$ make install
Run
---
......@@ -82,7 +67,7 @@ $ mpd-x.x.x/mpd 2100 mp3 playlists mpd.log mpd.err
Note: The first time you run mpd, it will "explore" your mp3 directory for
mp3's.
Also, for MPD >= 0.6.1, mpd can alternatively use config file. In this case,
Also, mpd can alternatively use config file. In this case,
run mpd like this:
$ mpd <config file>
......@@ -99,4 +84,4 @@ Using MPD
You can download a web interface (phpMp) to MPD at
http://musicpd.sourceforge.net .
MPD can be interfaced directly using telnet (see command.c, if you are brave).
MPD can be interfaced directly using telnet (see COMMANDS, if you are brave).
EXEC = mpd
OGG_MAKEFILE = Makefile.ogg
-include Makefile.ogg
PREFIX = /usr/local
BIN_DIR = $(PREFIX)/bin
INSTALL_DIR = $(PREFIX)/$(EXEC)
CC = gcc
LIBS = $(OGG_LIBS) -ldl
INCLUDES =
CFLAGS = -Wall $(INCLUDES) $(HAVE_OGG)
OFLAGS = -Wall
DFLAGS = -MM $(INCLUDES) $(HAVE_OGG)
SOURCES = main.c buffer2array.c mpg123.c interface.c command.c playlist.c ls.c \
id3v2lib/charset.c id3v2lib/lib_id3v2.3.c id3v1lib/lib_id3v1.c \
id3v2lib/lib_id3v2.2.c song.c list.c directory.c tables.c utils.c \
tag.c player.c ogg.c listen.c conf.c ogg_decode.c
OBJECTS = $(SOURCES:.c=.o)
DEPENDFILE = Makefile.depend
all: $(EXEC)
ogg: ogg-make
$(MAKE) all
$(MAKE) clean-ogg-make
ogg-make:
echo "HAVE_OGG = -DHAVE_OGG" > $(OGG_MAKEFILE)
echo "OGG_LIBS = -lvorbisfile -lvorbis -lao" >> $(OGG_MAKEFILE)
$(EXEC): $(OBJECTS)
$(CC) $(OFLAGS) -o $(EXEC) $(OBJECTS) $(LIBS)
deps:
$(CC) $(DFLAGS) $(SOURCES) > $(DEPENDFILE)
-include $(DEPENDFILE)
install: $(EXEC)
mkdir -p $(INSTALL_DIR)
cp $(EXEC) $(INSTALL_DIR)
ln -s $(INSTALL_DIR)/$(EXEC) $(BIN_DIR)/$(EXEC)
uninstall:
rm $(BIN_DIR)/$(EXEC)
rm $(INSTALL_DIR)/$(EXEC)
rm -r $(INSTALL_DIR)
clean:
rm -f $(EXEC) $(OBJECTS)
clean-deps:
rm -f $(DEPENDFILE)
clean-ogg-make:
rm -f $(OGG_MAKEFILE)
clean-all: clean clean-deps clean-ogg-make
bin_PROGRAMS = mpd
SUBDIRS = id3v1lib id3v2lib libmad
pkgdata_DATA = mpdconf.example README INSTALL
EXTRA_DIST = COMMANDS UPGRADING $(pkgdata_DATA)
mpd_headers = buffer2array.h interface.h command.h playlist.h ls.h \
song.h list.h directory.h tables.h utils.h path.h \
tag.h player.h listen.h conf.h ogg_decode.h volume.h mp3_decode.h
mpd_SOURCES = main.c buffer2array.c interface.c command.c playlist.c ls.c \
song.c list.c directory.c tables.c utils.c path.c \
tag.c player.c listen.c conf.c ogg_decode.c volume.c mp3_decode.c \
$(mpd_headers)
MAD_LIB = libmad/.libs/libmad.a
ID3_LIB = id3v2lib/libid3v2.a id3v1lib/libid3v1.a
mpd_LDADD = $(MAD_LIB) $(ID3_LIB)
# Makefile.in generated automatically by automake 1.4-p4 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
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 = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
AO_CFLAGS = @AO_CFLAGS@
AO_LIBS = @AO_LIBS@
AS = @AS@
CC = @CC@
CCAS = @CCAS@
CCASFLAGS = @CCASFLAGS@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
EXEEXT = @EXEEXT@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OGG_CFLAGS = @OGG_CFLAGS@
OGG_LIBS = @OGG_LIBS@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
STRIP = @STRIP@
VERSION = @VERSION@
VORBISENC_LIBS = @VORBISENC_LIBS@
VORBISFILE_LIBS = @VORBISFILE_LIBS@
VORBIS_CFLAGS = @VORBIS_CFLAGS@
VORBIS_LIBS = @VORBIS_LIBS@
bin_PROGRAMS = mpd
SUBDIRS = id3v1lib id3v2lib libmad
pkgdata_DATA = mpdconf.example README INSTALL
EXTRA_DIST = COMMANDS UPGRADING $(pkgdata_DATA)
mpd_headers = buffer2array.h interface.h command.h playlist.h ls.h song.h list.h directory.h tables.h utils.h path.h tag.h player.h listen.h conf.h ogg_decode.h volume.h mp3_decode.h
mpd_SOURCES = main.c buffer2array.c interface.c command.c playlist.c ls.c song.c list.c directory.c tables.c utils.c path.c tag.c player.c listen.c conf.c ogg_decode.c volume.c mp3_decode.c $(mpd_headers)
MAD_LIB = libmad/.libs/libmad.a
ID3_LIB = id3v2lib/libid3v2.a id3v1lib/libid3v1.a
mpd_LDADD = $(MAD_LIB) $(ID3_LIB)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_CLEAN_FILES =
bin_PROGRAMS = mpd$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS)
DEFS = @DEFS@ -I. -I$(srcdir)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
mpd_OBJECTS = main.$(OBJEXT) buffer2array.$(OBJEXT) interface.$(OBJEXT) \
command.$(OBJEXT) playlist.$(OBJEXT) ls.$(OBJEXT) song.$(OBJEXT) \
list.$(OBJEXT) directory.$(OBJEXT) tables.$(OBJEXT) utils.$(OBJEXT) \
path.$(OBJEXT) tag.$(OBJEXT) player.$(OBJEXT) listen.$(OBJEXT) \
conf.$(OBJEXT) ogg_decode.$(OBJEXT) volume.$(OBJEXT) \
mp3_decode.$(OBJEXT)
mpd_DEPENDENCIES = libmad/.libs/libmad.a id3v2lib/libid3v2.a \
id3v1lib/libid3v1.a
mpd_LDFLAGS =
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DATA = $(pkgdata_DATA)
DIST_COMMON = README COPYING ChangeLog INSTALL Makefile.am Makefile.in \
TODO aclocal.m4 config.guess config.sub configure configure.in \
install-sh ltmain.sh missing mkinstalldirs
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
SOURCES = $(mpd_SOURCES)
OBJECTS = $(mpd_OBJECTS)
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .lo .o .obj .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(ACLOCAL_M4): configure.in
cd $(srcdir) && $(ACLOCAL)
config.status: $(srcdir)/configure.in $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
mostlyclean-binPROGRAMS:
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
distclean-binPROGRAMS:
maintainer-clean-binPROGRAMS:
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(bindir)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
if test -f $$p; then \
echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
$(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
list='$(bin_PROGRAMS)'; for p in $$list; do \
rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
done
.c.o:
$(COMPILE) -c $<
# FIXME: We should only use cygpath when building on Windows,
# and only if it is available.
.c.obj:
$(COMPILE) -c `cygpath -w $<`
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
-rm -f *.$(OBJEXT)
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
.c.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.S.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
maintainer-clean-libtool:
mpd$(EXEEXT): $(mpd_OBJECTS) $(mpd_DEPENDENCIES)
@rm -f mpd$(EXEEXT)
$(LINK) $(mpd_LDFLAGS) $(mpd_OBJECTS) $(mpd_LDADD) $(LIBS)
install-pkgdataDATA: $(pkgdata_DATA)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
@list='$(pkgdata_DATA)'; for p in $$list; do \
if test -f $(srcdir)/$$p; then \
echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkgdatadir)/$$p"; \
$(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkgdatadir)/$$p; \
else if test -f $$p; then \
echo " $(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p"; \
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
fi; fi; \
done
uninstall-pkgdataDATA:
@$(NORMAL_UNINSTALL)
list='$(pkgdata_DATA)'; for p in $$list; do \
rm -f $(DESTDIR)$(pkgdatadir)/$$p; \
done
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
@SET_MAKE@
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
rev="$$subdir $$rev"; \
test "$$subdir" = "." && dot_seen=yes; \
done; \
test "$$dot_seen" = "no" && rev=". $$rev"; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
-rm -rf $(distdir)
GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
mkdir $(distdir)/=build
mkdir $(distdir)/=inst
dc_install_base=`cd $(distdir)/=inst && pwd`; \
cd $(distdir)/=build \
&& ../configure --srcdir=.. --prefix=$$dc_install_base \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) dist
-rm -rf $(distdir)
@banner="$(distdir).tar.gz is ready for distribution"; \
dashes=`echo "$$banner" | sed s/./=/g`; \
echo "$$dashes"; \
echo "$$banner"; \
echo "$$dashes"
dist: distdir
-chmod -R a+r $(distdir)
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
dist-all: distdir
-chmod -R a+r $(distdir)
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
distdir: $(DISTFILES)
-rm -rf $(distdir)
mkdir $(distdir)
-chmod 777 $(distdir)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
for subdir in $(SUBDIRS); do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
chmod 777 $(distdir)/$$subdir; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
|| exit 1; \
fi; \
done
info-am:
info: info-recursive
dvi-am:
dvi: dvi-recursive
check-am: all-am
check: check-recursive
installcheck-am:
installcheck: installcheck-recursive
install-exec-am: install-binPROGRAMS
install-exec: install-exec-recursive
install-data-am: install-pkgdataDATA
install-data: install-data-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-recursive
uninstall-am: uninstall-binPROGRAMS uninstall-pkgdataDATA
uninstall: uninstall-recursive
all-am: Makefile $(PROGRAMS) $(DATA)
all-redirect: all-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs: installdirs-recursive
installdirs-am:
$(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(pkgdatadir)
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \
mostlyclean-libtool mostlyclean-tags \
mostlyclean-generic
mostlyclean: mostlyclean-recursive
clean-am: clean-binPROGRAMS clean-compile clean-libtool clean-tags \
clean-generic mostlyclean-am
clean: clean-recursive
distclean-am: distclean-binPROGRAMS distclean-compile distclean-libtool \
distclean-tags distclean-generic clean-am
-rm -f libtool
distclean: distclean-recursive
-rm -f config.status
maintainer-clean-am: maintainer-clean-binPROGRAMS \
maintainer-clean-compile maintainer-clean-libtool \
maintainer-clean-tags maintainer-clean-generic \
distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-recursive
-rm -f config.status
.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
install-pkgdataDATA install-data-recursive uninstall-data-recursive \
install-exec-recursive uninstall-exec-recursive installdirs-recursive \
uninstalldirs-recursive all-recursive check-recursive \
installcheck-recursive info-recursive dvi-recursive \
mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
install-exec install-data-am install-data install-am install \
uninstall-am uninstall all-redirect all-am all installdirs-am \
installdirs mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
......@@ -9,6 +9,10 @@ retrieval, and playlist management can all be managed remotely.
To install MPD, see INSTALL.
MPD includes 3 libraries in the source. id3v1lib and id3v2lib are released
under the GPL and copyrighted by Samuel Abels (sam@manicsadness.com). libmad
is copyrighted by Robert Leslie (http://www.underbit.com/products/mad).
MPD is released under the GNU Public License.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
......
1) make timeout and max connections configurabe via config file
2) volume control
3) use mpglib from mpg123 for mp3 support
4) use autoconf and automake
5) broadcast messages (including status changes/updates)
6) store song times (possibly after playing)
7) add a set a flags (such as BAD MP3)
1) store song times (possibly after playing)
2) flac support
3) seeking
4) set flags (such as BAD MP3)
possibly:
---------
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -22,6 +22,8 @@
#include "ls.h"
#include "directory.h"
#include "tables.h"
#include "volume.h"
#include "path.h"
#include <stdlib.h>
#include <string.h>
......@@ -50,6 +52,8 @@
#define COMMAND_NEXT "next"
#define COMMAND_PREVIOUS "previous"
#define COMMAND_LISTALL "listall"
#define COMMAND_VOLUME "volume"
#define COMMAND_REPEAT "repeat"
extern Playlist playlist;
......@@ -73,10 +77,10 @@ int commandStatus(FILE * fp,int argArrayLength, char ** argArray) {
}
if(getPlayerState()>0) {
fprintf(fp,"%s %i %i:%i\n",state,playlist.current,getPlayerElapsedTime(),getPlayerTotalTime());
fprintf(fp,"%i %i %s %i %i:%i\n",getVolumeLevel(),getPlaylistRepeatStatus(),state,playlist.current,getPlayerElapsedTime(),getPlayerTotalTime());
}
else {
fprintf(fp,"%s\n",state);
fprintf(fp,"%i %i %s\n",getVolumeLevel(),getPlaylistRepeatStatus(),state);
}
free(state);
......@@ -180,6 +184,34 @@ int processCommand(FILE * fp, int argArrayLength, char ** argArray) {
}
return deleteFromPlaylist(fp,song);
}
else if(0==strcmp(argArray[0],COMMAND_VOLUME)) {
int change;
char * test;
if(argArrayLength!=2) {
fprintf(fp,"%s wrong number of arguments for \"%s\"\n",COMMAND_RESPOND_ERROR,argArray[0]);
return -1;
}
change = strtol(argArray[1],&test,10);
if(*test!='\0') {
fprintf(fp,"%s need a integer\n",COMMAND_RESPOND_ERROR);
return -1;
}
return changeVolumeLevel(fp,change);
}
else if(0==strcmp(argArray[0],COMMAND_REPEAT)) {
int status;
char * test;
if(argArrayLength!=2) {
fprintf(fp,"%s wrong number of arguments for \"%s\"\n",COMMAND_RESPOND_ERROR,argArray[0]);
return -1;
}
status = strtol(argArray[1],&test,10);
if(*test!='\0') {
fprintf(fp,"%s need a integer\n",COMMAND_RESPOND_ERROR);
return -1;
}
return setPlaylistRepeatStatus(fp,status);
}
else if(0==strcmp(argArray[0],COMMAND_PLAYLISTINFO)) {
int song = -1;
char * test;
......
......@@ -28,25 +28,23 @@
#define MAX_STRING_SIZE MAXPATHLEN+80
#define CONF_NUMBER_OF_PARAMS 9
#define CONF_NUMBER_OF_PARAMS 8
#define CONF_NUMBER_OF_PATHS 4
#define CONF_NUMBER_OF_REQUIRED 5
#define CONF_MPG123_COMMAND_DEFAULT "mpg123 -b 2048 -R foo"
#define CONF_MPG123_PROCESS_DEFAULT "mpg123"
#define CONF_MPG123_IGNORE_JUNK_DEFAULT "yes"
#define CONF_CONNECTION_TIMEOUT_DEFAULT "60"
#define CONF_MIXER_DEVICE_DEFAULT "/dev/mixer"
#define CONF_MAX_CONNECTIONS_DEFAULT "5"
char conf_strings[CONF_NUMBER_OF_PARAMS][24] = {
"mpg123_command",
"port",
"music_directory",
"playlist_directory",
"log_file",
"error_file",
"mpg123_process",
"mpg123_ignore_junk",
"connection_timeout"
"connection_timeout",
"mixer_device",
"max_connections"
};
int conf_absolutePaths[CONF_NUMBER_OF_PATHS] = {
......@@ -72,10 +70,9 @@ void initConf() {
for(i=0;i<CONF_NUMBER_OF_PARAMS;i++) conf_params[i] = NULL;
/* we don't specify these on the command line */
conf_params[CONF_MPG123_COMMAND] = strdup(CONF_MPG123_COMMAND_DEFAULT);
conf_params[CONF_MPG123_PROCESS] = strdup(CONF_MPG123_PROCESS_DEFAULT);
conf_params[CONF_MPG123_IGNORE_JUNK] = strdup(CONF_MPG123_IGNORE_JUNK_DEFAULT);
conf_params[CONF_CONNECTION_TIMEOUT] = strdup(CONF_CONNECTION_TIMEOUT_DEFAULT);
conf_params[CONF_MIXER_DEVICE] = strdup(CONF_MIXER_DEVICE_DEFAULT);
conf_params[CONF_MAX_CONNECTIONS] = strdup(CONF_MAX_CONNECTIONS_DEFAULT);
}
char ** readConf(char * file) {
......
......@@ -19,15 +19,14 @@
#ifndef CONF_H
#define CONF_H
#define CONF_MPG123_COMMAND 0
#define CONF_PORT 1
#define CONF_MUSIC_DIRECTORY 2
#define CONF_PLAYLIST_DIRECTORY 3
#define CONF_LOG_FILE 4
#define CONF_ERROR_FILE 5
#define CONF_MPG123_PROCESS 6
#define CONF_MPG123_IGNORE_JUNK 7
#define CONF_CONNECTION_TIMEOUT 8
#define CONF_PORT 0
#define CONF_MUSIC_DIRECTORY 1
#define CONF_PLAYLIST_DIRECTORY 2
#define CONF_LOG_FILE 3
#define CONF_ERROR_FILE 4
#define CONF_CONNECTION_TIMEOUT 5
#define CONF_MIXER_DEVICE 6
#define CONF_MAX_CONNECTIONS 7
/* do not free the return value, it is a static variable */
char ** readConf(char * file);
......
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002 Free Software Foundation, Inc.
timestamp='2002-03-20'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Per Bothner <per@bothner.com>.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
#
# The plan is that this can be called by configure scripts if you
# don't specify an explicit build system type.
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
Output the configuration name of the system \`$me' is run on.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit 0 ;;
--version | -v )
echo "$version" ; exit 0 ;;
--help | --h* | -h )
echo "$usage"; exit 0 ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help" >&2
exit 1 ;;
* )
break ;;
esac
done
if test $# != 0; then
echo "$me: too many arguments$help" >&2
exit 1
fi
dummy=dummy-$$
trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
# CC_FOR_BUILD -- compiler used by this script.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
,,) echo "int dummy(){}" > $dummy.c ;
for c in cc gcc c89 c99 ; do
($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
if test $? = 0 ; then
CC_FOR_BUILD="$c"; break ;
fi ;
done ;
rm -f $dummy.c $dummy.o $dummy.rel ;
if test x"$CC_FOR_BUILD" = x ; then
CC_FOR_BUILD=no_compiler_found ;
fi
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
esac'
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
PATH=$PATH:/.attbin ; export PATH
fi
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
# compatibility and a consistent mechanism for selecting the
# object file format.
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
case "${UNAME_MACHINE_ARCH}" in
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
case "${UNAME_MACHINE_ARCH}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep __ELF__ >/dev/null
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
os=netbsd
else
os=netbsdelf
fi
;;
*)
os=netbsd
;;
esac
# The OS release
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit 0 ;;
amiga:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
arc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
hp300:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
macppc:OpenBSD:*:*)
echo powerpc-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme88k:OpenBSD:*:*)
echo m88k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvmeppc:OpenBSD:*:*)
echo powerpc-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
pmax:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sgi:OpenBSD:*:*)
echo mipseb-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sun3:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
wgrisc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
alpha:OSF1:*:*)
if test $UNAME_RELEASE = "V4.0"; then
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
fi
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
cat <<EOF >$dummy.s
.data
\$Lformat:
.byte 37,100,45,37,120,10,0 # "%d-%x\n"
.text
.globl main
.align 4
.ent main
main:
.frame \$30,16,\$26,0
ldgp \$29,0(\$27)
.prologue 1
.long 0x47e03d80 # implver \$0
lda \$2,-1
.long 0x47e20c21 # amask \$2,\$1
lda \$16,\$Lformat
mov \$0,\$17
not \$1,\$18
jsr \$26,printf
ldgp \$29,0(\$26)
mov 0,\$16
jsr \$26,exit
.end main
EOF
eval $set_cc_for_build
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
if test "$?" = 0 ; then
case `./$dummy` in
0-0)
UNAME_MACHINE="alpha"
;;
1-0)
UNAME_MACHINE="alphaev5"
;;
1-1)
UNAME_MACHINE="alphaev56"
;;
1-101)
UNAME_MACHINE="alphapca56"
;;
2-303)
UNAME_MACHINE="alphaev6"
;;
2-307)
UNAME_MACHINE="alphaev67"
;;
2-1307)
UNAME_MACHINE="alphaev68"
;;
esac
fi
rm -f $dummy.s $dummy
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit 0 ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
# of the specific Alpha model?
echo alpha-pc-interix
exit 0 ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
exit 0 ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit 0;;
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
exit 0 ;;
*:[Mm]orph[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-morphos
exit 0 ;;
*:OS/390:*:*)
echo i370-ibm-openedition
exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
echo hppa1.1-hitachi-hiuxmpp
exit 0;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
fi
exit 0 ;;
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
i86pc:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in
Series*|S4*)
UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
exit 0 ;;
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
echo m68k-sun-sunos${UNAME_RELEASE}
;;
sun4)
echo sparc-sun-sunos${UNAME_RELEASE}
;;
esac
exit 0 ;;
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit 0 ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
# > m68000). The system name ranges from "MiNT" over "FreeMiNT"
# to the lowercase version "mint" (or "freemint"). Finally
# the system name "TOS" denotes a system which is actually not
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
exit 0 ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
exit 0 ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit 0 ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit 0 ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
exit 0 ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
echo clipper-intergraph-clix${UNAME_RELEASE}
exit 0 ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
$CC_FOR_BUILD $dummy.c -o $dummy \
&& ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit 0 ;;
m88k:CX/UX:7*:*)
echo m88k-harris-cxux7
exit 0 ;;
m88k:*:4*:R4*)
echo m88k-motorola-sysv4
exit 0 ;;
m88k:*:3*:R3*)
echo m88k-motorola-sysv3
exit 0 ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
[ ${TARGET_BINARY_INTERFACE}x = x ]
then
echo m88k-dg-dgux${UNAME_RELEASE}
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
exit 0 ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit 0 ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
echo m88k-motorola-sysv3
exit 0 ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
echo m88k-tektronix-sysv3
exit 0 ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
echo m68k-tektronix-bsd
exit 0 ;;
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
exit 0 ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
echo i386-ibm-aix
exit 0 ;;
ia64:AIX:*:*)
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
exit 0 ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <sys/systemcfg.h>
main()
{
if (!__power_pc())
exit(1);
puts("powerpc-ibm-aix3.2.5");
exit(0);
}
EOF
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
else
echo rs6000-ibm-aix3.2
fi
exit 0 ;;
*:AIX:*:[45])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
exit 0 ;;
*:AIX:*:*)
echo rs6000-ibm-aix
exit 0 ;;
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
echo romp-ibm-bsd4.4
exit 0 ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit 0 ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
exit 0 ;;
DPX/2?00:B.O.S.:*:*)
echo m68k-bull-sysv3
exit 0 ;;
9000/[34]??:4.3bsd:1.*:*)
echo m68k-hp-bsd
exit 0 ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit 0 ;;
9000/[34678]??:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;;
esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy`
if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
rm -f $dummy.c $dummy
fi ;;
esac
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit 0 ;;
ia64:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ia64-hp-hpux${HPUX_REV}
exit 0 ;;
3050*:HI-UX:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <unistd.h>
int
main ()
{
long cpu = sysconf (_SC_CPU_VERSION);
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
results, however. */
if (CPU_IS_PA_RISC (cpu))
{
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
default: puts ("hppa-hitachi-hiuxwe2"); break;
}
}
else if (CPU_IS_HP_MC68K (cpu))
puts ("m68k-hitachi-hiuxwe2");
else puts ("unknown-hitachi-hiuxwe2");
exit (0);
}
EOF
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
echo unknown-hitachi-hiuxwe2
exit 0 ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
echo hppa1.1-hp-bsd
exit 0 ;;
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit 0 ;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit 0 ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit 0 ;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
exit 0 ;;
i*86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
echo ${UNAME_MACHINE}-unknown-osf1mk
else
echo ${UNAME_MACHINE}-unknown-osf1
fi
exit 0 ;;
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit 0 ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit 0 ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit 0 ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
exit 0 ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
exit 0 ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit 0 ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*[A-Z]90:*:*:*)
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*T3D:*:*:*)
echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*T3E:*:*:*)
echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*SV1:*:*:*)
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
sparc*:BSD/OS:*:*)
echo sparc-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit 0 ;;
i*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit 0 ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit 0 ;;
x86:Interix*:3*)
echo i386-pc-interix3
exit 0 ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
# UNAME_MACHINE based on the output of uname instead of i386?
echo i386-pc-interix
exit 0 ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
exit 0 ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin
exit 0 ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
*:GNU:*:*)
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit 0 ;;
arm*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
mips:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef mips
#undef mipsel
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=mipsel
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=mips
#else
CPU=
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
rm -f $dummy.c
test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0
;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
exit 0 ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
exit 0 ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
PCA57) UNAME_MACHINE=alphapca56 ;;
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
exit 0 ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
PA7*) echo hppa1.1-unknown-linux-gnu ;;
PA8*) echo hppa2.0-unknown-linux-gnu ;;
*) echo hppa-unknown-linux-gnu ;;
esac
exit 0 ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-gnu
exit 0 ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
exit 0 ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
exit 0 ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
# problems with other programs or directories called `ld' in the path.
# Set LC_ALL=C to ensure ld outputs messages in English.
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
| sed -ne '/supported targets:/!d
s/[ ][ ]*/ /g
s/.*supported targets: *//
s/ .*//
p'`
case "$ld_supported_targets" in
elf32-i386)
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
;;
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit 0 ;;
coff-i386)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
exit 0 ;;
"")
# Either a pre-BFD a.out linker (linux-gnuoldld) or
# one that does not give us useful --help.
echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
exit 0 ;;
esac
# Determine whether the default compiler is a.out or elf
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <features.h>
#ifdef __ELF__
# ifdef __GLIBC__
# if __GLIBC__ >= 2
LIBC=gnu
# else
LIBC=gnulibc1
# endif
# else
LIBC=gnulibc1
# endif
#else
#ifdef __INTEL_COMPILER
LIBC=gnu
#else
LIBC=gnuaout
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
rm -f $dummy.c
test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
echo i386-sequent-sysv4
exit 0 ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit 0 ;;
i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
fi
exit 0 ;;
i*86:*:5:[78]*)
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
exit 0 ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
&& UNAME_MACHINE=i686
(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit 0 ;;
i*86:*DOS:*:*)
echo ${UNAME_MACHINE}-pc-msdosdjgpp
exit 0 ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386.
echo i386-pc-msdosdjgpp
exit 0 ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit 0 ;;
paragon:*:*:*)
echo i860-intel-osf1
exit 0 ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
fi
exit 0 ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
echo m68010-convergent-sysv
exit 0 ;;
M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4.3${OS_REL} && exit 0
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4 && exit 0 ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
exit 0 ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
echo ${UNAME_MACHINE}-sni-sysv4
else
echo ns32k-sni-sysv
fi
exit 0 ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit 0 ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
echo hppa1.1-stratus-sysv4
exit 0 ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
exit 0 ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
echo hppa1.1-stratus-vos
exit 0 ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;;
news*:NEWS-OS:6*:*)
echo mips-sony-newsos6
exit 0 ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit 0 ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit 0 ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
echo powerpc-apple-beos
exit 0 ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit 0 ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit 0 ;;
SX-5:SUPER-UX:*:*)
echo sx5-nec-superux${UNAME_RELEASE}
exit 0 ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
*:Rhapsody:*:*)
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
*:Darwin:*:*)
echo `uname -p`-apple-darwin${UNAME_RELEASE}
exit 0 ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = "x86"; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
exit 0 ;;
*:QNX:*:4*)
echo i386-pc-qnx
exit 0 ;;
NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit 0 ;;
*:NonStop-UX:*:*)
echo mips-compaq-nonstopux
exit 0 ;;
BS2000:POSIX*:*:*)
echo bs2000-siemens-sysv
exit 0 ;;
DS/*:UNIX_System_V:*:*)
echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
exit 0 ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
if test "$cputype" = "386"; then
UNAME_MACHINE=i386
else
UNAME_MACHINE="$cputype"
fi
echo ${UNAME_MACHINE}-unknown-plan9
exit 0 ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
echo ${UNAME_MACHINE}-pc-os2-emx
exit 0 ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
exit 0 ;;
*:TENEX:*:*)
echo pdp10-unknown-tenex
exit 0 ;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
echo pdp10-dec-tops20
exit 0 ;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
echo pdp10-xkl-tops20
exit 0 ;;
*:TOPS-20:*:*)
echo pdp10-unknown-tops20
exit 0 ;;
*:ITS:*:*)
echo pdp10-unknown-its
exit 0 ;;
i*86:XTS-300:*:STOP)
echo ${UNAME_MACHINE}-unknown-stop
exit 0 ;;
i*86:atheos:*:*)
echo ${UNAME_MACHINE}-unknown-atheos
exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
# include <sys/utsname.h>
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
I don't know.... */
printf ("mips-sony-bsd\n"); exit (0);
#else
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (__arm) && defined (__acorn) && defined (__unix)
printf ("arm-acorn-riscix"); exit (0);
#endif
#if defined (hp300) && !defined (hpux)
printf ("m68k-hp-bsd\n"); exit (0);
#endif
#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif
#if defined (__386BSD__)
printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if defined (_SEQUENT_)
struct utsname un;
uname(&un);
if (strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
printf ("i386-sequent-ptx1\n"); exit (0);
}
printf ("i386-sequent-ptx\n"); exit (0);
#endif
#if defined (vax)
# if !defined (ultrix)
# include <sys/param.h>
# if defined (BSD)
# if BSD == 43
printf ("vax-dec-bsd4.3\n"); exit (0);
# else
# if BSD == 199006
printf ("vax-dec-bsd4.3reno\n"); exit (0);
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# endif
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# else
printf ("vax-dec-ultrix\n"); exit (0);
# endif
#endif
#if defined (alliant) && defined (i860)
printf ("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
}
EOF
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
# Apollos put the system type in the environment.
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
# Convex versions that predate uname can use getsysinfo(1)
if [ -x /usr/convex/getsysinfo ]
then
case `getsysinfo -f cpu_type` in
c1*)
echo c1-convex-bsd
exit 0 ;;
c2*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit 0 ;;
c34*)
echo c34-convex-bsd
exit 0 ;;
c38*)
echo c38-convex-bsd
exit 0 ;;
c4*)
echo c4-convex-bsd
exit 0 ;;
esac
fi
cat >&2 <<EOF
$0: unable to guess system type
This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
ftp://ftp.gnu.org/pub/gnu/config/
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
pertinent to <config-patches@gnu.org> in order to provide the needed
information to handle your system.
config.guess timestamp = $timestamp
uname -m = `(uname -m) 2>/dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`
/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
hostinfo = `(hostinfo) 2>/dev/null`
/bin/universe = `(/bin/universe) 2>/dev/null`
/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
/bin/arch = `(/bin/arch) 2>/dev/null`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
UNAME_MACHINE = ${UNAME_MACHINE}
UNAME_RELEASE = ${UNAME_RELEASE}
UNAME_SYSTEM = ${UNAME_SYSTEM}
UNAME_VERSION = ${UNAME_VERSION}
EOF
exit 1
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002 Free Software Foundation, Inc.
timestamp='2002-03-07'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
# Each package is responsible for reporting which valid configurations
# it does not support. The user should be able to distinguish
# a failure to support a valid configuration from a meaningless
# configuration.
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or in some cases, the newer four-part form:
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS
$0 [OPTION] ALIAS
Canonicalize a configuration name.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit 0 ;;
--version | -v )
echo "$version" ; exit 0 ;;
--help | --h* | -h )
echo "$usage"; exit 0 ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help"
exit 1 ;;
*local*)
# First pass through any local machine types.
echo $1
exit 0;;
* )
break ;;
esac
done
case $# in
0) echo "$me: missing argument$help" >&2
exit 1;;
1) ;;
*) echo "$me: too many arguments$help" >&2
exit 1;;
esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
then os=`echo $1 | sed 's/.*-/-/'`
else os=; fi
;;
esac
### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work. We also
### recognize some manufacturers as not being operating systems, so we
### can provide default operating systems below.
case $os in
-sun*os*)
# Prevent following clause from handling this invalid input.
;;
-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis)
os=
basic_machine=$1
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
;;
-scout)
;;
-wrs)
os=-vxworks
basic_machine=$1
;;
-chorusos*)
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco4)
os=-sco3.2v4
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-udk*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*)
os=-lynxos
;;
-ptx*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
;;
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;;
-psos*)
os=-psos
;;
-mint | -mint[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
| d10v | d30v | dsp16xx \
| fr30 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| m32r | m68000 | m68k | m88k | mcore \
| mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el | mips64vr4300 \
| mips64vr4300el | mips64vr5000 | mips64vr5000el \
| mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
| mipsisa32 | mipsisa64 \
| mn10200 | mn10300 \
| ns16k | ns32k \
| openrisc | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| sh | sh[34] | sh[34]eb | shbe | shle | sh64 \
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
| strongarm \
| tahoe | thumb | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xscale | xstormy16 | xtensa \
| z8k)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12.
basic_machine=$basic_machine-unknown
os=-none
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i*86 | x86_64)
basic_machine=$basic_machine-pc
;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armv*-* \
| avr-* \
| bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c54x-* \
| clipper-* | cydra-* \
| d10v-* | d30v-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| m32r-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \
| mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
| mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
| mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| ymp-* \
| z8k-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd)
basic_machine=i386-unknown
os=-bsd
;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
basic_machine=m68000-att
;;
3b*)
basic_machine=we32k-att
;;
a29khif)
basic_machine=a29k-amd
os=-udi
;;
adobe68k)
basic_machine=m68010-adobe
os=-scout
;;
alliant | fx80)
basic_machine=fx80-alliant
;;
altos | altos3068)
basic_machine=m68k-altos
;;
am29k)
basic_machine=a29k-none
os=-bsd
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
;;
amiga | amiga-*)
basic_machine=m68k-unknown
;;
amigaos | amigados)
basic_machine=m68k-unknown
os=-amigaos
;;
amigaunix | amix)
basic_machine=m68k-unknown
os=-sysv4
;;
apollo68)
basic_machine=m68k-apollo
os=-sysv
;;
apollo68bsd)
basic_machine=m68k-apollo
os=-bsd
;;
aux)
basic_machine=m68k-apple
os=-aux
;;
balance)
basic_machine=ns32k-sequent
os=-dynix
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
;;
convex-c2)
basic_machine=c2-convex
os=-bsd
;;
convex-c32)
basic_machine=c32-convex
os=-bsd
;;
convex-c34)
basic_machine=c34-convex
os=-bsd
;;
convex-c38)
basic_machine=c38-convex
os=-bsd
;;
cray | j90)
basic_machine=j90-cray
os=-unicos
;;
crds | unos)
basic_machine=m68k-crds
;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
decsystem10* | dec10*)
basic_machine=pdp10-dec
os=-tops10
;;
decsystem20* | dec20*)
basic_machine=pdp10-dec
os=-tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
;;
delta88)
basic_machine=m88k-motorola
os=-sysv3
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
;;
dpx2* | dpx2*-bull)
basic_machine=m68k-bull
os=-sysv3
;;
ebmon29k)
basic_machine=a29k-amd
os=-ebmon
;;
elxsi)
basic_machine=elxsi-elxsi
os=-bsd
;;
encore | umax | mmax)
basic_machine=ns32k-encore
;;
es1800 | OSE68k | ose68k | ose | OSE)
basic_machine=m68k-ericsson
os=-ose
;;
fx2800)
basic_machine=i860-alliant
;;
genix)
basic_machine=ns32k-ns
;;
gmicro)
basic_machine=tron-gmicro
os=-sysv
;;
go32)
basic_machine=i386-pc
os=-go32
;;
h3050r* | hiux*)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
h8300hms)
basic_machine=h8300-hitachi
os=-hms
;;
h8300xray)
basic_machine=h8300-hitachi
os=-xray
;;
h8500hms)
basic_machine=h8500-hitachi
os=-hms
;;
harris)
basic_machine=m88k-harris
os=-sysv3
;;
hp300-*)
basic_machine=m68k-hp
;;
hp300bsd)
basic_machine=m68k-hp
os=-bsd
;;
hp300hpux)
basic_machine=m68k-hp
os=-hpux
;;
hp3k9[0-9][0-9] | hp9[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
basic_machine=m68000-hp
;;
hp9k3[2-9][0-9])
basic_machine=m68k-hp
;;
hp9k6[0-9][0-9] | hp6[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hp9k7[0-79][0-9] | hp7[0-79][0-9])
basic_machine=hppa1.1-hp
;;
hp9k78[0-9] | hp78[0-9])
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][13679] | hp8[0-9][13679])
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hppa-next)
os=-nextstep3
;;
hppaosf)
basic_machine=hppa1.1-hp
os=-osf
;;
hppro)
basic_machine=hppa1.1-hp
os=-proelf
;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i*86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i*86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i*86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
i386mach)
basic_machine=i386-mach
os=-mach
;;
i386-vsta | vsta)
basic_machine=i386-unknown
os=-vsta
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
-irix*)
;;
*)
os=-irix4
;;
esac
;;
isi68 | isi)
basic_machine=m68k-isi
os=-sysv
;;
m88k-omron*)
basic_machine=m88k-omron
;;
magnum | m3230)
basic_machine=mips-mips
os=-sysv
;;
merlin)
basic_machine=ns32k-utek
os=-sysv
;;
mingw32)
basic_machine=i386-pc
os=-mingw32
;;
miniframe)
basic_machine=m68000-convergent
;;
*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
mmix*)
basic_machine=mmix-knuth
os=-mmixware
;;
monitor)
basic_machine=m68k-rom68k
os=-coff
;;
morphos)
basic_machine=powerpc-unknown
os=-morphos
;;
msdos)
basic_machine=i386-pc
os=-msdos
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
;;
netbsd386)
basic_machine=i386-unknown
os=-netbsd
;;
netwinder)
basic_machine=armv4l-rebel
os=-linux
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
os=-newsos
;;
news1000)
basic_machine=m68030-sony
os=-newsos
;;
news-3600 | risc-news)
basic_machine=mips-sony
os=-newsos
;;
necv70)
basic_machine=v70-nec
os=-sysv
;;
next | m*-next )
basic_machine=m68k-next
case $os in
-nextstep* )
;;
-ns2*)
os=-nextstep2
;;
*)
os=-nextstep3
;;
esac
;;
nh3000)
basic_machine=m68k-harris
os=-cxux
;;
nh[45]000)
basic_machine=m88k-harris
os=-cxux
;;
nindy960)
basic_machine=i960-intel
os=-nindy
;;
mon960)
basic_machine=i960-intel
os=-mon960
;;
nonstopux)
basic_machine=mips-compaq
os=-nonstopux
;;
np1)
basic_machine=np1-gould
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
;;
or32 | or32-*)
basic_machine=or32-unknown
os=-coff
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
;;
os68k)
basic_machine=m68k-none
os=-os68k
;;
pa-hitachi)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
paragon)
basic_machine=i860-intel
os=-osf
;;
pbd)
basic_machine=sparc-tti
;;
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon)
basic_machine=i686-pc
;;
pentiumii | pentium2)
basic_machine=i686-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
pw32)
basic_machine=i586-unknown
os=-pw32
;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
;;
rm[46]00)
basic_machine=mips-siemens
;;
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
s390 | s390-*)
basic_machine=s390-ibm
;;
s390x | s390x-*)
basic_machine=s390x-ibm
;;
sa29200)
basic_machine=a29k-amd
os=-udi
;;
sequent)
basic_machine=i386-sequent
;;
sh)
basic_machine=sh-hitachi
os=-hms
;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
sps7)
basic_machine=m68k-bull
os=-sysv2
;;
spur)
basic_machine=spur-unknown
;;
st2000)
basic_machine=m68k-tandem
;;
stratus)
basic_machine=i860-stratus
os=-sysv4
;;
sun2)
basic_machine=m68000-sun
;;
sun2os3)
basic_machine=m68000-sun
os=-sunos3
;;
sun2os4)
basic_machine=m68000-sun
os=-sunos4
;;
sun3os3)
basic_machine=m68k-sun
os=-sunos3
;;
sun3os4)
basic_machine=m68k-sun
os=-sunos4
;;
sun4os3)
basic_machine=sparc-sun
os=-sunos3
;;
sun4os4)
basic_machine=sparc-sun
os=-sunos4
;;
sun4sol2)
basic_machine=sparc-sun
os=-solaris2
;;
sun3 | sun3-*)
basic_machine=m68k-sun
;;
sun4)
basic_machine=sparc-sun
;;
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
sv1)
basic_machine=sv1-cray
os=-unicos
;;
symmetry)
basic_machine=i386-sequent
os=-dynix
;;
t3d)
basic_machine=alpha-cray
os=-unicos
;;
t3e)
basic_machine=alphaev5-cray
os=-unicos
;;
t90)
basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
toad1)
basic_machine=pdp10-xkl
os=-tops20
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
udi29k)
basic_machine=a29k-amd
os=-udi
;;
ultra3)
basic_machine=a29k-nyu
os=-sym1
;;
v810 | necv810)
basic_machine=v810-nec
os=-none
;;
vaxv)
basic_machine=vax-dec
os=-sysv
;;
vms)
basic_machine=vax-dec
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
;;
vxworks68)
basic_machine=m68k-wrs
os=-vxworks
;;
vxworks29k)
basic_machine=a29k-wrs
os=-vxworks
;;
w65*)
basic_machine=w65-wdc
os=-none
;;
w89k-*)
basic_machine=hppa1.1-winbond
os=-proelf
;;
windows32)
basic_machine=i386-pc
os=-windows32-msvcrt
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
ymp)
basic_machine=ymp-cray
os=-unicos
;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
;;
none)
basic_machine=none-none
os=-none
;;
# Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular.
w89k)
basic_machine=hppa1.1-winbond
;;
op50n)
basic_machine=hppa1.1-oki
;;
op60c)
basic_machine=hppa1.1-oki
;;
romp)
basic_machine=romp-ibm
;;
rs6000)
basic_machine=rs6000-ibm
;;
vax)
basic_machine=vax-dec
;;
pdp10)
# there are many clones, so DEC is not a safe bet
basic_machine=pdp10-unknown
;;
pdp11)
basic_machine=pdp11-dec
;;
we32k)
basic_machine=we32k-att
;;
sh3 | sh4 | sh3eb | sh4eb)
basic_machine=sh-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
cydra)
basic_machine=cydra-cydrome
;;
orion)
basic_machine=orion-highlevel
;;
orion105)
basic_machine=clipper-highlevel
;;
mac | mpw | mac-mpw)
basic_machine=m68k-apple
;;
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
c4x*)
basic_machine=c4x-none
os=-coff
;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
esac
# Here we canonicalize certain aliases for manufacturers.
case $basic_machine in
*-digital*)
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
;;
*-commodore*)
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
;;
*)
;;
esac
# Decode manufacturer-specific aliases for certain operating systems.
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
-solaris)
os=-solaris2
;;
-svr4*)
os=-sysv4
;;
-unixware*)
os=-sysv4.2uw
;;
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
# First accept the basic system types.
# The portable systems comes first.
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
case $basic_machine in
x86-* | i*86-*)
;;
*)
os=-nto$os
;;
esac
;;
-nto*)
os=-nto-qnx
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
;;
-sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'`
;;
-opened*)
os=-openedition
;;
-wince*)
os=-wince
;;
-osfrose*)
os=-osfrose
;;
-osf*)
os=-osf
;;
-utek*)
os=-bsd
;;
-dynix*)
os=-bsd
;;
-acis*)
os=-aos
;;
-atheos*)
os=-atheos
;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
-nova*)
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
;;
-nsk*)
os=-nsk
;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
;;
-sinix*)
os=-sysv4
;;
-triton*)
os=-sysv3
;;
-oss*)
os=-sysv3
;;
-svr4)
os=-sysv4
;;
-svr3)
os=-sysv3
;;
-sysvr4)
os=-sysv4
;;
# This must come after -sysvr4.
-sysv*)
;;
-ose*)
os=-ose
;;
-es1800*)
os=-ose
;;
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-none)
;;
*)
# Get rid of the `-' at the beginning of $os.
os=`echo $os | sed 's/[^-]*-//'`
echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
exit 1
;;
esac
else
# Here we handle the default operating systems that come with various machines.
# The value should be what the vendor currently ships out the door with their
# machine or put another way, the most popular os provided with the machine.
# Note that if you're going to try to match "-MANUFACTURER" here (say,
# "-sun"), then you have to tell the case statement up towards the top
# that MANUFACTURER isn't an operating system. Otherwise, code above
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.
case $basic_machine in
*-acorn)
os=-riscix1.2
;;
arm*-rebel)
os=-linux
;;
arm*-semi)
os=-aout
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
pdp11-*)
os=-none
;;
*-dec | vax-*)
os=-ultrix4.2
;;
m68*-apollo)
os=-domain
;;
i386-sun)
os=-sunos4.0.2
;;
m68000-sun)
os=-sunos3
# This also exists in the configure program, but was not the
# default.
# os=-sunos4
;;
m68*-cisco)
os=-aout
;;
mips*-cisco)
os=-elf
;;
mips*-*)
os=-elf
;;
or32-*)
os=-coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
sparc-* | *-sun)
os=-sunos4.1.1
;;
*-be)
os=-beos
;;
*-ibm)
os=-aix
;;
*-wec)
os=-proelf
;;
*-winbond)
os=-proelf
;;
*-oki)
os=-proelf
;;
*-hp)
os=-hpux
;;
*-hitachi)
os=-hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
os=-sysv
;;
*-cbm)
os=-amigaos
;;
*-dg)
os=-dgux
;;
*-dolphin)
os=-sysv3
;;
m68k-ccur)
os=-rtu
;;
m88k-omron*)
os=-luna
;;
*-next )
os=-nextstep
;;
*-sequent)
os=-ptx
;;
*-crds)
os=-unos
;;
*-ns)
os=-genix
;;
i370-*)
os=-mvs
;;
*-next)
os=-nextstep3
;;
*-gould)
os=-sysv
;;
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
os=-irix
;;
*-siemens)
os=-sysv4
;;
*-masscomp)
os=-rtu
;;
f30[01]-fujitsu | f700-fujitsu)
os=-uxpv
;;
*-rom68k)
os=-coff
;;
*-*bug)
os=-coff
;;
*-apple)
os=-macos
;;
*-atari*)
os=-mint
;;
*)
os=-none
;;
esac
fi
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
vendor=unknown
case $basic_machine in
*-unknown)
case $os in
-riscix*)
vendor=acorn
;;
-sunos*)
vendor=sun
;;
-aix*)
vendor=ibm
;;
-beos*)
vendor=be
;;
-hpux*)
vendor=hp
;;
-mpeix*)
vendor=hp
;;
-hiux*)
vendor=hitachi
;;
-unos*)
vendor=crds
;;
-dgux*)
vendor=dg
;;
-luna*)
vendor=omron
;;
-genix*)
vendor=ns
;;
-mvs* | -opened*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-vxsim* | -vxworks*)
vendor=wrs
;;
-aux*)
vendor=apple
;;
-hms*)
vendor=hitachi
;;
-mpw* | -macos*)
vendor=apple
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
vendor=atari
;;
-vos*)
vendor=stratus
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
esac
echo $basic_machine$os
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
This source diff could not be displayed because it is too large. You can view the blob instead.
AC_INIT(main.c)
AM_INIT_AUTOMAKE(mpd, 0.7.0)
AC_CONFIG_SUBDIRS(libmad)
CFLAGS="-Wall"
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_LIBTOOL
dnl MAD wants this stuff
AC_SUBST(CCAS)
AC_SUBST(CCASFLAGS)
AM_PATH_AO(LIBS="$LIBS $AO_LIBS" CFLAGS="$CFLAGS $AO_CFLAGS",AC_MSG_ERROR(Must have libao installed!!!))
AC_CHECK_HEADER(sys/soundcard.h,CFLAGS="$CFLAGS",[CFLAGS="$CFLAGS -DNO_LINUX_OSS_MIXER";AC_MSG_WARN(Soundcard headers not found -- disabling mixer)])
AC_ARG_ENABLE(ogg,[ --disable-ogg disable ogg support],,enable_ogg=yes)
if test x$enable_ogg = xyes; then
AM_PATH_OGG(LIBS="$LIBS $OGG_LIBS" CFLAGS="$CFLAGS $OGG_CFLAGS",enable_ogg=no)
fi
if test x$enable_ogg = xyes; then
AM_PATH_VORBIS(LIBS="$LIBS $VORBIS_LIBS $VORBISFILE_LIBS" CFLAGS="$CFLAGS $VORBIS_CFLAGS $VORBISFILE_CFLAGS",enable_ogg=no)
fi
if test x$enable_ogg = xyes; then
CFLAGS="$CFLAGS -DHAVE_OGG"
fi
AC_OUTPUT(Makefile libmad/Makefile id3v1lib/Makefile id3v2lib/Makefile)
......@@ -22,6 +22,7 @@
#include "command.h"
#include "tables.h"
#include "utils.h"
#include "path.h"
#include <string.h>
#include <sys/types.h>
......@@ -145,7 +146,7 @@ int removeDeletedFromDirectory(Directory * directory) {
cwd[1] = '\0';
if(dirname==NULL) dirname=cwd;
if((dir = opendir(dirname))==NULL) return -1;
if((dir = opendir(rmp2amp(dirname)))==NULL) return -1;
while((ent = readdir(dir))) {
if(ent->d_name[0]=='.') continue; /* hide hidden stuff */
......@@ -208,7 +209,7 @@ int updateDirectory(Directory * directory) {
removeDeletedFromDirectory(directory);
}
if((dir = opendir(dirname))==NULL) return -1;
if((dir = opendir(rmp2amp(dirname)))==NULL) return -1;
while((ent = readdir(dir))) {
if(ent->d_name[0]=='.') continue; /* hide hidden stuff */
......@@ -239,7 +240,7 @@ int exploreDirectory(Directory * directory) {
cwd[1] = '\0';
if(dirname==NULL) dirname=cwd;
if((dir = opendir(dirname))==NULL) return -1;
if((dir = opendir(rmp2amp(dirname)))==NULL) return -1;
printf("explore: %s\n",dirname);
while((ent = readdir(dir))) {
......
noinst_LIBRARIES=libid3v1.a
libid3v1_a_headers = lib_id3v1.h genre.h
libid3v1_a_SOURCES = lib_id3v1.c $(libid3v1_a_headers)
# Makefile.in generated automatically by automake 1.4-p4 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
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 = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
AO_CFLAGS = @AO_CFLAGS@
AO_LIBS = @AO_LIBS@
AS = @AS@
CC = @CC@
CCAS = @CCAS@
CCASFLAGS = @CCASFLAGS@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
EXEEXT = @EXEEXT@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OGG_CFLAGS = @OGG_CFLAGS@
OGG_LIBS = @OGG_LIBS@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
STRIP = @STRIP@
VERSION = @VERSION@
VORBISENC_LIBS = @VORBISENC_LIBS@
VORBISFILE_LIBS = @VORBISFILE_LIBS@
VORBIS_CFLAGS = @VORBIS_CFLAGS@
VORBIS_LIBS = @VORBIS_LIBS@
noinst_LIBRARIES = libid3v1.a
libid3v1_a_headers = lib_id3v1.h genre.h
libid3v1_a_SOURCES = lib_id3v1.c $(libid3v1_a_headers)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
DEFS = @DEFS@ -I. -I$(srcdir)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libid3v1_a_LIBADD =
libid3v1_a_OBJECTS = lib_id3v1.$(OBJEXT)
AR = ar
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = README COPYING Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
SOURCES = $(libid3v1_a_SOURCES)
OBJECTS = $(libid3v1_a_OBJECTS)
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .lo .o .obj .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps id3v1lib/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
mostlyclean-noinstLIBRARIES:
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
distclean-noinstLIBRARIES:
maintainer-clean-noinstLIBRARIES:
.c.o:
$(COMPILE) -c $<
# FIXME: We should only use cygpath when building on Windows,
# and only if it is available.
.c.obj:
$(COMPILE) -c `cygpath -w $<`
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
-rm -f *.$(OBJEXT)
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
.c.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.S.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
maintainer-clean-libtool:
libid3v1.a: $(libid3v1_a_OBJECTS) $(libid3v1_a_DEPENDENCIES)
-rm -f libid3v1.a
$(AR) cru libid3v1.a $(libid3v1_a_OBJECTS) $(libid3v1_a_LIBADD)
$(RANLIB) libid3v1.a
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = id3v1lib
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am:
install-exec: install-exec-am
install-data-am:
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am:
uninstall: uninstall-am
all-am: Makefile $(LIBRARIES)
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
mostlyclean-libtool mostlyclean-tags \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-noinstLIBRARIES clean-compile clean-libtool clean-tags \
clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-noinstLIBRARIES distclean-compile \
distclean-libtool distclean-tags distclean-generic \
clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
maintainer-clean-tags maintainer-clean-generic \
distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-am
.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
install-exec install-data-am install-data install-am install \
uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
noinst_LIBRARIES=libid3v2.a
libid3v2_a_headers = charset.h lib_id3v2.2.h lib_id3v2.3.h genre.h
libid3v2_a_SOURCES = charset.c lib_id3v2.2.c lib_id3v2.3.c $(libid3v2_a_headers)
# Makefile.in generated automatically by automake 1.4-p4 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
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 = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
AO_CFLAGS = @AO_CFLAGS@
AO_LIBS = @AO_LIBS@
AS = @AS@
CC = @CC@
CCAS = @CCAS@
CCASFLAGS = @CCASFLAGS@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
EXEEXT = @EXEEXT@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OGG_CFLAGS = @OGG_CFLAGS@
OGG_LIBS = @OGG_LIBS@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
STRIP = @STRIP@
VERSION = @VERSION@
VORBISENC_LIBS = @VORBISENC_LIBS@
VORBISFILE_LIBS = @VORBISFILE_LIBS@
VORBIS_CFLAGS = @VORBIS_CFLAGS@
VORBIS_LIBS = @VORBIS_LIBS@
noinst_LIBRARIES = libid3v2.a
libid3v2_a_headers = charset.h lib_id3v2.2.h lib_id3v2.3.h genre.h
libid3v2_a_SOURCES = charset.c lib_id3v2.2.c lib_id3v2.3.c $(libid3v2_a_headers)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
DEFS = @DEFS@ -I. -I$(srcdir)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libid3v2_a_LIBADD =
libid3v2_a_OBJECTS = charset.$(OBJEXT) lib_id3v2.2.$(OBJEXT) \
lib_id3v2.3.$(OBJEXT)
AR = ar
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = README COPYING Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
SOURCES = $(libid3v2_a_SOURCES)
OBJECTS = $(libid3v2_a_OBJECTS)
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .lo .o .obj .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps id3v2lib/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
mostlyclean-noinstLIBRARIES:
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
distclean-noinstLIBRARIES:
maintainer-clean-noinstLIBRARIES:
.c.o:
$(COMPILE) -c $<
# FIXME: We should only use cygpath when building on Windows,
# and only if it is available.
.c.obj:
$(COMPILE) -c `cygpath -w $<`
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
-rm -f *.$(OBJEXT)
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
.c.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.S.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
maintainer-clean-libtool:
libid3v2.a: $(libid3v2_a_OBJECTS) $(libid3v2_a_DEPENDENCIES)
-rm -f libid3v2.a
$(AR) cru libid3v2.a $(libid3v2_a_OBJECTS) $(libid3v2_a_LIBADD)
$(RANLIB) libid3v2.a
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = id3v2lib
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am:
install-exec: install-exec-am
install-data-am:
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am:
uninstall: uninstall-am
all-am: Makefile $(LIBRARIES)
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
mostlyclean-libtool mostlyclean-tags \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-noinstLIBRARIES clean-compile clean-libtool clean-tags \
clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-noinstLIBRARIES distclean-compile \
distclean-libtool distclean-tags distclean-generic \
clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
maintainer-clean-tags maintainer-clean-generic \
distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-am
.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
install-exec install-data-am install-data install-am install \
uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0
......@@ -30,13 +30,11 @@
#include <string.h>
#include <fcntl.h>
#define VERSION "0.6.2"
#define GREETING "MPD"
#define INTERFACE_MAX_BUFFER_LENGTH 1024
#define INTERFACE_MAX_CONNECTIONS 5
int interface_max_connections;
int interface_timeout;
typedef struct _Interface {
......@@ -48,7 +46,7 @@ typedef struct _Interface {
time_t lastTime;
} Interface;
Interface interfaces[INTERFACE_MAX_CONNECTIONS];
Interface * interfaces = NULL;
void openInterface(Interface * interface, int fd) {
assert(interface->open==0);
......@@ -77,9 +75,9 @@ void closeInterface(Interface * interface) {
void openAInterface(int fd) {
int i;
for(i=0;i<INTERFACE_MAX_CONNECTIONS && interfaces[i].open;i++);
for(i=0;i<interface_max_connections && interfaces[i].open;i++);
if(i==INTERFACE_MAX_CONNECTIONS) {
if(i==interface_max_connections) {
FILE * fp = fdopen(fd,"w");
fprintf(fp,"%s Max Connections Reached!\n",COMMAND_RESPOND_ERROR);
fclose(fp);
......@@ -134,7 +132,7 @@ void addInterfacesToFdSet(fd_set * fds) {
FD_ZERO(fds);
for(i=0;i<INTERFACE_MAX_CONNECTIONS;i++) {
for(i=0;i<interface_max_connections;i++) {
if(interfaces[i].open) {
FD_SET(interfaces[i].fd,fds);
}
......@@ -152,7 +150,7 @@ int readInputFromInterfaces() {
addInterfacesToFdSet(&fds);
while(select(FD_SETSIZE,&fds,NULL,NULL,&tv)) {
for(i=0;i<INTERFACE_MAX_CONNECTIONS;i++) {
for(i=0;i<interface_max_connections;i++) {
if(interfaces[i].open && FD_ISSET(interfaces[i].fd,&fds)) {
if(COMMAND_RETURN_KILL==interfaceReadInput(&(interfaces[i]))) {
return COMMAND_RETURN_KILL;
......@@ -170,41 +168,45 @@ void initInterfaces() {
int i;
char * test;
for(i=0;i<INTERFACE_MAX_CONNECTIONS;i++) {
interfaces[i].open = 0;
}
interface_timeout = strtol((getConf())[CONF_CONNECTION_TIMEOUT],&test,10);
if(*test!='\0') {
fprintf(stderr,"connection timeout \"%s\" is not an integer\n",(getConf())[CONF_CONNECTION_TIMEOUT]);
exit(-1);
}
interface_max_connections = strtol((getConf())[CONF_MAX_CONNECTIONS],&test,10);
if(*test!='\0') {
fprintf(stderr,"max connections \"%s\" is not an integer\n",(getConf())[CONF_MAX_CONNECTIONS]);
exit(-1);
}
interfaces = malloc(sizeof(Interface)*interface_max_connections);
for(i=0;i<interface_max_connections;i++) {
interfaces[i].open = 0;
}
}
void closeAllInterfaces() {
int i;
for(i=0;i<INTERFACE_MAX_CONNECTIONS;i++) {
for(i=0;i<interface_max_connections;i++) {
if(interfaces[i].open) {
closeInterface(&(interfaces[i]));
}
}
}
void closeAllInterfaceFDs() {
int i;
void freeAllInterfaces() {
closeAllInterfaces();
for(i=0;i<INTERFACE_MAX_CONNECTIONS;i++) {
if(interfaces[i].open) {
close(interfaces[i].fd);
}
}
free(interfaces);
}
void closeOldInterfaces() {
int i;
for(i=0;i<INTERFACE_MAX_CONNECTIONS;i++) {
for(i=0;i<interface_max_connections;i++) {
if(interfaces[i].open && (time(NULL)-interfaces[i].lastTime>interface_timeout)) {
closeInterface(&(interfaces[i]));
}
......
......@@ -25,7 +25,7 @@
void initInterfaces();
void openAInterface(int fd);
void closeAllInterfaces();
void closeAllInterfaceFDs();
void freeAllInterfaces();
void closeOldInterfaces();
int readInputFromInterfaces();
......
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
libmad - MPEG audio decoder library
Copyright (C) 2000-2001 Robert Leslie
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
If you would like to negotiate alternate licensing terms, you may do
so by contacting the author: Robert Leslie <rob@mars.org>
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: D.dat,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
/*
* These are the coefficients for the subband synthesis window. This is a
* reordered version of Table B.3 from ISO/IEC 11172-3.
*
* Every value is parameterized so that shift optimizations can be made at
* compile-time. For example, every value can be right-shifted 12 bits to
* minimize multiply instruction times without any loss of accuracy.
*/
{ PRESHIFT(0x00000000) /* 0.000000000 */, /* 0 */
-PRESHIFT(0x0001d000) /* -0.000442505 */,
PRESHIFT(0x000d5000) /* 0.003250122 */,
-PRESHIFT(0x001cb000) /* -0.007003784 */,
PRESHIFT(0x007f5000) /* 0.031082153 */,
-PRESHIFT(0x01421000) /* -0.078628540 */,
PRESHIFT(0x019ae000) /* 0.100311279 */,
-PRESHIFT(0x09271000) /* -0.572036743 */,
PRESHIFT(0x1251e000) /* 1.144989014 */,
PRESHIFT(0x09271000) /* 0.572036743 */,
PRESHIFT(0x019ae000) /* 0.100311279 */,
PRESHIFT(0x01421000) /* 0.078628540 */,
PRESHIFT(0x007f5000) /* 0.031082153 */,
PRESHIFT(0x001cb000) /* 0.007003784 */,
PRESHIFT(0x000d5000) /* 0.003250122 */,
PRESHIFT(0x0001d000) /* 0.000442505 */,
PRESHIFT(0x00000000) /* 0.000000000 */,
-PRESHIFT(0x0001d000) /* -0.000442505 */,
PRESHIFT(0x000d5000) /* 0.003250122 */,
-PRESHIFT(0x001cb000) /* -0.007003784 */,
PRESHIFT(0x007f5000) /* 0.031082153 */,
-PRESHIFT(0x01421000) /* -0.078628540 */,
PRESHIFT(0x019ae000) /* 0.100311279 */,
-PRESHIFT(0x09271000) /* -0.572036743 */,
PRESHIFT(0x1251e000) /* 1.144989014 */,
PRESHIFT(0x09271000) /* 0.572036743 */,
PRESHIFT(0x019ae000) /* 0.100311279 */,
PRESHIFT(0x01421000) /* 0.078628540 */,
PRESHIFT(0x007f5000) /* 0.031082153 */,
PRESHIFT(0x001cb000) /* 0.007003784 */,
PRESHIFT(0x000d5000) /* 0.003250122 */,
PRESHIFT(0x0001d000) /* 0.000442505 */ },
{ -PRESHIFT(0x00001000) /* -0.000015259 */, /* 1 */
-PRESHIFT(0x0001f000) /* -0.000473022 */,
PRESHIFT(0x000da000) /* 0.003326416 */,
-PRESHIFT(0x00207000) /* -0.007919312 */,
PRESHIFT(0x007d0000) /* 0.030517578 */,
-PRESHIFT(0x0158d000) /* -0.084182739 */,
PRESHIFT(0x01747000) /* 0.090927124 */,
-PRESHIFT(0x099a8000) /* -0.600219727 */,
PRESHIFT(0x124f0000) /* 1.144287109 */,
PRESHIFT(0x08b38000) /* 0.543823242 */,
PRESHIFT(0x01bde000) /* 0.108856201 */,
PRESHIFT(0x012b4000) /* 0.073059082 */,
PRESHIFT(0x0080f000) /* 0.031478882 */,
PRESHIFT(0x00191000) /* 0.006118774 */,
PRESHIFT(0x000d0000) /* 0.003173828 */,
PRESHIFT(0x0001a000) /* 0.000396729 */,
-PRESHIFT(0x00001000) /* -0.000015259 */,
-PRESHIFT(0x0001f000) /* -0.000473022 */,
PRESHIFT(0x000da000) /* 0.003326416 */,
-PRESHIFT(0x00207000) /* -0.007919312 */,
PRESHIFT(0x007d0000) /* 0.030517578 */,
-PRESHIFT(0x0158d000) /* -0.084182739 */,
PRESHIFT(0x01747000) /* 0.090927124 */,
-PRESHIFT(0x099a8000) /* -0.600219727 */,
PRESHIFT(0x124f0000) /* 1.144287109 */,
PRESHIFT(0x08b38000) /* 0.543823242 */,
PRESHIFT(0x01bde000) /* 0.108856201 */,
PRESHIFT(0x012b4000) /* 0.073059082 */,
PRESHIFT(0x0080f000) /* 0.031478882 */,
PRESHIFT(0x00191000) /* 0.006118774 */,
PRESHIFT(0x000d0000) /* 0.003173828 */,
PRESHIFT(0x0001a000) /* 0.000396729 */ },
{ -PRESHIFT(0x00001000) /* -0.000015259 */, /* 2 */
-PRESHIFT(0x00023000) /* -0.000534058 */,
PRESHIFT(0x000de000) /* 0.003387451 */,
-PRESHIFT(0x00245000) /* -0.008865356 */,
PRESHIFT(0x007a0000) /* 0.029785156 */,
-PRESHIFT(0x016f7000) /* -0.089706421 */,
PRESHIFT(0x014a8000) /* 0.080688477 */,
-PRESHIFT(0x0a0d8000) /* -0.628295898 */,
PRESHIFT(0x12468000) /* 1.142211914 */,
PRESHIFT(0x083ff000) /* 0.515609741 */,
PRESHIFT(0x01dd8000) /* 0.116577148 */,
PRESHIFT(0x01149000) /* 0.067520142 */,
PRESHIFT(0x00820000) /* 0.031738281 */,
PRESHIFT(0x0015b000) /* 0.005294800 */,
PRESHIFT(0x000ca000) /* 0.003082275 */,
PRESHIFT(0x00018000) /* 0.000366211 */,
-PRESHIFT(0x00001000) /* -0.000015259 */,
-PRESHIFT(0x00023000) /* -0.000534058 */,
PRESHIFT(0x000de000) /* 0.003387451 */,
-PRESHIFT(0x00245000) /* -0.008865356 */,
PRESHIFT(0x007a0000) /* 0.029785156 */,
-PRESHIFT(0x016f7000) /* -0.089706421 */,
PRESHIFT(0x014a8000) /* 0.080688477 */,
-PRESHIFT(0x0a0d8000) /* -0.628295898 */,
PRESHIFT(0x12468000) /* 1.142211914 */,
PRESHIFT(0x083ff000) /* 0.515609741 */,
PRESHIFT(0x01dd8000) /* 0.116577148 */,
PRESHIFT(0x01149000) /* 0.067520142 */,
PRESHIFT(0x00820000) /* 0.031738281 */,
PRESHIFT(0x0015b000) /* 0.005294800 */,
PRESHIFT(0x000ca000) /* 0.003082275 */,
PRESHIFT(0x00018000) /* 0.000366211 */ },
{ -PRESHIFT(0x00001000) /* -0.000015259 */, /* 3 */
-PRESHIFT(0x00026000) /* -0.000579834 */,
PRESHIFT(0x000e1000) /* 0.003433228 */,
-PRESHIFT(0x00285000) /* -0.009841919 */,
PRESHIFT(0x00765000) /* 0.028884888 */,
-PRESHIFT(0x0185d000) /* -0.095169067 */,
PRESHIFT(0x011d1000) /* 0.069595337 */,
-PRESHIFT(0x0a7fe000) /* -0.656219482 */,
PRESHIFT(0x12386000) /* 1.138763428 */,
PRESHIFT(0x07ccb000) /* 0.487472534 */,
PRESHIFT(0x01f9c000) /* 0.123474121 */,
PRESHIFT(0x00fdf000) /* 0.061996460 */,
PRESHIFT(0x00827000) /* 0.031845093 */,
PRESHIFT(0x00126000) /* 0.004486084 */,
PRESHIFT(0x000c4000) /* 0.002990723 */,
PRESHIFT(0x00015000) /* 0.000320435 */,
-PRESHIFT(0x00001000) /* -0.000015259 */,
-PRESHIFT(0x00026000) /* -0.000579834 */,
PRESHIFT(0x000e1000) /* 0.003433228 */,
-PRESHIFT(0x00285000) /* -0.009841919 */,
PRESHIFT(0x00765000) /* 0.028884888 */,
-PRESHIFT(0x0185d000) /* -0.095169067 */,
PRESHIFT(0x011d1000) /* 0.069595337 */,
-PRESHIFT(0x0a7fe000) /* -0.656219482 */,
PRESHIFT(0x12386000) /* 1.138763428 */,
PRESHIFT(0x07ccb000) /* 0.487472534 */,
PRESHIFT(0x01f9c000) /* 0.123474121 */,
PRESHIFT(0x00fdf000) /* 0.061996460 */,
PRESHIFT(0x00827000) /* 0.031845093 */,
PRESHIFT(0x00126000) /* 0.004486084 */,
PRESHIFT(0x000c4000) /* 0.002990723 */,
PRESHIFT(0x00015000) /* 0.000320435 */ },
{ -PRESHIFT(0x00001000) /* -0.000015259 */, /* 4 */
-PRESHIFT(0x00029000) /* -0.000625610 */,
PRESHIFT(0x000e3000) /* 0.003463745 */,
-PRESHIFT(0x002c7000) /* -0.010848999 */,
PRESHIFT(0x0071e000) /* 0.027801514 */,
-PRESHIFT(0x019bd000) /* -0.100540161 */,
PRESHIFT(0x00ec0000) /* 0.057617187 */,
-PRESHIFT(0x0af15000) /* -0.683914185 */,
PRESHIFT(0x12249000) /* 1.133926392 */,
PRESHIFT(0x075a0000) /* 0.459472656 */,
PRESHIFT(0x0212c000) /* 0.129577637 */,
PRESHIFT(0x00e79000) /* 0.056533813 */,
PRESHIFT(0x00825000) /* 0.031814575 */,
PRESHIFT(0x000f4000) /* 0.003723145 */,
PRESHIFT(0x000be000) /* 0.002899170 */,
PRESHIFT(0x00013000) /* 0.000289917 */,
-PRESHIFT(0x00001000) /* -0.000015259 */,
-PRESHIFT(0x00029000) /* -0.000625610 */,
PRESHIFT(0x000e3000) /* 0.003463745 */,
-PRESHIFT(0x002c7000) /* -0.010848999 */,
PRESHIFT(0x0071e000) /* 0.027801514 */,
-PRESHIFT(0x019bd000) /* -0.100540161 */,
PRESHIFT(0x00ec0000) /* 0.057617187 */,
-PRESHIFT(0x0af15000) /* -0.683914185 */,
PRESHIFT(0x12249000) /* 1.133926392 */,
PRESHIFT(0x075a0000) /* 0.459472656 */,
PRESHIFT(0x0212c000) /* 0.129577637 */,
PRESHIFT(0x00e79000) /* 0.056533813 */,
PRESHIFT(0x00825000) /* 0.031814575 */,
PRESHIFT(0x000f4000) /* 0.003723145 */,
PRESHIFT(0x000be000) /* 0.002899170 */,
PRESHIFT(0x00013000) /* 0.000289917 */ },
{ -PRESHIFT(0x00001000) /* -0.000015259 */, /* 5 */
-PRESHIFT(0x0002d000) /* -0.000686646 */,
PRESHIFT(0x000e4000) /* 0.003479004 */,
-PRESHIFT(0x0030b000) /* -0.011886597 */,
PRESHIFT(0x006cb000) /* 0.026535034 */,
-PRESHIFT(0x01b17000) /* -0.105819702 */,
PRESHIFT(0x00b77000) /* 0.044784546 */,
-PRESHIFT(0x0b619000) /* -0.711318970 */,
PRESHIFT(0x120b4000) /* 1.127746582 */,
PRESHIFT(0x06e81000) /* 0.431655884 */,
PRESHIFT(0x02288000) /* 0.134887695 */,
PRESHIFT(0x00d17000) /* 0.051132202 */,
PRESHIFT(0x0081b000) /* 0.031661987 */,
PRESHIFT(0x000c5000) /* 0.003005981 */,
PRESHIFT(0x000b7000) /* 0.002792358 */,
PRESHIFT(0x00011000) /* 0.000259399 */,
-PRESHIFT(0x00001000) /* -0.000015259 */,
-PRESHIFT(0x0002d000) /* -0.000686646 */,
PRESHIFT(0x000e4000) /* 0.003479004 */,
-PRESHIFT(0x0030b000) /* -0.011886597 */,
PRESHIFT(0x006cb000) /* 0.026535034 */,
-PRESHIFT(0x01b17000) /* -0.105819702 */,
PRESHIFT(0x00b77000) /* 0.044784546 */,
-PRESHIFT(0x0b619000) /* -0.711318970 */,
PRESHIFT(0x120b4000) /* 1.127746582 */,
PRESHIFT(0x06e81000) /* 0.431655884 */,
PRESHIFT(0x02288000) /* 0.134887695 */,
PRESHIFT(0x00d17000) /* 0.051132202 */,
PRESHIFT(0x0081b000) /* 0.031661987 */,
PRESHIFT(0x000c5000) /* 0.003005981 */,
PRESHIFT(0x000b7000) /* 0.002792358 */,
PRESHIFT(0x00011000) /* 0.000259399 */ },
{ -PRESHIFT(0x00001000) /* -0.000015259 */, /* 6 */
-PRESHIFT(0x00031000) /* -0.000747681 */,
PRESHIFT(0x000e4000) /* 0.003479004 */,
-PRESHIFT(0x00350000) /* -0.012939453 */,
PRESHIFT(0x0066c000) /* 0.025085449 */,
-PRESHIFT(0x01c67000) /* -0.110946655 */,
PRESHIFT(0x007f5000) /* 0.031082153 */,
-PRESHIFT(0x0bd06000) /* -0.738372803 */,
PRESHIFT(0x11ec7000) /* 1.120223999 */,
PRESHIFT(0x06772000) /* 0.404083252 */,
PRESHIFT(0x023b3000) /* 0.139450073 */,
PRESHIFT(0x00bbc000) /* 0.045837402 */,
PRESHIFT(0x00809000) /* 0.031387329 */,
PRESHIFT(0x00099000) /* 0.002334595 */,
PRESHIFT(0x000b0000) /* 0.002685547 */,
PRESHIFT(0x00010000) /* 0.000244141 */,
-PRESHIFT(0x00001000) /* -0.000015259 */,
-PRESHIFT(0x00031000) /* -0.000747681 */,
PRESHIFT(0x000e4000) /* 0.003479004 */,
-PRESHIFT(0x00350000) /* -0.012939453 */,
PRESHIFT(0x0066c000) /* 0.025085449 */,
-PRESHIFT(0x01c67000) /* -0.110946655 */,
PRESHIFT(0x007f5000) /* 0.031082153 */,
-PRESHIFT(0x0bd06000) /* -0.738372803 */,
PRESHIFT(0x11ec7000) /* 1.120223999 */,
PRESHIFT(0x06772000) /* 0.404083252 */,
PRESHIFT(0x023b3000) /* 0.139450073 */,
PRESHIFT(0x00bbc000) /* 0.045837402 */,
PRESHIFT(0x00809000) /* 0.031387329 */,
PRESHIFT(0x00099000) /* 0.002334595 */,
PRESHIFT(0x000b0000) /* 0.002685547 */,
PRESHIFT(0x00010000) /* 0.000244141 */ },
{ -PRESHIFT(0x00002000) /* -0.000030518 */, /* 7 */
-PRESHIFT(0x00035000) /* -0.000808716 */,
PRESHIFT(0x000e3000) /* 0.003463745 */,
-PRESHIFT(0x00397000) /* -0.014022827 */,
PRESHIFT(0x005ff000) /* 0.023422241 */,
-PRESHIFT(0x01dad000) /* -0.115921021 */,
PRESHIFT(0x0043a000) /* 0.016510010 */,
-PRESHIFT(0x0c3d9000) /* -0.765029907 */,
PRESHIFT(0x11c83000) /* 1.111373901 */,
PRESHIFT(0x06076000) /* 0.376800537 */,
PRESHIFT(0x024ad000) /* 0.143264771 */,
PRESHIFT(0x00a67000) /* 0.040634155 */,
PRESHIFT(0x007f0000) /* 0.031005859 */,
PRESHIFT(0x0006f000) /* 0.001693726 */,
PRESHIFT(0x000a9000) /* 0.002578735 */,
PRESHIFT(0x0000e000) /* 0.000213623 */,
-PRESHIFT(0x00002000) /* -0.000030518 */,
-PRESHIFT(0x00035000) /* -0.000808716 */,
PRESHIFT(0x000e3000) /* 0.003463745 */,
-PRESHIFT(0x00397000) /* -0.014022827 */,
PRESHIFT(0x005ff000) /* 0.023422241 */,
-PRESHIFT(0x01dad000) /* -0.115921021 */,
PRESHIFT(0x0043a000) /* 0.016510010 */,
-PRESHIFT(0x0c3d9000) /* -0.765029907 */,
PRESHIFT(0x11c83000) /* 1.111373901 */,
PRESHIFT(0x06076000) /* 0.376800537 */,
PRESHIFT(0x024ad000) /* 0.143264771 */,
PRESHIFT(0x00a67000) /* 0.040634155 */,
PRESHIFT(0x007f0000) /* 0.031005859 */,
PRESHIFT(0x0006f000) /* 0.001693726 */,
PRESHIFT(0x000a9000) /* 0.002578735 */,
PRESHIFT(0x0000e000) /* 0.000213623 */ },
{ -PRESHIFT(0x00002000) /* -0.000030518 */, /* 8 */
-PRESHIFT(0x0003a000) /* -0.000885010 */,
PRESHIFT(0x000e0000) /* 0.003417969 */,
-PRESHIFT(0x003df000) /* -0.015121460 */,
PRESHIFT(0x00586000) /* 0.021575928 */,
-PRESHIFT(0x01ee6000) /* -0.120697021 */,
PRESHIFT(0x00046000) /* 0.001068115 */,
-PRESHIFT(0x0ca8d000) /* -0.791213989 */,
PRESHIFT(0x119e9000) /* 1.101211548 */,
PRESHIFT(0x05991000) /* 0.349868774 */,
PRESHIFT(0x02578000) /* 0.146362305 */,
PRESHIFT(0x0091a000) /* 0.035552979 */,
PRESHIFT(0x007d1000) /* 0.030532837 */,
PRESHIFT(0x00048000) /* 0.001098633 */,
PRESHIFT(0x000a1000) /* 0.002456665 */,
PRESHIFT(0x0000d000) /* 0.000198364 */,
-PRESHIFT(0x00002000) /* -0.000030518 */,
-PRESHIFT(0x0003a000) /* -0.000885010 */,
PRESHIFT(0x000e0000) /* 0.003417969 */,
-PRESHIFT(0x003df000) /* -0.015121460 */,
PRESHIFT(0x00586000) /* 0.021575928 */,
-PRESHIFT(0x01ee6000) /* -0.120697021 */,
PRESHIFT(0x00046000) /* 0.001068115 */,
-PRESHIFT(0x0ca8d000) /* -0.791213989 */,
PRESHIFT(0x119e9000) /* 1.101211548 */,
PRESHIFT(0x05991000) /* 0.349868774 */,
PRESHIFT(0x02578000) /* 0.146362305 */,
PRESHIFT(0x0091a000) /* 0.035552979 */,
PRESHIFT(0x007d1000) /* 0.030532837 */,
PRESHIFT(0x00048000) /* 0.001098633 */,
PRESHIFT(0x000a1000) /* 0.002456665 */,
PRESHIFT(0x0000d000) /* 0.000198364 */ },
{ -PRESHIFT(0x00002000) /* -0.000030518 */, /* 9 */
-PRESHIFT(0x0003f000) /* -0.000961304 */,
PRESHIFT(0x000dd000) /* 0.003372192 */,
-PRESHIFT(0x00428000) /* -0.016235352 */,
PRESHIFT(0x00500000) /* 0.019531250 */,
-PRESHIFT(0x02011000) /* -0.125259399 */,
-PRESHIFT(0x003e6000) /* -0.015228271 */,
-PRESHIFT(0x0d11e000) /* -0.816864014 */,
PRESHIFT(0x116fc000) /* 1.089782715 */,
PRESHIFT(0x052c5000) /* 0.323318481 */,
PRESHIFT(0x02616000) /* 0.148773193 */,
PRESHIFT(0x007d6000) /* 0.030609131 */,
PRESHIFT(0x007aa000) /* 0.029937744 */,
PRESHIFT(0x00024000) /* 0.000549316 */,
PRESHIFT(0x0009a000) /* 0.002349854 */,
PRESHIFT(0x0000b000) /* 0.000167847 */,
-PRESHIFT(0x00002000) /* -0.000030518 */,
-PRESHIFT(0x0003f000) /* -0.000961304 */,
PRESHIFT(0x000dd000) /* 0.003372192 */,
-PRESHIFT(0x00428000) /* -0.016235352 */,
PRESHIFT(0x00500000) /* 0.019531250 */,
-PRESHIFT(0x02011000) /* -0.125259399 */,
-PRESHIFT(0x003e6000) /* -0.015228271 */,
-PRESHIFT(0x0d11e000) /* -0.816864014 */,
PRESHIFT(0x116fc000) /* 1.089782715 */,
PRESHIFT(0x052c5000) /* 0.323318481 */,
PRESHIFT(0x02616000) /* 0.148773193 */,
PRESHIFT(0x007d6000) /* 0.030609131 */,
PRESHIFT(0x007aa000) /* 0.029937744 */,
PRESHIFT(0x00024000) /* 0.000549316 */,
PRESHIFT(0x0009a000) /* 0.002349854 */,
PRESHIFT(0x0000b000) /* 0.000167847 */ },
{ -PRESHIFT(0x00002000) /* -0.000030518 */, /* 10 */
-PRESHIFT(0x00044000) /* -0.001037598 */,
PRESHIFT(0x000d7000) /* 0.003280640 */,
-PRESHIFT(0x00471000) /* -0.017349243 */,
PRESHIFT(0x0046b000) /* 0.017257690 */,
-PRESHIFT(0x0212b000) /* -0.129562378 */,
-PRESHIFT(0x0084a000) /* -0.032379150 */,
-PRESHIFT(0x0d78a000) /* -0.841949463 */,
PRESHIFT(0x113be000) /* 1.077117920 */,
PRESHIFT(0x04c16000) /* 0.297210693 */,
PRESHIFT(0x02687000) /* 0.150497437 */,
PRESHIFT(0x0069c000) /* 0.025817871 */,
PRESHIFT(0x0077f000) /* 0.029281616 */,
PRESHIFT(0x00002000) /* 0.000030518 */,
PRESHIFT(0x00093000) /* 0.002243042 */,
PRESHIFT(0x0000a000) /* 0.000152588 */,
-PRESHIFT(0x00002000) /* -0.000030518 */,
-PRESHIFT(0x00044000) /* -0.001037598 */,
PRESHIFT(0x000d7000) /* 0.003280640 */,
-PRESHIFT(0x00471000) /* -0.017349243 */,
PRESHIFT(0x0046b000) /* 0.017257690 */,
-PRESHIFT(0x0212b000) /* -0.129562378 */,
-PRESHIFT(0x0084a000) /* -0.032379150 */,
-PRESHIFT(0x0d78a000) /* -0.841949463 */,
PRESHIFT(0x113be000) /* 1.077117920 */,
PRESHIFT(0x04c16000) /* 0.297210693 */,
PRESHIFT(0x02687000) /* 0.150497437 */,
PRESHIFT(0x0069c000) /* 0.025817871 */,
PRESHIFT(0x0077f000) /* 0.029281616 */,
PRESHIFT(0x00002000) /* 0.000030518 */,
PRESHIFT(0x00093000) /* 0.002243042 */,
PRESHIFT(0x0000a000) /* 0.000152588 */ },
{ -PRESHIFT(0x00003000) /* -0.000045776 */, /* 11 */
-PRESHIFT(0x00049000) /* -0.001113892 */,
PRESHIFT(0x000d0000) /* 0.003173828 */,
-PRESHIFT(0x004ba000) /* -0.018463135 */,
PRESHIFT(0x003ca000) /* 0.014801025 */,
-PRESHIFT(0x02233000) /* -0.133590698 */,
-PRESHIFT(0x00ce4000) /* -0.050354004 */,
-PRESHIFT(0x0ddca000) /* -0.866363525 */,
PRESHIFT(0x1102f000) /* 1.063217163 */,
PRESHIFT(0x04587000) /* 0.271591187 */,
PRESHIFT(0x026cf000) /* 0.151596069 */,
PRESHIFT(0x0056c000) /* 0.021179199 */,
PRESHIFT(0x0074e000) /* 0.028533936 */,
-PRESHIFT(0x0001d000) /* -0.000442505 */,
PRESHIFT(0x0008b000) /* 0.002120972 */,
PRESHIFT(0x00009000) /* 0.000137329 */,
-PRESHIFT(0x00003000) /* -0.000045776 */,
-PRESHIFT(0x00049000) /* -0.001113892 */,
PRESHIFT(0x000d0000) /* 0.003173828 */,
-PRESHIFT(0x004ba000) /* -0.018463135 */,
PRESHIFT(0x003ca000) /* 0.014801025 */,
-PRESHIFT(0x02233000) /* -0.133590698 */,
-PRESHIFT(0x00ce4000) /* -0.050354004 */,
-PRESHIFT(0x0ddca000) /* -0.866363525 */,
PRESHIFT(0x1102f000) /* 1.063217163 */,
PRESHIFT(0x04587000) /* 0.271591187 */,
PRESHIFT(0x026cf000) /* 0.151596069 */,
PRESHIFT(0x0056c000) /* 0.021179199 */,
PRESHIFT(0x0074e000) /* 0.028533936 */,
-PRESHIFT(0x0001d000) /* -0.000442505 */,
PRESHIFT(0x0008b000) /* 0.002120972 */,
PRESHIFT(0x00009000) /* 0.000137329 */ },
{ -PRESHIFT(0x00003000) /* -0.000045776 */, /* 12 */
-PRESHIFT(0x0004f000) /* -0.001205444 */,
PRESHIFT(0x000c8000) /* 0.003051758 */,
-PRESHIFT(0x00503000) /* -0.019577026 */,
PRESHIFT(0x0031a000) /* 0.012115479 */,
-PRESHIFT(0x02326000) /* -0.137298584 */,
-PRESHIFT(0x011b5000) /* -0.069168091 */,
-PRESHIFT(0x0e3dd000) /* -0.890090942 */,
PRESHIFT(0x10c54000) /* 1.048156738 */,
PRESHIFT(0x03f1b000) /* 0.246505737 */,
PRESHIFT(0x026ee000) /* 0.152069092 */,
PRESHIFT(0x00447000) /* 0.016708374 */,
PRESHIFT(0x00719000) /* 0.027725220 */,
-PRESHIFT(0x00039000) /* -0.000869751 */,
PRESHIFT(0x00084000) /* 0.002014160 */,
PRESHIFT(0x00008000) /* 0.000122070 */,
-PRESHIFT(0x00003000) /* -0.000045776 */,
-PRESHIFT(0x0004f000) /* -0.001205444 */,
PRESHIFT(0x000c8000) /* 0.003051758 */,
-PRESHIFT(0x00503000) /* -0.019577026 */,
PRESHIFT(0x0031a000) /* 0.012115479 */,
-PRESHIFT(0x02326000) /* -0.137298584 */,
-PRESHIFT(0x011b5000) /* -0.069168091 */,
-PRESHIFT(0x0e3dd000) /* -0.890090942 */,
PRESHIFT(0x10c54000) /* 1.048156738 */,
PRESHIFT(0x03f1b000) /* 0.246505737 */,
PRESHIFT(0x026ee000) /* 0.152069092 */,
PRESHIFT(0x00447000) /* 0.016708374 */,
PRESHIFT(0x00719000) /* 0.027725220 */,
-PRESHIFT(0x00039000) /* -0.000869751 */,
PRESHIFT(0x00084000) /* 0.002014160 */,
PRESHIFT(0x00008000) /* 0.000122070 */ },
{ -PRESHIFT(0x00004000) /* -0.000061035 */, /* 13 */
-PRESHIFT(0x00055000) /* -0.001296997 */,
PRESHIFT(0x000bd000) /* 0.002883911 */,
-PRESHIFT(0x0054c000) /* -0.020690918 */,
PRESHIFT(0x0025d000) /* 0.009231567 */,
-PRESHIFT(0x02403000) /* -0.140670776 */,
-PRESHIFT(0x016ba000) /* -0.088775635 */,
-PRESHIFT(0x0e9be000) /* -0.913055420 */,
PRESHIFT(0x1082d000) /* 1.031936646 */,
PRESHIFT(0x038d4000) /* 0.221984863 */,
PRESHIFT(0x026e7000) /* 0.151962280 */,
PRESHIFT(0x0032e000) /* 0.012420654 */,
PRESHIFT(0x006df000) /* 0.026840210 */,
-PRESHIFT(0x00053000) /* -0.001266479 */,
PRESHIFT(0x0007d000) /* 0.001907349 */,
PRESHIFT(0x00007000) /* 0.000106812 */,
-PRESHIFT(0x00004000) /* -0.000061035 */,
-PRESHIFT(0x00055000) /* -0.001296997 */,
PRESHIFT(0x000bd000) /* 0.002883911 */,
-PRESHIFT(0x0054c000) /* -0.020690918 */,
PRESHIFT(0x0025d000) /* 0.009231567 */,
-PRESHIFT(0x02403000) /* -0.140670776 */,
-PRESHIFT(0x016ba000) /* -0.088775635 */,
-PRESHIFT(0x0e9be000) /* -0.913055420 */,
PRESHIFT(0x1082d000) /* 1.031936646 */,
PRESHIFT(0x038d4000) /* 0.221984863 */,
PRESHIFT(0x026e7000) /* 0.151962280 */,
PRESHIFT(0x0032e000) /* 0.012420654 */,
PRESHIFT(0x006df000) /* 0.026840210 */,
-PRESHIFT(0x00053000) /* -0.001266479 */,
PRESHIFT(0x0007d000) /* 0.001907349 */,
PRESHIFT(0x00007000) /* 0.000106812 */ },
{ -PRESHIFT(0x00004000) /* -0.000061035 */, /* 14 */
-PRESHIFT(0x0005b000) /* -0.001388550 */,
PRESHIFT(0x000b1000) /* 0.002700806 */,
-PRESHIFT(0x00594000) /* -0.021789551 */,
PRESHIFT(0x00192000) /* 0.006134033 */,
-PRESHIFT(0x024c8000) /* -0.143676758 */,
-PRESHIFT(0x01bf2000) /* -0.109161377 */,
-PRESHIFT(0x0ef69000) /* -0.935195923 */,
PRESHIFT(0x103be000) /* 1.014617920 */,
PRESHIFT(0x032b4000) /* 0.198059082 */,
PRESHIFT(0x026bc000) /* 0.151306152 */,
PRESHIFT(0x00221000) /* 0.008316040 */,
PRESHIFT(0x006a2000) /* 0.025909424 */,
-PRESHIFT(0x0006a000) /* -0.001617432 */,
PRESHIFT(0x00075000) /* 0.001785278 */,
PRESHIFT(0x00007000) /* 0.000106812 */,
-PRESHIFT(0x00004000) /* -0.000061035 */,
-PRESHIFT(0x0005b000) /* -0.001388550 */,
PRESHIFT(0x000b1000) /* 0.002700806 */,
-PRESHIFT(0x00594000) /* -0.021789551 */,
PRESHIFT(0x00192000) /* 0.006134033 */,
-PRESHIFT(0x024c8000) /* -0.143676758 */,
-PRESHIFT(0x01bf2000) /* -0.109161377 */,
-PRESHIFT(0x0ef69000) /* -0.935195923 */,
PRESHIFT(0x103be000) /* 1.014617920 */,
PRESHIFT(0x032b4000) /* 0.198059082 */,
PRESHIFT(0x026bc000) /* 0.151306152 */,
PRESHIFT(0x00221000) /* 0.008316040 */,
PRESHIFT(0x006a2000) /* 0.025909424 */,
-PRESHIFT(0x0006a000) /* -0.001617432 */,
PRESHIFT(0x00075000) /* 0.001785278 */,
PRESHIFT(0x00007000) /* 0.000106812 */ },
{ -PRESHIFT(0x00005000) /* -0.000076294 */, /* 15 */
-PRESHIFT(0x00061000) /* -0.001480103 */,
PRESHIFT(0x000a3000) /* 0.002487183 */,
-PRESHIFT(0x005da000) /* -0.022857666 */,
PRESHIFT(0x000b9000) /* 0.002822876 */,
-PRESHIFT(0x02571000) /* -0.146255493 */,
-PRESHIFT(0x0215c000) /* -0.130310059 */,
-PRESHIFT(0x0f4dc000) /* -0.956481934 */,
PRESHIFT(0x0ff0a000) /* 0.996246338 */,
PRESHIFT(0x02cbf000) /* 0.174789429 */,
PRESHIFT(0x0266e000) /* 0.150115967 */,
PRESHIFT(0x00120000) /* 0.004394531 */,
PRESHIFT(0x00662000) /* 0.024932861 */,
-PRESHIFT(0x0007f000) /* -0.001937866 */,
PRESHIFT(0x0006f000) /* 0.001693726 */,
PRESHIFT(0x00006000) /* 0.000091553 */,
-PRESHIFT(0x00005000) /* -0.000076294 */,
-PRESHIFT(0x00061000) /* -0.001480103 */,
PRESHIFT(0x000a3000) /* 0.002487183 */,
-PRESHIFT(0x005da000) /* -0.022857666 */,
PRESHIFT(0x000b9000) /* 0.002822876 */,
-PRESHIFT(0x02571000) /* -0.146255493 */,
-PRESHIFT(0x0215c000) /* -0.130310059 */,
-PRESHIFT(0x0f4dc000) /* -0.956481934 */,
PRESHIFT(0x0ff0a000) /* 0.996246338 */,
PRESHIFT(0x02cbf000) /* 0.174789429 */,
PRESHIFT(0x0266e000) /* 0.150115967 */,
PRESHIFT(0x00120000) /* 0.004394531 */,
PRESHIFT(0x00662000) /* 0.024932861 */,
-PRESHIFT(0x0007f000) /* -0.001937866 */,
PRESHIFT(0x0006f000) /* 0.001693726 */,
PRESHIFT(0x00006000) /* 0.000091553 */ },
{ -PRESHIFT(0x00005000) /* -0.000076294 */, /* 16 */
-PRESHIFT(0x00068000) /* -0.001586914 */,
PRESHIFT(0x00092000) /* 0.002227783 */,
-PRESHIFT(0x0061f000) /* -0.023910522 */,
-PRESHIFT(0x0002d000) /* -0.000686646 */,
-PRESHIFT(0x025ff000) /* -0.148422241 */,
-PRESHIFT(0x026f7000) /* -0.152206421 */,
-PRESHIFT(0x0fa13000) /* -0.976852417 */,
PRESHIFT(0x0fa13000) /* 0.976852417 */,
PRESHIFT(0x026f7000) /* 0.152206421 */,
PRESHIFT(0x025ff000) /* 0.148422241 */,
PRESHIFT(0x0002d000) /* 0.000686646 */,
PRESHIFT(0x0061f000) /* 0.023910522 */,
-PRESHIFT(0x00092000) /* -0.002227783 */,
PRESHIFT(0x00068000) /* 0.001586914 */,
PRESHIFT(0x00005000) /* 0.000076294 */,
-PRESHIFT(0x00005000) /* -0.000076294 */,
-PRESHIFT(0x00068000) /* -0.001586914 */,
PRESHIFT(0x00092000) /* 0.002227783 */,
-PRESHIFT(0x0061f000) /* -0.023910522 */,
-PRESHIFT(0x0002d000) /* -0.000686646 */,
-PRESHIFT(0x025ff000) /* -0.148422241 */,
-PRESHIFT(0x026f7000) /* -0.152206421 */,
-PRESHIFT(0x0fa13000) /* -0.976852417 */,
PRESHIFT(0x0fa13000) /* 0.976852417 */,
PRESHIFT(0x026f7000) /* 0.152206421 */,
PRESHIFT(0x025ff000) /* 0.148422241 */,
PRESHIFT(0x0002d000) /* 0.000686646 */,
PRESHIFT(0x0061f000) /* 0.023910522 */,
-PRESHIFT(0x00092000) /* -0.002227783 */,
PRESHIFT(0x00068000) /* 0.001586914 */,
PRESHIFT(0x00005000) /* 0.000076294 */ }
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.
##
## libmad - MPEG audio decoder library
## Copyright (C) 2000-2001 Robert Leslie
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
## $Id: Makefile.am,v 1.2 2003/06/18 20:46:35 shank Exp $
##
## Process this file with automake to produce Makefile.in
noinst_LTLIBRARIES = libmad.la
noinst_HEADERS = mad.h
EXTRA_DIST = COPYRIGHT mad.h.sed
exported_headers = \
version.h fixed.h bit.h timer.h stream.h frame.h synth.h decoder.h
headers = \
$(exported_headers) global.h layer12.h layer3.h huffman.h
data_includes = \
D.dat imdct_s.dat qc_table.dat rq_table.dat sf_table.dat
libmad_la_SOURCES = \
version.c fixed.c bit.c timer.c stream.c frame.c synth.c decoder.c \
layer12.c layer3.c huffman.c $(headers) $(data_includes)
EXTRA_libmad_la_SOURCES = imdct_l_arm.S #synth_mmx.S
libmad_la_DEPENDENCIES = @ASO_OBJS@
libmad_la_LIBADD = @ASO_OBJS@
#CFLAGS = -Wall @CFLAGS@ $(ARCH) $(DEBUGGER) $(OPTIMIZER) $(PROFILER)
#LDFLAGS = @LDFLAGS@ $(PROFILER)
INCLUDES = $(FPM) $(ASO)
BUILT_SOURCES = mad.h
CLEANFILES = mad.h
## From the libtool documentation on library versioning:
##
## CURRENT
## The most recent interface number that this library implements.
##
## REVISION
## The implementation number of the CURRENT interface.
##
## AGE
## The difference between the newest and oldest interfaces that this
## library implements. In other words, the library implements all the
## interface numbers in the range from number `CURRENT - AGE' to
## `CURRENT'.
##
## If two libraries have identical CURRENT and AGE numbers, then the
## dynamic linker chooses the library with the greater REVISION number.
##
## 1. Start with version information of `0:0:0' for each libtool library.
##
## 2. Update the version information only immediately before a public
## release of your software. More frequent updates are unnecessary,
## and only guarantee that the current interface number gets larger
## faster.
##
## 3. If the library source code has changed at all since the last
## update, then increment REVISION (`C:R:A' becomes `C:r+1:A').
##
## 4. If any interfaces have been added, removed, or changed since the
## last update, increment CURRENT, and set REVISION to 0.
##
## 5. If any interfaces have been added since the last public release,
## then increment AGE.
##
## 6. If any interfaces have been removed since the last public release,
## then set AGE to 0.
version_current = 1
version_revision = 0
version_age = 1
version_info = $(version_current):$(version_revision):$(version_age)
libmad_la_LDFLAGS = -version-info $(version_info)
## -release $(VERSION)
mad.h: config.status config.h Makefile.am \
$(srcdir)/COPYRIGHT $(srcdir)/mad.h.sed $(exported_headers)
(sed -e '1s|.*|/*|' -e '1b' -e '$$s|.*| */|' -e '$$b' \
-e 's/^.*/ *&/' $(srcdir)/COPYRIGHT; echo; \
echo "# ifdef __cplusplus"; \
echo 'extern "C" {'; \
echo "# endif"; echo; \
if [ ".$(FPM)" != "." ]; then \
echo ".$(FPM)" | sed -e 's|^\.-D|# define |'; echo; \
fi; \
sed -ne 's/^# *define *\(HAVE_.*_ASM\).*/# define \1/p' \
config.h; echo; \
sed -ne 's/^# *define *OPT_\(SPEED\|ACCURACY\).*/# define OPT_\1/p' \
config.h; echo; \
sed -ne 's/^# *define *\(SIZEOF_.*\)/# define \1/p' \
config.h; echo; \
for header in $(exported_headers); do \
echo; \
sed -n -f $(srcdir)/mad.h.sed $(srcdir)/$$header; echo; \
done; \
echo "# ifdef __cplusplus"; \
echo '}'; \
echo "# endif") | cat -s >$@
libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status --recheck
.c.s:
$(COMPILE) -S $<
again: clean all
.PHONY: again
# Makefile.in generated automatically by automake 1.4-p4 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
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 = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
AS = @AS@
ASO = @ASO@
ASO_OBJS = @ASO_OBJS@
CC = @CC@
CCAS = @CCAS@
CCASFLAGS = @CCASFLAGS@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
EXEEXT = @EXEEXT@
FPM = @FPM@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
STRIP = @STRIP@
VERSION = @VERSION@
noinst_LTLIBRARIES = libmad.la
noinst_HEADERS = mad.h
EXTRA_DIST = COPYRIGHT mad.h.sed
exported_headers = version.h fixed.h bit.h timer.h stream.h frame.h synth.h decoder.h
headers = $(exported_headers) global.h layer12.h layer3.h huffman.h
data_includes = D.dat imdct_s.dat qc_table.dat rq_table.dat sf_table.dat
libmad_la_SOURCES = version.c fixed.c bit.c timer.c stream.c frame.c synth.c decoder.c layer12.c layer3.c huffman.c $(headers) $(data_includes)
EXTRA_libmad_la_SOURCES = imdct_l_arm.S #synth_mmx.S
libmad_la_DEPENDENCIES = @ASO_OBJS@
libmad_la_LIBADD = @ASO_OBJS@
#CFLAGS = -Wall @CFLAGS@ $(ARCH) $(DEBUGGER) $(OPTIMIZER) $(PROFILER)
#LDFLAGS = @LDFLAGS@ $(PROFILER)
INCLUDES = $(FPM) $(ASO)
BUILT_SOURCES = mad.h
CLEANFILES = mad.h
version_current = 1
version_revision = 0
version_age = 1
version_info = $(version_current):$(version_revision):$(version_age)
libmad_la_LDFLAGS = -version-info $(version_info)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
DEFS = @DEFS@ -I. -I$(srcdir) -I.
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libmad_la_OBJECTS = version.lo fixed.lo bit.lo timer.lo stream.lo \
frame.lo synth.lo decoder.lo layer12.lo layer3.lo huffman.lo
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
HEADERS = $(noinst_HEADERS)
DIST_COMMON = ./stamp-h.in COPYING INSTALL Makefile.am Makefile.in \
acconfig.h aclocal.m4 config.h.in configure configure.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
SOURCES = $(libmad_la_SOURCES) $(EXTRA_libmad_la_SOURCES)
OBJECTS = $(libmad_la_OBJECTS)
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .lo .o .obj .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(ACLOCAL_M4): configure.in
cd $(srcdir) && $(ACLOCAL)
config.status: $(srcdir)/configure.in $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
config.h: stamp-h
@if test ! -f $@; then \
rm -f stamp-h; \
$(MAKE) stamp-h; \
else :; fi
stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES= CONFIG_HEADERS=config.h \
$(SHELL) ./config.status
@echo timestamp > stamp-h 2> /dev/null
$(srcdir)/config.h.in: $(srcdir)/stamp-h.in
@if test ! -f $@; then \
rm -f $(srcdir)/stamp-h.in; \
$(MAKE) $(srcdir)/stamp-h.in; \
else :; fi
$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
cd $(top_srcdir) && $(AUTOHEADER)
@echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
mostlyclean-hdr:
clean-hdr:
distclean-hdr:
-rm -f config.h
maintainer-clean-hdr:
mostlyclean-noinstLTLIBRARIES:
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
distclean-noinstLTLIBRARIES:
maintainer-clean-noinstLTLIBRARIES:
.c.o:
$(COMPILE) -c $<
# FIXME: We should only use cygpath when building on Windows,
# and only if it is available.
.c.obj:
$(COMPILE) -c `cygpath -w $<`
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
-rm -f *.$(OBJEXT)
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
.c.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.S.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
maintainer-clean-libtool:
libmad.la: $(libmad_la_OBJECTS) $(libmad_la_DEPENDENCIES)
$(LINK) $(libmad_la_LDFLAGS) $(libmad_la_OBJECTS) $(libmad_la_LIBADD) $(LIBS)
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
-rm -rf $(distdir)
GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
mkdir $(distdir)/=build
mkdir $(distdir)/=inst
dc_install_base=`cd $(distdir)/=inst && pwd`; \
cd $(distdir)/=build \
&& ../configure --srcdir=.. --prefix=$$dc_install_base \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) dist
-rm -rf $(distdir)
@banner="$(distdir).tar.gz is ready for distribution"; \
dashes=`echo "$$banner" | sed s/./=/g`; \
echo "$$dashes"; \
echo "$$banner"; \
echo "$$dashes"
dist: distdir
-chmod -R a+r $(distdir)
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
dist-all: distdir
-chmod -R a+r $(distdir)
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
distdir: $(DISTFILES)
-rm -rf $(distdir)
mkdir $(distdir)
-chmod 777 $(distdir)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
all-recursive-am: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
install-exec-am:
install-exec: install-exec-am
install-data-am:
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am:
uninstall: uninstall-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
mostlyclean-am: mostlyclean-hdr mostlyclean-noinstLTLIBRARIES \
mostlyclean-compile mostlyclean-libtool \
mostlyclean-tags mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-hdr clean-noinstLTLIBRARIES clean-compile clean-libtool \
clean-tags clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-hdr distclean-noinstLTLIBRARIES \
distclean-compile distclean-libtool distclean-tags \
distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
-rm -f config.status
maintainer-clean-am: maintainer-clean-hdr \
maintainer-clean-noinstLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
maintainer-clean-tags maintainer-clean-generic \
distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-am
-rm -f config.status
.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
mostlyclean-noinstLTLIBRARIES distclean-noinstLTLIBRARIES \
clean-noinstLTLIBRARIES maintainer-clean-noinstLTLIBRARIES \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \
install-exec-am install-exec install-data-am install-data install-am \
install uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
mad.h: config.status config.h Makefile.am \
$(srcdir)/COPYRIGHT $(srcdir)/mad.h.sed $(exported_headers)
(sed -e '1s|.*|/*|' -e '1b' -e '$$s|.*| */|' -e '$$b' \
-e 's/^.*/ *&/' $(srcdir)/COPYRIGHT; echo; \
echo "# ifdef __cplusplus"; \
echo 'extern "C" {'; \
echo "# endif"; echo; \
if [ ".$(FPM)" != "." ]; then \
echo ".$(FPM)" | sed -e 's|^\.-D|# define |'; echo; \
fi; \
sed -ne 's/^# *define *\(HAVE_.*_ASM\).*/# define \1/p' \
config.h; echo; \
sed -ne 's/^# *define *OPT_\(SPEED\|ACCURACY\).*/# define OPT_\1/p' \
config.h; echo; \
sed -ne 's/^# *define *\(SIZEOF_.*\)/# define \1/p' \
config.h; echo; \
for header in $(exported_headers); do \
echo; \
sed -n -f $(srcdir)/mad.h.sed $(srcdir)/$$header; echo; \
done; \
echo "# ifdef __cplusplus"; \
echo '}'; \
echo "# endif") | cat -s >$@
libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status --recheck
.c.s:
$(COMPILE) -S $<
again: clean all
.PHONY: again
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: acconfig.h,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifndef LIBMAD_CONFIG_H
# define LIBMAD_CONFIG_H
/*****************************************************************************
* Definitions selected automatically by `configure' *
*****************************************************************************/
@TOP@
/* Define to optimize for speed over accuracy. */
#undef OPT_SPEED
/* Define to optimize for accuracy over speed. */
#undef OPT_ACCURACY
/* Define to enable a fast subband synthesis approximation optimization. */
#undef OPT_SSO
/* Define to influence a strict interpretation of the ISO/IEC standards,
even if this is in opposition with best accepted practices. */
#undef OPT_STRICT
/* Define if your MIPS CPU supports a 2-operand MADD instruction. */
#undef HAVE_MADD_ASM
/* Define if your MIPS CPU supports a 2-operand MADD16 instruction. */
#undef HAVE_MADD16_ASM
/* Define to enable diagnostic debugging support. */
#undef DEBUG
/* Define to disable debugging assertions. */
#undef NDEBUG
/* Define to enable experimental code. */
#undef EXPERIMENTAL
@BOTTOM@
/*****************************************************************************
* End of automatically configured definitions *
*****************************************************************************/
# endif
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: bit.c,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# ifdef HAVE_LIMITS_H
# include <limits.h>
# else
# define CHAR_BIT 8
# endif
# include "bit.h"
/*
* This is the lookup table for computing the CRC-check word.
* As described in section 2.4.3.1 and depicted in Figure A.9
* of ISO/IEC 11172-3, the generator polynomial is:
*
* G(X) = X^16 + X^15 + X^2 + 1
*/
static
unsigned short const crc_table[256] = {
0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011,
0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022,
0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072,
0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041,
0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2,
0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1,
0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1,
0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082,
0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1,
0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1,
0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2,
0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151,
0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162,
0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132,
0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101,
0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312,
0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371,
0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342,
0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1,
0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2,
0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2,
0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381,
0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291,
0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2,
0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1,
0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252,
0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261,
0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231,
0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202
};
# define CRC_POLY 0x8005
/*
* NAME: bit->init()
* DESCRIPTION: initialize bit pointer struct
*/
void mad_bit_init(struct mad_bitptr *bitptr, unsigned char const *byte)
{
bitptr->byte = byte;
bitptr->cache = 0;
bitptr->left = CHAR_BIT;
}
/*
* NAME: bit->length()
* DESCRIPTION: return number of bits between start and end points
*/
unsigned int mad_bit_length(struct mad_bitptr const *begin,
struct mad_bitptr const *end)
{
return begin->left +
CHAR_BIT * (end->byte - (begin->byte + 1)) + (CHAR_BIT - end->left);
}
/*
* NAME: bit->nextbyte()
* DESCRIPTION: return pointer to next unprocessed byte
*/
unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *bitptr)
{
return bitptr->left == CHAR_BIT ? bitptr->byte : bitptr->byte + 1;
}
/*
* NAME: bit->skip()
* DESCRIPTION: advance bit pointer
*/
void mad_bit_skip(struct mad_bitptr *bitptr, unsigned int len)
{
bitptr->byte += len / CHAR_BIT;
bitptr->left -= len % CHAR_BIT;
if (bitptr->left > CHAR_BIT) {
bitptr->byte++;
bitptr->left += CHAR_BIT;
}
if (bitptr->left < CHAR_BIT)
bitptr->cache = *bitptr->byte;
}
/*
* NAME: bit->read()
* DESCRIPTION: read an arbitrary number of bits and return their UIMSBF value
*/
unsigned long mad_bit_read(struct mad_bitptr *bitptr, unsigned int len)
{
register unsigned long value;
if (bitptr->left == CHAR_BIT)
bitptr->cache = *bitptr->byte;
if (len < bitptr->left) {
value = (bitptr->cache & ((1 << bitptr->left) - 1)) >>
(bitptr->left - len);
bitptr->left -= len;
return value;
}
/* remaining bits in current byte */
value = bitptr->cache & ((1 << bitptr->left) - 1);
len -= bitptr->left;
bitptr->byte++;
bitptr->left = CHAR_BIT;
/* more bytes */
while (len >= CHAR_BIT) {
value = (value << CHAR_BIT) | *bitptr->byte++;
len -= CHAR_BIT;
}
if (len > 0) {
bitptr->cache = *bitptr->byte;
value = (value << len) | (bitptr->cache >> (CHAR_BIT - len));
bitptr->left -= len;
}
return value;
}
# if 0
/*
* NAME: bit->write()
* DESCRIPTION: write an arbitrary number of bits
*/
void mad_bit_write(struct mad_bitptr *bitptr, unsigned int len,
unsigned long value)
{
unsigned char *ptr;
ptr = (unsigned char *) bitptr->byte;
/* ... */
}
# endif
/*
* NAME: bit->crc()
* DESCRIPTION: compute CRC-check word
*/
unsigned short mad_bit_crc(struct mad_bitptr bitptr, unsigned int len,
unsigned short init)
{
register unsigned int crc;
for (crc = init; len >= 32; len -= 32) {
register unsigned long data;
data = mad_bit_read(&bitptr, 32);
crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 24)) & 0xff];
crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 16)) & 0xff];
crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 8)) & 0xff];
crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 0)) & 0xff];
}
switch (len / 8) {
case 3: crc = (crc << 8) ^
crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff];
case 2: crc = (crc << 8) ^
crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff];
case 1: crc = (crc << 8) ^
crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff];
len %= 8;
case 0: break;
}
while (len--) {
register unsigned int msb;
msb = mad_bit_read(&bitptr, 1) ^ (crc >> 15);
crc <<= 1;
if (msb & 1)
crc ^= CRC_POLY;
}
return crc & 0xffff;
}
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: bit.h,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifndef LIBMAD_BIT_H
# define LIBMAD_BIT_H
struct mad_bitptr {
unsigned char const *byte;
unsigned short cache;
unsigned short left;
};
void mad_bit_init(struct mad_bitptr *, unsigned char const *);
# define mad_bit_finish(bitptr) /* nothing */
unsigned int mad_bit_length(struct mad_bitptr const *,
struct mad_bitptr const *);
# define mad_bit_bitsleft(bitptr) ((bitptr)->left)
unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *);
void mad_bit_skip(struct mad_bitptr *, unsigned int);
unsigned long mad_bit_read(struct mad_bitptr *, unsigned int);
void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long);
unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short);
# endif
/* config.h.in. Generated automatically from configure.in by autoheader 2.13. */
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: acconfig.h,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifndef LIBMAD_CONFIG_H
# define LIBMAD_CONFIG_H
/*****************************************************************************
* Definitions selected automatically by `configure' *
*****************************************************************************/
/* Define to empty if the keyword does not work. */
#undef const
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
/* Define as __inline if that's what the C compiler calls it. */
#undef inline
/* Define to `int' if <sys/types.h> doesn't define. */
#undef pid_t
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to optimize for speed over accuracy. */
#undef OPT_SPEED
/* Define to optimize for accuracy over speed. */
#undef OPT_ACCURACY
/* Define to enable a fast subband synthesis approximation optimization. */
#undef OPT_SSO
/* Define to influence a strict interpretation of the ISO/IEC standards,
even if this is in opposition with best accepted practices. */
#undef OPT_STRICT
/* Define if your MIPS CPU supports a 2-operand MADD instruction. */
#undef HAVE_MADD_ASM
/* Define if your MIPS CPU supports a 2-operand MADD16 instruction. */
#undef HAVE_MADD16_ASM
/* Define to enable diagnostic debugging support. */
#undef DEBUG
/* Define to disable debugging assertions. */
#undef NDEBUG
/* Define to enable experimental code. */
#undef EXPERIMENTAL
/* The number of bytes in a int. */
#undef SIZEOF_INT
/* The number of bytes in a long. */
#undef SIZEOF_LONG
/* The number of bytes in a long long. */
#undef SIZEOF_LONG_LONG
/* Define if you have the fcntl function. */
#undef HAVE_FCNTL
/* Define if you have the fork function. */
#undef HAVE_FORK
/* Define if you have the pipe function. */
#undef HAVE_PIPE
/* Define if you have the waitpid function. */
#undef HAVE_WAITPID
/* Define if you have the <assert.h> header file. */
#undef HAVE_ASSERT_H
/* Define if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Name of package */
#undef PACKAGE
/* Version number of package */
#undef VERSION
/*****************************************************************************
* End of automatically configured definitions *
*****************************************************************************/
# endif
This source diff could not be displayed because it is too large. You can view the blob instead.
dnl -*- m4 -*-
dnl
dnl libmad - MPEG audio decoder library
dnl Copyright (C) 2000-2001 Robert Leslie
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
dnl
AC_REVISION([$Id: configure.in,v 1.3 2003/06/19 02:27:00 shank Exp $])dnl
dnl Process this file with autoconf to produce a configure script.
AC_INIT(decoder.h)
AM_INIT_AUTOMAKE(libmad, 0.14.2b)
AM_CONFIG_HEADER(config.h)
dnl System type.
AC_CANONICAL_HOST
dnl Checks for programs.
AC_PROG_CC
dnl Support for libtool.
AC_DISABLE_SHARED
dnl AC_LIBTOOL_WIN32_DLL
AM_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
dnl Compiler options.
arch=""
debug=""
optimize=""
profile=""
set -- $CFLAGS
CFLAGS="-Wall"
if test "$GCC" = yes
then
case "$host" in
*-pc-cygwin)
CPPFLAGS="$CPPFLAGS -mno-cygwin"
LDFLAGS="$LDFLAGS -mno-cygwin"
;;
esac
fi
while test $# -gt 0
do
case "$1" in
-Wall)
shift
;;
-g)
debug="-g"
shift
;;
-mno-cygwin)
shift
;;
-m*)
arch="$arch $1"
shift
;;
-O2)
optimize="-O"
shift
;;
-fomit-frame-pointer)
shift
;;
-O*|-f*)
optimize="$optimize $1"
shift
;;
*)
CFLAGS="$CFLAGS $1"
shift
;;
esac
done
if test "$GCC" = yes
then
if test -z "$arch"
then
case "$host" in
i386-*) ;;
i?86-*) arch="-m486" ;;
arm*-empeg-*) arch="-march=armv4 -mtune=strongarm1100" ;;
armv4*-*) arch="-march=armv4 -mtune=strongarm" ;;
powerpc-*) ;;
mips*-agenda-*) arch="-mcpu=vr4100" ;;
mips*-luxsonor-*) arch="-mips1 -mcpu=r3000 -Wa,-m4010" ;;
esac
fi
case "$optimize" in
-O|"-O "*)
optimize="-O"
optimize="$optimize -fforce-mem"
optimize="$optimize -fforce-addr"
: #x optimize="$optimize -finline-functions"
: #- optimize="$optimize -fstrength-reduce"
optimize="$optimize -fthread-jumps"
optimize="$optimize -fcse-follow-jumps"
optimize="$optimize -fcse-skip-blocks"
: #x optimize="$optimize -frerun-cse-after-loop"
: #x optimize="$optimize -frerun-loop-opt"
: #x optimize="$optimize -fgcse"
optimize="$optimize -fexpensive-optimizations"
optimize="$optimize -fregmove"
: #* optimize="$optimize -fdelayed-branch"
: #x optimize="$optimize -fschedule-insns"
optimize="$optimize -fschedule-insns2"
: #? optimize="$optimize -ffunction-sections"
: #? optimize="$optimize -fcaller-saves"
: #> optimize="$optimize -funroll-loops"
: #> optimize="$optimize -funroll-all-loops"
: #x optimize="$optimize -fmove-all-movables"
: #x optimize="$optimize -freduce-all-givs"
: #? optimize="$optimize -fstrict-aliasing"
: #* optimize="$optimize -fstructure-noalias"
case "$host" in
arm*-*)
# this may provoke bugs in gcc 2.95.2
optimize="$optimize -fstrength-reduce"
#
# this may actually be slower but it
# triggers bugs if not included
optimize="$optimize -finline-functions"
;;
mips*-*)
optimize="$optimize -fstrength-reduce"
optimize="$optimize -finline-functions"
;;
i?86-*)
optimize="$optimize -fstrength-reduce"
;;
*)
# this sometimes provokes bugs in gcc 2.95.2
: #optimize="$optimize -fstrength-reduce"
;;
esac
;;
esac
fi
case "$host" in
mips*-agenda-*) AC_DEFINE(HAVE_MADD16_ASM) ;;
mips*-luxsonor-*) AC_DEFINE(HAVE_MADD_ASM) ;;
esac
dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(assert.h limits.h unistd.h sys/types.h fcntl.h errno.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
AC_TYPE_PID_T
AC_CHECK_SIZEOF(int, 2)
AC_CHECK_SIZEOF(long, 4)
AC_CHECK_SIZEOF(long long, 8)
dnl Checks for library functions.
AC_CHECK_FUNCS(waitpid fcntl pipe fork)
dnl Other options.
AC_SUBST(FPM)
AC_SUBST(ASO)
AC_SUBST(ASO_OBJS)
AC_SUBST(CCAS)
AC_SUBST(CCASFLAGS)
dnl handle --enable and --disable options
AC_CACHE_SAVE
AC_MSG_CHECKING(whether to optimize for speed or for accuracy)
AC_ARG_ENABLE(speed,
[ --enable-speed optimize for speed over accuracy], [
case "$enableval" in
yes)
optimize_for="speed"
AC_DEFINE(OPT_SPEED)
;;
esac
])
AC_ARG_ENABLE(accuracy,
[ --enable-accuracy optimize for accuracy over speed], [
case "$enableval" in
yes)
if test "$optimize_for" = "speed"
then
optimize_for="both"
else
optimize_for="accuracy"
fi
AC_DEFINE(OPT_ACCURACY)
;;
esac
])
AC_MSG_RESULT(${optimize_for-default})
if test "$optimize_for" = "both"
then
AC_MSG_ERROR(cannot optimize for both speed and accuracy)
fi
AC_MSG_CHECKING(for architecture-specific fixed-point math routines)
AC_ARG_ENABLE(fpm,
[ --enable-fpm=ARCH use ARCH-specific fixed-point math routines
(one of: intel, arm, mips, sparc, ppc,
64bit, default)], [
case "$enableval" in
yes) ;;
no|default|approx) FPM="DEFAULT" ;;
intel|i?86) FPM="INTEL" ;;
arm) FPM="ARM" ;;
mips) FPM="MIPS" ;;
sparc) FPM="SPARC" ;;
ppc|powerpc) FPM="PPC" ;;
64bit) FPM="64BIT" ;;
float) FPM="FLOAT" ;;
*)
AC_MSG_RESULT(failed)
AC_MSG_ERROR([bad --enable-fpm option])
;;
esac
])
if test -z "$FPM" && test "$GCC" = yes
then
case "$host" in
i?86-*) FPM="INTEL" ;;
arm*-*) FPM="ARM" ;;
mips*-*) FPM="MIPS" ;;
sparc*-*) FPM="SPARC" ;;
powerpc*-*) FPM="PPC" ;;
# FIXME: need to test for 64-bit long long...
esac
fi
AC_MSG_RESULT(${FPM=DEFAULT})
if test "$FPM" = "DEFAULT"
then
AC_MSG_WARN([default fixed-point math will yield limited accuracy])
fi
FPM="-DFPM_$FPM"
AC_ARG_ENABLE(sso,
[ --enable-sso use subband synthesis optimization], [
case "$enableval" in
yes) AC_DEFINE(OPT_SSO) ;;
esac
])
AC_ARG_ENABLE(aso,
[ --disable-aso disable architecture-specific optimizations],
[], [enable_aso=yes])
if test "$enable_aso" = yes
then
case "$host" in
i?86-*)
: #ASO="$ASO -DASO_INTERLEAVE1"
ASO="$ASO -DASO_ZEROCHECK"
: #not yet #ASO="$ASO -DASO_SYNTH"
: #not yet #ASO_OBJS="synth_mmx.lo"
;;
arm*-*)
ASO="$ASO -DASO_INTERLEAVE1"
ASO="$ASO -DASO_IMDCT"
ASO_OBJS="imdct_l_arm.lo"
;;
mips*-*)
ASO="$ASO -DASO_INTERLEAVE2"
ASO="$ASO -DASO_ZEROCHECK"
;;
esac
fi
AC_MSG_CHECKING(for ISO/IEC interpretation)
AC_ARG_ENABLE(strict-iso,
[ --enable-strict-iso use strict ISO/IEC interpretations], [
case "$enableval" in
yes)
AC_DEFINE(OPT_STRICT)
interpretation="strict"
;;
esac
])
AC_MSG_RESULT(${interpretation-best accepted practices})
AC_MSG_CHECKING(whether to enable profiling)
AC_ARG_ENABLE(profiling,
[ --enable-profiling generate profiling code], [
case "$enableval" in
yes) profile="-pg" ;;
esac
])
AC_MSG_RESULT(${enable_profiling-no})
AC_MSG_CHECKING(whether to enable debugging)
AC_ARG_ENABLE(debugging,
[ --enable-debugging enable diagnostic debugging support
--disable-debugging do not enable debugging and use more optimization], [
case "$enableval" in
yes)
AC_DEFINE(DEBUG)
optimize=""
;;
no)
if test -n "$profile"
then
AC_MSG_ERROR(--enable-profiling and --disable-debugging are incompatible)
fi
AC_DEFINE(NDEBUG)
debug=""
if test "$GCC" = yes
then
optimize="$optimize -fomit-frame-pointer"
fi
;;
esac
])
AC_MSG_RESULT(${enable_debugging-default})
AC_MSG_CHECKING(whether to enable experimental code)
AC_ARG_ENABLE(experimental,
[ --enable-experimental enable experimental code], [
case "$enableval" in
yes) AC_DEFINE(EXPERIMENTAL) ;;
esac
])
AC_MSG_RESULT(${enable_experimental-no})
dnl Create output files.
test -n "$arch" && CFLAGS="$CFLAGS $arch"
test -n "$debug" && CFLAGS="$CFLAGS $debug"
test -n "$optimize" && CFLAGS="$CFLAGS $optimize"
test -n "$profile" && CFLAGS="$CFLAGS $profile" LDFLAGS="$LDFLAGS $profile"
LTLIBOBJS=`echo "$LIBOBJS" | sed -e 's/\.o/.lo/g'`
AC_SUBST(LTLIBOBJS)
AC_OUTPUT(Makefile)
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: decoder.c,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
# endif
# ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
# endif
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
# ifdef HAVE_FCNTL_H
# include <fcntl.h>
# endif
# include <stdlib.h>
# ifdef HAVE_ERRNO_H
# include <errno.h>
# endif
# include "stream.h"
# include "frame.h"
# include "synth.h"
# include "decoder.h"
void mad_decoder_init(struct mad_decoder *decoder, void *data,
enum mad_flow (*input_func)(void *,
struct mad_stream *),
enum mad_flow (*header_func)(void *,
struct mad_header const *),
enum mad_flow (*filter_func)(void *,
struct mad_stream const *,
struct mad_frame *),
enum mad_flow (*output_func)(void *,
struct mad_header const *,
struct mad_pcm *),
enum mad_flow (*error_func)(void *,
struct mad_stream *,
struct mad_frame *),
enum mad_flow (*message_func)(void *,
void *, unsigned int *))
{
decoder->mode = -1;
decoder->options = 0;
decoder->async.pid = 0;
decoder->async.in = -1;
decoder->async.out = -1;
decoder->sync = 0;
decoder->cb_data = data;
decoder->input_func = input_func;
decoder->header_func = header_func;
decoder->filter_func = filter_func;
decoder->output_func = output_func;
decoder->error_func = error_func;
decoder->message_func = message_func;
}
int mad_decoder_finish(struct mad_decoder *decoder)
{
# if defined(USE_ASYNC)
if (decoder->mode == MAD_DECODER_MODE_ASYNC && decoder->async.pid) {
pid_t pid;
int status;
close(decoder->async.in);
do
pid = waitpid(decoder->async.pid, &status, 0);
while (pid == -1 && errno == EINTR);
decoder->mode = -1;
close(decoder->async.out);
decoder->async.pid = 0;
decoder->async.in = -1;
decoder->async.out = -1;
if (pid == -1)
return -1;
return (!WIFEXITED(status) || WEXITSTATUS(status)) ? -1 : 0;
}
# endif
return 0;
}
# if defined(USE_ASYNC)
static
enum mad_flow send_io(int fd, void const *data, size_t len)
{
char const *ptr = data;
ssize_t count;
while (len) {
do
count = write(fd, ptr, len);
while (count == -1 && errno == EINTR);
if (count == -1)
return MAD_FLOW_BREAK;
len -= count;
ptr += count;
}
return MAD_FLOW_CONTINUE;
}
static
enum mad_flow receive_io(int fd, void *buffer, size_t len)
{
char *ptr = buffer;
ssize_t count;
while (len) {
do
count = read(fd, ptr, len);
while (count == -1 && errno == EINTR);
if (count == -1)
return (errno == EAGAIN) ? MAD_FLOW_IGNORE : MAD_FLOW_BREAK;
else if (count == 0)
return MAD_FLOW_STOP;
len -= count;
ptr += count;
}
return MAD_FLOW_CONTINUE;
}
static
enum mad_flow receive_io_blocking(int fd, void *buffer, size_t len)
{
int flags, blocking;
enum mad_flow result;
flags = fcntl(fd, F_GETFL);
if (flags == -1)
return MAD_FLOW_BREAK;
blocking = flags & ~O_NONBLOCK;
if (blocking != flags &&
fcntl(fd, F_SETFL, blocking) == -1)
return MAD_FLOW_BREAK;
result = receive_io(fd, buffer, len);
if (flags != blocking &&
fcntl(fd, F_SETFL, flags) == -1)
return MAD_FLOW_BREAK;
return result;
}
static
enum mad_flow send(int fd, void const *message, unsigned int size)
{
enum mad_flow result;
/* send size */
result = send_io(fd, &size, sizeof(size));
/* send message */
if (result == MAD_FLOW_CONTINUE)
result = send_io(fd, message, size);
return result;
}
static
enum mad_flow receive(int fd, void **message, unsigned int *size)
{
enum mad_flow result;
unsigned int actual;
if (*message == 0)
*size = 0;
/* receive size */
result = receive_io(fd, &actual, sizeof(actual));
/* receive message */
if (result == MAD_FLOW_CONTINUE) {
if (actual > *size)
actual -= *size;
else {
*size = actual;
actual = 0;
}
if (*size > 0) {
if (*message == 0) {
*message = malloc(*size);
if (*message == 0)
return MAD_FLOW_BREAK;
}
result = receive_io_blocking(fd, *message, *size);
}
/* throw away remainder of message */
while (actual && result == MAD_FLOW_CONTINUE) {
char sink[256];
unsigned int len;
len = actual > sizeof(sink) ? sizeof(sink) : actual;
result = receive_io_blocking(fd, sink, len);
actual -= len;
}
}
return result;
}
static
enum mad_flow check_message(struct mad_decoder *decoder)
{
enum mad_flow result;
void *message = 0;
unsigned int size;
result = receive(decoder->async.in, &message, &size);
if (result == MAD_FLOW_CONTINUE) {
if (decoder->message_func == 0)
size = 0;
else {
result = decoder->message_func(decoder->cb_data, message, &size);
if (result == MAD_FLOW_IGNORE ||
result == MAD_FLOW_BREAK)
size = 0;
}
if (send(decoder->async.out, message, size) != MAD_FLOW_CONTINUE)
result = MAD_FLOW_BREAK;
}
if (message)
free(message);
return result;
}
# endif
static
enum mad_flow error_default(void *data, struct mad_stream *stream,
struct mad_frame *frame)
{
int *bad_last_frame = data;
switch (stream->error) {
case MAD_ERROR_BADCRC:
if (*bad_last_frame)
mad_frame_mute(frame);
else
*bad_last_frame = 1;
return MAD_FLOW_IGNORE;
default:
return MAD_FLOW_CONTINUE;
}
}
static
int run_sync(struct mad_decoder *decoder)
{
enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
void *error_data;
int bad_last_frame = 0;
struct mad_stream *stream;
struct mad_frame *frame;
struct mad_synth *synth;
int result = 0;
if (decoder->input_func == 0)
return 0;
if (decoder->error_func) {
error_func = decoder->error_func;
error_data = decoder->cb_data;
}
else {
error_func = error_default;
error_data = &bad_last_frame;
}
stream = &decoder->sync->stream;
frame = &decoder->sync->frame;
synth = &decoder->sync->synth;
mad_stream_init(stream);
mad_frame_init(frame);
mad_synth_init(synth);
mad_stream_options(stream, decoder->options);
do {
switch (decoder->input_func(decoder->cb_data, stream)) {
case MAD_FLOW_STOP:
goto done;
case MAD_FLOW_BREAK:
goto fail;
case MAD_FLOW_IGNORE:
continue;
case MAD_FLOW_CONTINUE:
break;
}
while (1) {
# if defined(USE_ASYNC)
if (decoder->mode == MAD_DECODER_MODE_ASYNC) {
switch (check_message(decoder)) {
case MAD_FLOW_IGNORE:
case MAD_FLOW_CONTINUE:
break;
case MAD_FLOW_BREAK:
goto fail;
case MAD_FLOW_STOP:
goto done;
}
}
# endif
if (decoder->header_func) {
if (mad_header_decode(&frame->header, stream) == -1) {
if (!MAD_RECOVERABLE(stream->error))
break;
switch (error_func(error_data, stream, frame)) {
case MAD_FLOW_STOP:
goto done;
case MAD_FLOW_BREAK:
goto fail;
case MAD_FLOW_IGNORE:
case MAD_FLOW_CONTINUE:
default:
continue;
}
}
switch (decoder->header_func(decoder->cb_data, &frame->header)) {
case MAD_FLOW_STOP:
goto done;
case MAD_FLOW_BREAK:
goto fail;
case MAD_FLOW_IGNORE:
continue;
case MAD_FLOW_CONTINUE:
break;
}
}
if (mad_frame_decode(frame, stream) == -1) {
if (!MAD_RECOVERABLE(stream->error))
break;
switch (error_func(error_data, stream, frame)) {
case MAD_FLOW_STOP:
goto done;
case MAD_FLOW_BREAK:
goto fail;
case MAD_FLOW_IGNORE:
break;
case MAD_FLOW_CONTINUE:
default:
continue;
}
}
else
bad_last_frame = 0;
if (decoder->filter_func) {
switch (decoder->filter_func(decoder->cb_data, stream, frame)) {
case MAD_FLOW_STOP:
goto done;
case MAD_FLOW_BREAK:
goto fail;
case MAD_FLOW_IGNORE:
continue;
case MAD_FLOW_CONTINUE:
break;
}
}
mad_synth_frame(synth, frame);
if (decoder->output_func) {
switch (decoder->output_func(decoder->cb_data,
&frame->header, &synth->pcm)) {
case MAD_FLOW_STOP:
goto done;
case MAD_FLOW_BREAK:
goto fail;
case MAD_FLOW_IGNORE:
case MAD_FLOW_CONTINUE:
break;
}
}
}
}
while (stream->error == MAD_ERROR_BUFLEN);
fail:
result = -1;
done:
mad_synth_finish(synth);
mad_frame_finish(frame);
mad_stream_finish(stream);
return result;
}
# if defined(USE_ASYNC)
static
int run_async(struct mad_decoder *decoder)
{
pid_t pid;
int ptoc[2], ctop[2], flags;
if (pipe(ptoc) == -1)
return -1;
if (pipe(ctop) == -1) {
close(ptoc[0]);
close(ptoc[1]);
return -1;
}
flags = fcntl(ptoc[0], F_GETFL);
if (flags == -1 ||
fcntl(ptoc[0], F_SETFL, flags | O_NONBLOCK) == -1) {
close(ctop[0]);
close(ctop[1]);
close(ptoc[0]);
close(ptoc[1]);
return -1;
}
pid = fork();
if (pid == -1) {
close(ctop[0]);
close(ctop[1]);
close(ptoc[0]);
close(ptoc[1]);
return -1;
}
decoder->async.pid = pid;
if (pid) {
/* parent */
close(ptoc[0]);
close(ctop[1]);
decoder->async.in = ctop[0];
decoder->async.out = ptoc[1];
return 0;
}
/* child */
close(ptoc[1]);
close(ctop[0]);
decoder->async.in = ptoc[0];
decoder->async.out = ctop[1];
_exit(run_sync(decoder));
/* not reached */
return -1;
}
# endif
int mad_decoder_run(struct mad_decoder *decoder, enum mad_decoder_mode mode)
{
int result;
int (*run)(struct mad_decoder *) = 0;
switch (decoder->mode = mode) {
case MAD_DECODER_MODE_SYNC:
run = run_sync;
break;
case MAD_DECODER_MODE_ASYNC:
# if defined(USE_ASYNC)
run = run_async;
# endif
break;
}
if (run == 0)
return -1;
decoder->sync = malloc(sizeof(*decoder->sync));
if (decoder->sync == 0)
return -1;
result = run(decoder);
free(decoder->sync);
decoder->sync = 0;
return result;
}
int mad_decoder_message(struct mad_decoder *decoder,
void *message, unsigned int *len)
{
# if defined(USE_ASYNC)
if (decoder->mode != MAD_DECODER_MODE_ASYNC ||
send(decoder->async.out, message, *len) != MAD_FLOW_CONTINUE ||
receive(decoder->async.in, &message, len) != MAD_FLOW_CONTINUE)
return -1;
return 0;
# else
return -1;
# endif
}
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: decoder.h,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifndef LIBMAD_DECODER_H
# define LIBMAD_DECODER_H
# include "stream.h"
# include "frame.h"
# include "synth.h"
enum mad_decoder_mode {
MAD_DECODER_MODE_SYNC = 0,
MAD_DECODER_MODE_ASYNC
};
enum mad_flow {
MAD_FLOW_CONTINUE = 0x0000, /* continue normally */
MAD_FLOW_STOP = 0x0010, /* stop decoding normally */
MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */
MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */
};
struct mad_decoder {
enum mad_decoder_mode mode;
int options;
struct {
long pid;
int in;
int out;
} async;
struct {
struct mad_stream stream;
struct mad_frame frame;
struct mad_synth synth;
} *sync;
void *cb_data;
enum mad_flow (*input_func)(void *, struct mad_stream *);
enum mad_flow (*header_func)(void *, struct mad_header const *);
enum mad_flow (*filter_func)(void *,
struct mad_stream const *, struct mad_frame *);
enum mad_flow (*output_func)(void *,
struct mad_header const *, struct mad_pcm *);
enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
enum mad_flow (*message_func)(void *, void *, unsigned int *);
};
void mad_decoder_init(struct mad_decoder *, void *,
enum mad_flow (*)(void *, struct mad_stream *),
enum mad_flow (*)(void *, struct mad_header const *),
enum mad_flow (*)(void *,
struct mad_stream const *,
struct mad_frame *),
enum mad_flow (*)(void *,
struct mad_header const *,
struct mad_pcm *),
enum mad_flow (*)(void *,
struct mad_stream *,
struct mad_frame *),
enum mad_flow (*)(void *, void *, unsigned int *));
int mad_decoder_finish(struct mad_decoder *);
# define mad_decoder_options(decoder, opts) \
((void) ((decoder)->options = (opts)))
int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode);
int mad_decoder_message(struct mad_decoder *, void *, unsigned int *);
# endif
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: fixed.c,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include "fixed.h"
/*
* NAME: fixed->abs()
* DESCRIPTION: return absolute value of a fixed-point number
*/
mad_fixed_t mad_f_abs(mad_fixed_t x)
{
return x < 0 ? -x : x;
}
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: fixed.h,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifndef LIBMAD_FIXED_H
# define LIBMAD_FIXED_H
# if SIZEOF_INT >= 4
typedef signed int mad_fixed_t;
typedef signed int mad_fixed64hi_t;
typedef unsigned int mad_fixed64lo_t;
# else
typedef signed long mad_fixed_t;
typedef signed long mad_fixed64hi_t;
typedef unsigned long mad_fixed64lo_t;
# endif
# if defined(_MSC_VER)
# define mad_fixed64_t signed __int64
# elif 1 || defined(__GNUC__)
# define mad_fixed64_t signed long long
# endif
# if defined(FPM_FLOAT)
typedef double mad_sample_t;
# else
typedef mad_fixed_t mad_sample_t;
# endif
/*
* Fixed-point format: 0xABBBBBBB
* A == whole part (sign + 3 bits)
* B == fractional part (28 bits)
*
* Values are signed two's complement, so the effective range is:
* 0x80000000 to 0x7fffffff
* -8.0 to +7.9999999962747097015380859375
*
* The smallest representable value is:
* 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9)
*
* 28 bits of fractional accuracy represent about
* 8.6 digits of decimal accuracy.
*
* Fixed-point numbers can be added or subtracted as normal
* integers, but multiplication requires shifting the 64-bit result
* from 56 fractional bits back to 28 (and rounding.)
*
* Changing the definition of MAD_F_FRACBITS is only partially
* supported, and must be done with care.
*/
# define MAD_F_FRACBITS 28
# if MAD_F_FRACBITS == 28
# define MAD_F(x) ((mad_fixed_t) (x##L))
# else
# if MAD_F_FRACBITS < 28
# warning "MAD_F_FRACBITS < 28"
# define MAD_F(x) ((mad_fixed_t) \
(((x##L) + \
(1L << (28 - MAD_F_FRACBITS - 1))) >> \
(28 - MAD_F_FRACBITS)))
# elif MAD_F_FRACBITS > 28
# error "MAD_F_FRACBITS > 28 not currently supported"
# define MAD_F(x) ((mad_fixed_t) \
((x##L) << (MAD_F_FRACBITS - 28)))
# endif
# endif
# define MAD_F_MIN ((mad_fixed_t) -0x80000000L)
# define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL)
# define MAD_F_ONE MAD_F(0x10000000)
# define mad_f_tofixed(x) ((mad_fixed_t) \
((x) * (double) (1L << MAD_F_FRACBITS) + 0.5))
# define mad_f_todouble(x) ((double) \
((x) / (double) (1L << MAD_F_FRACBITS)))
# define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS)
# define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1))
/* (x should be positive) */
# define mad_f_fromint(x) ((x) << MAD_F_FRACBITS)
# define mad_f_add(x, y) ((x) + (y))
# define mad_f_sub(x, y) ((x) - (y))
# if defined(FPM_FLOAT)
# error "FPM_FLOAT not yet supported"
# undef MAD_F
# define MAD_F(x) mad_f_todouble(x)
# define mad_f_mul(x, y) ((x) * (y))
# define mad_f_scale64
# undef ASO_ZEROCHECK
# elif defined(FPM_64BIT)
/*
* This version should be the most accurate if 64-bit types are supported by
* the compiler, although it may not be the most efficient.
*/
# if defined(OPT_ACCURACY)
# define mad_f_mul(x, y) \
((mad_fixed_t) \
((((mad_fixed64_t) (x) * (y)) + \
(1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS))
# else
# define mad_f_mul(x, y) \
((mad_fixed_t) (((mad_fixed64_t) (x) * (y)) >> MAD_F_SCALEBITS))
# endif
# define MAD_F_SCALEBITS MAD_F_FRACBITS
/* --- Intel --------------------------------------------------------------- */
# elif defined(FPM_INTEL)
# if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable: 4035) /* no return value */
static __forceinline
mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y)
{
enum {
fracbits = MAD_F_FRACBITS
};
__asm {
mov eax, x
imul y
shrd eax, edx, fracbits
}
/* implicit return of eax */
}
# pragma warning(pop)
# define mad_f_mul mad_f_mul_inline
# define mad_f_scale64
# else
/*
* This Intel version is fast and accurate; the disposition of the least
* significant bit depends on OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
asm ("imull %3" \
: "=a" (lo), "=d" (hi) \
: "%a" (x), "rm" (y) \
: "cc")
# if defined(OPT_ACCURACY)
/*
* This gives best accuracy but is not very fast.
*/
# define MAD_F_MLA(hi, lo, x, y) \
({ mad_fixed64hi_t __hi; \
mad_fixed64lo_t __lo; \
MAD_F_MLX(__hi, __lo, (x), (y)); \
asm ("addl %2,%0\n\t" \
"adcl %3,%1" \
: "=rm" (lo), "=rm" (hi) \
: "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \
: "cc"); \
})
# endif /* OPT_ACCURACY */
# if defined(OPT_ACCURACY)
/*
* Surprisingly, this is faster than SHRD followed by ADC.
*/
# define mad_f_scale64(hi, lo) \
({ mad_fixed64hi_t __hi_; \
mad_fixed64lo_t __lo_; \
mad_fixed_t __result; \
asm ("addl %4,%2\n\t" \
"adcl %5,%3" \
: "=rm" (__lo_), "=rm" (__hi_) \
: "0" (lo), "1" (hi), \
"ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \
: "cc"); \
asm ("shrdl %3,%2,%1" \
: "=rm" (__result) \
: "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# else
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
asm ("shrdl %3,%2,%1" \
: "=rm" (__result) \
: "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# endif /* OPT_ACCURACY */
# define MAD_F_SCALEBITS MAD_F_FRACBITS
# endif
/* --- ARM ----------------------------------------------------------------- */
# elif defined(FPM_ARM)
/*
* This ARM V4 version is as accurate as FPM_64BIT but much faster. The
* least significant bit is properly rounded at no CPU cycle cost!
*/
# if 1
/*
* There's a bug somewhere, possibly in the compiler, that sometimes makes
* this necessary instead of the default implementation via MAD_F_MLX and
* mad_f_scale64. It may be related to the use (or lack) of
* -finline-functions and/or -fstrength-reduce.
*
* This is also apparently faster than MAD_F_MLX/mad_f_scale64.
*/
# define mad_f_mul(x, y) \
({ mad_fixed64hi_t __hi; \
mad_fixed64lo_t __lo; \
mad_fixed_t __result; \
asm ("smull %0, %1, %3, %4\n\t" \
"movs %0, %0, lsr %5\n\t" \
"adc %2, %0, %1, lsl %6" \
: "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
: "%r" (x), "r" (y), \
"M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# endif
# define MAD_F_MLX(hi, lo, x, y) \
asm ("smull %0, %1, %2, %3" \
: "=&r" (lo), "=&r" (hi) \
: "%r" (x), "r" (y))
# define MAD_F_MLA(hi, lo, x, y) \
asm ("smlal %0, %1, %2, %3" \
: "+r" (lo), "+r" (hi) \
: "%r" (x), "r" (y))
# define MAD_F_MLN(hi, lo) \
asm ("rsbs %0, %2, #0\n\t" \
"rsc %1, %3, #0" \
: "=r" (lo), "=r" (hi) \
: "0" (lo), "1" (hi) \
: "cc")
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
asm ("movs %0, %1, lsr %3\n\t" \
"adc %0, %0, %2, lsl %4" \
: "=r" (__result) \
: "r" (lo), "r" (hi), \
"M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# define MAD_F_SCALEBITS MAD_F_FRACBITS
/* --- MIPS ---------------------------------------------------------------- */
# elif defined(FPM_MIPS)
/*
* This MIPS version is fast and accurate; the disposition of the least
* significant bit depends on OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
asm ("mult %2,%3" \
: "=l" (lo), "=h" (hi) \
: "%r" (x), "r" (y))
# if defined(HAVE_MADD_ASM)
# define MAD_F_MLA(hi, lo, x, y) \
asm ("madd %2,%3" \
: "+l" (lo), "+h" (hi) \
: "%r" (x), "r" (y))
# elif defined(HAVE_MADD16_ASM)
/*
* This loses significant accuracy due to the 16-bit integer limit in the
* multiply/accumulate instruction.
*/
# define MAD_F_ML0(hi, lo, x, y) \
asm ("mult %2,%3" \
: "=l" (lo), "=h" (hi) \
: "%r" ((x) >> 12), "r" ((y) >> 16))
# define MAD_F_MLA(hi, lo, x, y) \
asm ("madd16 %2,%3" \
: "+l" (lo), "+h" (hi) \
: "%r" ((x) >> 12), "r" ((y) >> 16))
# define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo))
# endif
# if defined(OPT_SPEED)
# define mad_f_scale64(hi, lo) \
((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS)))
# define MAD_F_SCALEBITS MAD_F_FRACBITS
# endif
/* --- SPARC --------------------------------------------------------------- */
# elif defined(FPM_SPARC)
/*
* This SPARC V8 version is fast and accurate; the disposition of the least
* significant bit depends on OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
asm ("smul %2, %3, %0\n\t" \
"rd %%y, %1" \
: "=r" (lo), "=r" (hi) \
: "%r" (x), "rI" (y))
/* --- PowerPC ------------------------------------------------------------- */
# elif defined(FPM_PPC)
/*
* This PowerPC version is tuned for the 4xx embedded processors. It is
* effectively a tuned version of FPM_64BIT. It is a little faster and just
* as accurate. The disposition of the least significant bit depends on
* OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
asm ("mulhw %1, %2, %3\n\t" \
"mullw %0, %2, %3" \
: "=&r" (lo), "=&r" (hi) \
: "%r" (x), "r" (y))
# define MAD_F_MLA(hi, lo, x, y) \
({ mad_fixed64hi_t __hi; \
mad_fixed64lo_t __lo; \
MAD_F_MLX(__hi, __lo, (x), (y)); \
asm ("addc %0, %2, %3\n\t" \
"adde %1, %4, %5" \
: "=r" (lo), "=r" (hi) \
: "%r" (__lo), "0" (lo), "%r" (__hi), "1" (hi)); \
})
# if defined(OPT_ACCURACY)
/*
* This is accurate and ~2 - 2.5 times slower than the unrounded version.
*
* The __volatile__ improves the generated code by another 5% (fewer spills
* to memory); eventually they should be removed.
*/
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
mad_fixed64hi_t __hi_; \
mad_fixed64lo_t __lo_; \
asm __volatile__ ("addc %0, %2, %4\n\t" \
"addze %1, %3" \
: "=r" (__lo_), "=r" (__hi_) \
: "r" (lo), "r" (hi), "r" (1 << (MAD_F_SCALEBITS - 1))); \
asm __volatile__ ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \
"rlwimi %0, %1,32-%3,%3,31" \
: "=&r" (__result) \
: "r" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS)); \
__result; \
})
# else
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
asm ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \
"rlwimi %0, %1,32-%3,%3,31" \
: "=r" (__result) \
: "r" (lo), "r" (hi), "I" (MAD_F_SCALEBITS)); \
__result; \
})
# endif /* OPT_ACCURACY */
# define MAD_F_SCALEBITS MAD_F_FRACBITS
/* --- Default ------------------------------------------------------------- */
# elif defined(FPM_DEFAULT)
/*
* This version is the most portable but it loses significant accuracy.
* Furthermore, accuracy is biased against the second argument, so care
* should be taken when ordering operands.
*
* The scale factors are constant as this is not used with SSO.
*
* Pre-rounding is required to stay within the limits of compliance.
*/
# if defined(OPT_SPEED)
# define mad_f_mul(x, y) (((x) >> 12) * ((y) >> 16))
# else
# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \
(((y) + (1L << 15)) >> 16))
# endif
/* ------------------------------------------------------------------------- */
# else
# error "no FPM selected"
# endif
/* default implementations */
# if !defined(mad_f_mul)
# define mad_f_mul(x, y) \
({ mad_fixed64hi_t __hi; \
mad_fixed64lo_t __lo; \
MAD_F_MLX(__hi, __lo, (x), (y)); \
mad_f_scale64(__hi, __lo); \
})
# endif
# if !defined(MAD_F_MLA)
# define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y)))
# define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y)))
# define MAD_F_MLN(hi, lo) ((lo) = -(lo))
# define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
# endif
# if !defined(MAD_F_ML0)
# define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y))
# endif
# if !defined(MAD_F_MLN)
# define MAD_F_MLN(hi, lo) ((hi) = ((lo) = -(lo)) ? ~(hi) : -(hi))
# endif
# if !defined(MAD_F_MLZ)
# define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo))
# endif
# if !defined(mad_f_scale64)
# if defined(OPT_ACCURACY)
# define mad_f_scale64(hi, lo) \
((((mad_fixed_t) \
(((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \
((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1)
# else
# define mad_f_scale64(hi, lo) \
((mad_fixed_t) \
(((hi) << (32 - MAD_F_SCALEBITS)) | \
((lo) >> MAD_F_SCALEBITS)))
# endif
# define MAD_F_SCALEBITS MAD_F_FRACBITS
# endif
/* miscellaneous C routines */
mad_fixed_t mad_f_abs(mad_fixed_t);
# endif
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: frame.c,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include <stdlib.h>
# include "bit.h"
# include "stream.h"
# include "frame.h"
# include "timer.h"
# include "layer12.h"
# include "layer3.h"
static
unsigned long const bitrate_table[5][15] = {
/* MPEG-1 */
{ 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */
256000, 288000, 320000, 352000, 384000, 416000, 448000 },
{ 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */
128000, 160000, 192000, 224000, 256000, 320000, 384000 },
{ 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */
112000, 128000, 160000, 192000, 224000, 256000, 320000 },
/* MPEG-2 LSF */
{ 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */
128000, 144000, 160000, 176000, 192000, 224000, 256000 },
{ 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */
64000, 80000, 96000, 112000, 128000, 144000, 160000 } /* II & III */
};
static
unsigned int const samplerate_table[3] = { 44100, 48000, 32000 };
static
int (*const decoder_table[3])(struct mad_stream *, struct mad_frame *) = {
mad_layer_I,
mad_layer_II,
mad_layer_III
};
/*
* NAME: header->init()
* DESCRIPTION: initialize header struct
*/
void mad_header_init(struct mad_header *header)
{
header->layer = 0;
header->mode = 0;
header->mode_extension = 0;
header->emphasis = 0;
header->bitrate = 0;
header->samplerate = 0;
header->crc_check = 0;
header->crc_target = 0;
header->flags = 0;
header->private_bits = 0;
header->duration = mad_timer_zero;
}
/*
* NAME: frame->init()
* DESCRIPTION: initialize frame struct
*/
void mad_frame_init(struct mad_frame *frame)
{
mad_header_init(&frame->header);
frame->options = 0;
frame->overlap = 0;
mad_frame_mute(frame);
}
/*
* NAME: frame->finish()
* DESCRIPTION: deallocate any dynamic memory associated with frame
*/
void mad_frame_finish(struct mad_frame *frame)
{
mad_header_finish(&frame->header);
if (frame->overlap) {
free(frame->overlap);
frame->overlap = 0;
}
}
/*
* NAME: decode_header()
* DESCRIPTION: read header data and following CRC word
*/
static
int decode_header(struct mad_header *header, struct mad_stream *stream)
{
unsigned int index;
header->flags = 0;
header->private_bits = 0;
/* header() */
/* syncword */
mad_bit_skip(&stream->ptr, 11);
/* MPEG 2.5 indicator (really part of syncword) */
if (mad_bit_read(&stream->ptr, 1) == 0)
header->flags |= MAD_FLAG_MPEG_2_5_EXT;
/* ID */
if (mad_bit_read(&stream->ptr, 1) == 0)
header->flags |= MAD_FLAG_LSF_EXT;
else if (header->flags & MAD_FLAG_MPEG_2_5_EXT) {
stream->error = MAD_ERROR_LOSTSYNC;
return -1;
}
/* layer */
header->layer = 4 - mad_bit_read(&stream->ptr, 2);
if (header->layer == 4) {
stream->error = MAD_ERROR_BADLAYER;
return -1;
}
/* protection_bit */
if (mad_bit_read(&stream->ptr, 1) == 0) {
header->flags |= MAD_FLAG_PROTECTION;
header->crc_check = mad_bit_crc(stream->ptr, 16, 0xffff);
}
/* bitrate_index */
index = mad_bit_read(&stream->ptr, 4);
if (index == 15) {
stream->error = MAD_ERROR_BADBITRATE;
return -1;
}
if (header->flags & MAD_FLAG_LSF_EXT)
header->bitrate = bitrate_table[3 + (header->layer >> 1)][index];
else
header->bitrate = bitrate_table[header->layer - 1][index];
/* sampling_frequency */
index = mad_bit_read(&stream->ptr, 2);
if (index == 3) {
stream->error = MAD_ERROR_BADSAMPLERATE;
return -1;
}
header->samplerate = samplerate_table[index];
if (header->flags & MAD_FLAG_LSF_EXT) {
header->samplerate /= 2;
if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
header->samplerate /= 2;
}
/* padding_bit */
if (mad_bit_read(&stream->ptr, 1))
header->flags |= MAD_FLAG_PADDING;
/* private_bit */
if (mad_bit_read(&stream->ptr, 1))
header->private_bits |= MAD_PRIVATE_HEADER;
/* mode */
header->mode = 3 - mad_bit_read(&stream->ptr, 2);
/* mode_extension */
header->mode_extension = mad_bit_read(&stream->ptr, 2);
/* copyright */
if (mad_bit_read(&stream->ptr, 1))
header->flags |= MAD_FLAG_COPYRIGHT;
/* original/copy */
if (mad_bit_read(&stream->ptr, 1))
header->flags |= MAD_FLAG_ORIGINAL;
/* emphasis */
header->emphasis = mad_bit_read(&stream->ptr, 2);
if (header->emphasis == 2) {
stream->error = MAD_ERROR_BADEMPHASIS;
return -1;
}
/* error_check() */
/* crc_check */
if (header->flags & MAD_FLAG_PROTECTION)
header->crc_target = mad_bit_read(&stream->ptr, 16);
return 0;
}
/*
* NAME: free_bitrate()
* DESCRIPTION: attempt to discover the bitstream's free bitrate
*/
static
int free_bitrate(struct mad_stream *stream, struct mad_header const *header)
{
struct mad_bitptr keep_ptr;
unsigned long rate = 0;
unsigned int pad_slot, slots_per_frame;
unsigned char const *ptr = 0;
keep_ptr = stream->ptr;
pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0;
slots_per_frame = (header->layer == MAD_LAYER_III &&
(header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144;
while (mad_stream_sync(stream) == 0) {
struct mad_stream peek_stream;
struct mad_header peek_header;
peek_stream = *stream;
peek_header = *header;
if (decode_header(&peek_header, &peek_stream) == 0 &&
peek_header.layer == header->layer &&
peek_header.samplerate == header->samplerate) {
unsigned int N;
ptr = mad_bit_nextbyte(&stream->ptr);
N = ptr - stream->this_frame;
if (header->layer == MAD_LAYER_I) {
rate = (unsigned long) header->samplerate *
(N - 4 * pad_slot + 4) / 48 / 1000;
}
else {
rate = (unsigned long) header->samplerate *
(N - pad_slot + 1) / slots_per_frame / 1000;
}
if (rate >= 8)
break;
}
mad_bit_skip(&stream->ptr, 8);
}
stream->ptr = keep_ptr;
if (rate < 8 || (header->layer == MAD_LAYER_III && rate > 640)) {
stream->error = MAD_ERROR_LOSTSYNC;
return -1;
}
stream->freerate = rate * 1000;
# if 0 && defined(DEBUG)
fprintf(stderr, "free bitrate == %lu\n", stream->freerate);
# endif
return 0;
}
/*
* NAME: header->decode()
* DESCRIPTION: read the next frame header from the stream
*/
int mad_header_decode(struct mad_header *header, struct mad_stream *stream)
{
register unsigned char const *ptr, *end;
unsigned int pad_slot, N;
ptr = stream->next_frame;
end = stream->bufend;
if (ptr == 0) {
stream->error = MAD_ERROR_BUFPTR;
goto fail;
}
/* stream skip */
if (stream->skiplen) {
if (!stream->sync)
ptr = stream->this_frame;
if (end - ptr < stream->skiplen) {
stream->skiplen -= end - ptr;
stream->next_frame = end;
stream->error = MAD_ERROR_BUFLEN;
goto fail;
}
ptr += stream->skiplen;
stream->skiplen = 0;
stream->sync = 1;
}
sync:
/* synchronize */
if (stream->sync) {
if (end - ptr < MAD_BUFFER_GUARD) {
stream->next_frame = ptr;
stream->error = MAD_ERROR_BUFLEN;
goto fail;
}
else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
/* mark point where frame sync word was expected */
stream->this_frame = ptr;
stream->next_frame = ptr + 1;
stream->error = MAD_ERROR_LOSTSYNC;
goto fail;
}
}
else {
mad_bit_init(&stream->ptr, ptr);
if (mad_stream_sync(stream) == -1) {
if (end - stream->next_frame >= MAD_BUFFER_GUARD)
stream->next_frame = end - MAD_BUFFER_GUARD;
stream->error = MAD_ERROR_BUFLEN;
goto fail;
}
ptr = mad_bit_nextbyte(&stream->ptr);
}
/* begin processing */
stream->this_frame = ptr;
stream->next_frame = ptr + 1; /* possibly bogus sync word */
mad_bit_init(&stream->ptr, stream->this_frame);
if (decode_header(header, stream) == -1)
goto fail;
/* calculate frame duration */
mad_timer_set(&header->duration, 0,
32 * MAD_NSBSAMPLES(header), header->samplerate);
/* calculate free bit rate */
if (header->bitrate == 0) {
if ((stream->freerate == 0 || !stream->sync) &&
free_bitrate(stream, header) == -1)
goto fail;
header->bitrate = stream->freerate;
header->flags |= MAD_FLAG_FREEFORMAT;
}
/* calculate beginning of next frame */
pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0;
if (header->layer == MAD_LAYER_I)
N = ((12 * header->bitrate / header->samplerate) + pad_slot) * 4;
else {
unsigned int slots_per_frame;
slots_per_frame = (header->layer == MAD_LAYER_III &&
(header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144;
N = (slots_per_frame * header->bitrate / header->samplerate) + pad_slot;
}
/* verify there is enough data left in buffer to decode this frame */
if (N + MAD_BUFFER_GUARD > end - stream->this_frame) {
stream->next_frame = stream->this_frame;
stream->error = MAD_ERROR_BUFLEN;
goto fail;
}
stream->next_frame = stream->this_frame + N;
if (!stream->sync) {
/* check that a valid frame header follows this frame */
ptr = stream->next_frame;
if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
ptr = stream->next_frame = stream->this_frame + 1;
goto sync;
}
stream->sync = 1;
}
header->flags |= MAD_FLAG_INCOMPLETE;
return 0;
fail:
stream->sync = 0;
return -1;
}
/*
* NAME: frame->decode()
* DESCRIPTION: decode a single frame from a bitstream
*/
int mad_frame_decode(struct mad_frame *frame, struct mad_stream *stream)
{
frame->options = stream->options;
/* header() */
/* error_check() */
if (!(frame->header.flags & MAD_FLAG_INCOMPLETE) &&
mad_header_decode(&frame->header, stream) == -1)
goto fail;
/* audio_data() */
frame->header.flags &= ~MAD_FLAG_INCOMPLETE;
if (decoder_table[frame->header.layer - 1](stream, frame) == -1) {
if (!MAD_RECOVERABLE(stream->error))
stream->next_frame = stream->this_frame;
goto fail;
}
/* ancillary_data() */
if (frame->header.layer != MAD_LAYER_III) {
struct mad_bitptr next_frame;
mad_bit_init(&next_frame, stream->next_frame);
stream->anc_ptr = stream->ptr;
stream->anc_bitlen = mad_bit_length(&stream->ptr, &next_frame);
mad_bit_finish(&next_frame);
}
return 0;
fail:
stream->anc_bitlen = 0;
return -1;
}
/*
* NAME: frame->mute()
* DESCRIPTION: zero all subband values so the frame becomes silent
*/
void mad_frame_mute(struct mad_frame *frame)
{
unsigned int s, sb;
for (s = 0; s < 36; ++s) {
for (sb = 0; sb < 32; ++sb) {
frame->sbsample[0][s][sb] =
frame->sbsample[1][s][sb] = 0;
}
}
if (frame->overlap) {
for (s = 0; s < 18; ++s) {
for (sb = 0; sb < 32; ++sb) {
(*frame->overlap)[0][sb][s] =
(*frame->overlap)[1][sb][s] = 0;
}
}
}
}
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: frame.h,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifndef LIBMAD_FRAME_H
# define LIBMAD_FRAME_H
# include "fixed.h"
# include "timer.h"
# include "stream.h"
enum mad_layer {
MAD_LAYER_I = 1, /* Layer I */
MAD_LAYER_II = 2, /* Layer II */
MAD_LAYER_III = 3 /* Layer III */
};
enum mad_mode {
MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */
MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */
MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */
MAD_MODE_STEREO = 3 /* normal LR stereo */
};
enum mad_emphasis {
MAD_EMPHASIS_NONE = 0, /* no emphasis */
MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */
MAD_EMPHASIS_CCITT_J_17 = 3 /* CCITT J.17 emphasis */
};
struct mad_header {
enum mad_layer layer; /* audio layer (1, 2, or 3) */
enum mad_mode mode; /* channel mode (see above) */
int mode_extension; /* additional mode info */
enum mad_emphasis emphasis; /* de-emphasis to use (see above) */
unsigned long bitrate; /* stream bitrate (bps) */
unsigned int samplerate; /* sampling frequency (Hz) */
unsigned short crc_check; /* frame CRC accumulator */
unsigned short crc_target; /* final target CRC checksum */
int flags; /* flags (see below) */
int private_bits; /* private bits (see below) */
mad_timer_t duration; /* audio playing time of frame */
};
struct mad_frame {
struct mad_header header; /* MPEG audio header */
int options; /* decoding options (from stream) */
mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */
mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */
};
# define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1)
# define MAD_NSBSAMPLES(header) \
((header)->layer == MAD_LAYER_I ? 12 : \
(((header)->layer == MAD_LAYER_III && \
((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36))
enum {
MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */
MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */
MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */
MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */
MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */
MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */
MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */
MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */
MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */
MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */
MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */
MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */
};
enum {
MAD_PRIVATE_HEADER = 0x0100, /* header private bit */
MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */
};
void mad_header_init(struct mad_header *);
# define mad_header_finish(header) /* nothing */
int mad_header_decode(struct mad_header *, struct mad_stream *);
void mad_frame_init(struct mad_frame *);
void mad_frame_finish(struct mad_frame *);
int mad_frame_decode(struct mad_frame *, struct mad_stream *);
void mad_frame_mute(struct mad_frame *);
# endif
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: global.h,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifndef LIBMAD_GLOBAL_H
# define LIBMAD_GLOBAL_H
/* conditional debugging */
# if defined(DEBUG) && defined(NDEBUG)
# error "cannot define both DEBUG and NDEBUG"
# endif
# if defined(DEBUG)
# include <stdio.h>
# endif
/* conditional features */
# if defined(OPT_SPEED) && defined(OPT_ACCURACY)
# error "cannot optimize for both speed and accuracy"
# endif
# if defined(OPT_SPEED) && !defined(OPT_SSO)
# define OPT_SSO 1
# endif
# if defined(HAVE_UNISTD_H) && defined(HAVE_WAITPID) && \
defined(HAVE_FCNTL) && defined(HAVE_PIPE) && defined(HAVE_FORK)
# define USE_ASYNC
# endif
# if !defined(HAVE_ASSERT_H)
# if defined(NDEBUG)
# define assert(x) /* nothing */
# else
# define assert(x) do { if (!(x)) abort(); } while (0)
# endif
# endif
# endif
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: huffman.c,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include "huffman.h"
/*
* These are the Huffman code words for Layer III.
* The data for these tables are derived from Table B.7 of ISO/IEC 11172-3.
*
* These tables support decoding up to 4 Huffman code bits at a time.
*/
# if defined(__GNUC__)
# define PTR(offs, bits) { ptr: { 0, bits, offs } }
# define V(v, w, x, y, hlen) { value: { 1, hlen, v, w, x, y } }
# else
# define PTR(offs, bits) { { 0, bits, offs } }
# define V(v, w, x, y, hlen) { { 1, hlen, (v << 0) | (w << 1) | \
(x << 2) | (y << 3) } }
# endif
static
union huffquad const hufftabA[] = {
/* 0000 */ PTR(16, 2),
/* 0001 */ PTR(20, 2),
/* 0010 */ PTR(24, 1),
/* 0011 */ PTR(26, 1),
/* 0100 */ V(0, 0, 1, 0, 4),
/* 0101 */ V(0, 0, 0, 1, 4),
/* 0110 */ V(0, 1, 0, 0, 4),
/* 0111 */ V(1, 0, 0, 0, 4),
/* 1000 */ V(0, 0, 0, 0, 1),
/* 1001 */ V(0, 0, 0, 0, 1),
/* 1010 */ V(0, 0, 0, 0, 1),
/* 1011 */ V(0, 0, 0, 0, 1),
/* 1100 */ V(0, 0, 0, 0, 1),
/* 1101 */ V(0, 0, 0, 0, 1),
/* 1110 */ V(0, 0, 0, 0, 1),
/* 1111 */ V(0, 0, 0, 0, 1),
/* 0000 ... */
/* 00 */ V(1, 0, 1, 1, 2), /* 16 */
/* 01 */ V(1, 1, 1, 1, 2),
/* 10 */ V(1, 1, 0, 1, 2),
/* 11 */ V(1, 1, 1, 0, 2),
/* 0001 ... */
/* 00 */ V(0, 1, 1, 1, 2), /* 20 */
/* 01 */ V(0, 1, 0, 1, 2),
/* 10 */ V(1, 0, 0, 1, 1),
/* 11 */ V(1, 0, 0, 1, 1),
/* 0010 ... */
/* 0 */ V(0, 1, 1, 0, 1), /* 24 */
/* 1 */ V(0, 0, 1, 1, 1),
/* 0011 ... */
/* 0 */ V(1, 0, 1, 0, 1), /* 26 */
/* 1 */ V(1, 1, 0, 0, 1)
};
static
union huffquad const hufftabB[] = {
/* 0000 */ V(1, 1, 1, 1, 4),
/* 0001 */ V(1, 1, 1, 0, 4),
/* 0010 */ V(1, 1, 0, 1, 4),
/* 0011 */ V(1, 1, 0, 0, 4),
/* 0100 */ V(1, 0, 1, 1, 4),
/* 0101 */ V(1, 0, 1, 0, 4),
/* 0110 */ V(1, 0, 0, 1, 4),
/* 0111 */ V(1, 0, 0, 0, 4),
/* 1000 */ V(0, 1, 1, 1, 4),
/* 1001 */ V(0, 1, 1, 0, 4),
/* 1010 */ V(0, 1, 0, 1, 4),
/* 1011 */ V(0, 1, 0, 0, 4),
/* 1100 */ V(0, 0, 1, 1, 4),
/* 1101 */ V(0, 0, 1, 0, 4),
/* 1110 */ V(0, 0, 0, 1, 4),
/* 1111 */ V(0, 0, 0, 0, 4)
};
# undef V
# undef PTR
# if defined(__GNUC__)
# define PTR(offs, bits) { ptr: { 0, bits, offs } }
# define V(x, y, hlen) { value: { 1, hlen, x, y } }
# else
# define PTR(offs, bits) { { 0, bits, offs } }
# define V(x, y, hlen) { { 1, hlen, (x << 0) | (y << 4) } }
# endif
static
union huffpair const hufftab0[] = {
/* */ V(0, 0, 0)
};
static
union huffpair const hufftab1[] = {
/* 000 */ V(1, 1, 3),
/* 001 */ V(0, 1, 3),
/* 010 */ V(1, 0, 2),
/* 011 */ V(1, 0, 2),
/* 100 */ V(0, 0, 1),
/* 101 */ V(0, 0, 1),
/* 110 */ V(0, 0, 1),
/* 111 */ V(0, 0, 1)
};
static
union huffpair const hufftab2[] = {
/* 000 */ PTR(8, 3),
/* 001 */ V(1, 1, 3),
/* 010 */ V(0, 1, 3),
/* 011 */ V(1, 0, 3),
/* 100 */ V(0, 0, 1),
/* 101 */ V(0, 0, 1),
/* 110 */ V(0, 0, 1),
/* 111 */ V(0, 0, 1),
/* 000 ... */
/* 000 */ V(2, 2, 3), /* 8 */
/* 001 */ V(0, 2, 3),
/* 010 */ V(1, 2, 2),
/* 011 */ V(1, 2, 2),
/* 100 */ V(2, 1, 2),
/* 101 */ V(2, 1, 2),
/* 110 */ V(2, 0, 2),
/* 111 */ V(2, 0, 2)
};
static
union huffpair const hufftab3[] = {
/* 000 */ PTR(8, 3),
/* 001 */ V(1, 0, 3),
/* 010 */ V(1, 1, 2),
/* 011 */ V(1, 1, 2),
/* 100 */ V(0, 1, 2),
/* 101 */ V(0, 1, 2),
/* 110 */ V(0, 0, 2),
/* 111 */ V(0, 0, 2),
/* 000 ... */
/* 000 */ V(2, 2, 3), /* 8 */
/* 001 */ V(0, 2, 3),
/* 010 */ V(1, 2, 2),
/* 011 */ V(1, 2, 2),
/* 100 */ V(2, 1, 2),
/* 101 */ V(2, 1, 2),
/* 110 */ V(2, 0, 2),
/* 111 */ V(2, 0, 2)
};
static
union huffpair const hufftab5[] = {
/* 000 */ PTR(8, 4),
/* 001 */ V(1, 1, 3),
/* 010 */ V(0, 1, 3),
/* 011 */ V(1, 0, 3),
/* 100 */ V(0, 0, 1),
/* 101 */ V(0, 0, 1),
/* 110 */ V(0, 0, 1),
/* 111 */ V(0, 0, 1),
/* 000 ... */
/* 0000 */ PTR(24, 1), /* 8 */
/* 0001 */ V(3, 2, 4),
/* 0010 */ V(3, 1, 3),
/* 0011 */ V(3, 1, 3),
/* 0100 */ V(1, 3, 4),
/* 0101 */ V(0, 3, 4),
/* 0110 */ V(3, 0, 4),
/* 0111 */ V(2, 2, 4),
/* 1000 */ V(1, 2, 3),
/* 1001 */ V(1, 2, 3),
/* 1010 */ V(2, 1, 3),
/* 1011 */ V(2, 1, 3),
/* 1100 */ V(0, 2, 3),
/* 1101 */ V(0, 2, 3),
/* 1110 */ V(2, 0, 3),
/* 1111 */ V(2, 0, 3),
/* 000 0000 ... */
/* 0 */ V(3, 3, 1), /* 24 */
/* 1 */ V(2, 3, 1)
};
static
union huffpair const hufftab6[] = {
/* 0000 */ PTR(16, 3),
/* 0001 */ PTR(24, 1),
/* 0010 */ PTR(26, 1),
/* 0011 */ V(1, 2, 4),
/* 0100 */ V(2, 1, 4),
/* 0101 */ V(2, 0, 4),
/* 0110 */ V(0, 1, 3),
/* 0111 */ V(0, 1, 3),
/* 1000 */ V(1, 1, 2),
/* 1001 */ V(1, 1, 2),
/* 1010 */ V(1, 1, 2),
/* 1011 */ V(1, 1, 2),
/* 1100 */ V(1, 0, 3),
/* 1101 */ V(1, 0, 3),
/* 1110 */ V(0, 0, 3),
/* 1111 */ V(0, 0, 3),
/* 0000 ... */
/* 000 */ V(3, 3, 3), /* 16 */
/* 001 */ V(0, 3, 3),
/* 010 */ V(2, 3, 2),
/* 011 */ V(2, 3, 2),
/* 100 */ V(3, 2, 2),
/* 101 */ V(3, 2, 2),
/* 110 */ V(3, 0, 2),
/* 111 */ V(3, 0, 2),
/* 0001 ... */
/* 0 */ V(1, 3, 1), /* 24 */
/* 1 */ V(3, 1, 1),
/* 0010 ... */
/* 0 */ V(2, 2, 1), /* 26 */
/* 1 */ V(0, 2, 1)
};
static
union huffpair const hufftab7[] = {
/* 0000 */ PTR(16, 4),
/* 0001 */ PTR(32, 4),
/* 0010 */ PTR(48, 2),
/* 0011 */ V(1, 1, 4),
/* 0100 */ V(0, 1, 3),
/* 0101 */ V(0, 1, 3),
/* 0110 */ V(1, 0, 3),
/* 0111 */ V(1, 0, 3),
/* 1000 */ V(0, 0, 1),
/* 1001 */ V(0, 0, 1),
/* 1010 */ V(0, 0, 1),
/* 1011 */ V(0, 0, 1),
/* 1100 */ V(0, 0, 1),
/* 1101 */ V(0, 0, 1),
/* 1110 */ V(0, 0, 1),
/* 1111 */ V(0, 0, 1),
/* 0000 ... */
/* 0000 */ PTR(52, 2), /* 16 */
/* 0001 */ PTR(56, 1),
/* 0010 */ PTR(58, 1),
/* 0011 */ V(1, 5, 4),
/* 0100 */ V(5, 1, 4),
/* 0101 */ PTR(60, 1),
/* 0110 */ V(5, 0, 4),
/* 0111 */ PTR(62, 1),
/* 1000 */ V(2, 4, 4),
/* 1001 */ V(4, 2, 4),
/* 1010 */ V(1, 4, 3),
/* 1011 */ V(1, 4, 3),
/* 1100 */ V(4, 1, 3),
/* 1101 */ V(4, 1, 3),
/* 1110 */ V(4, 0, 3),
/* 1111 */ V(4, 0, 3),
/* 0001 ... */
/* 0000 */ V(0, 4, 4), /* 32 */
/* 0001 */ V(2, 3, 4),
/* 0010 */ V(3, 2, 4),
/* 0011 */ V(0, 3, 4),
/* 0100 */ V(1, 3, 3),
/* 0101 */ V(1, 3, 3),
/* 0110 */ V(3, 1, 3),
/* 0111 */ V(3, 1, 3),
/* 1000 */ V(3, 0, 3),
/* 1001 */ V(3, 0, 3),
/* 1010 */ V(2, 2, 3),
/* 1011 */ V(2, 2, 3),
/* 1100 */ V(1, 2, 2),
/* 1101 */ V(1, 2, 2),
/* 1110 */ V(1, 2, 2),
/* 1111 */ V(1, 2, 2),
/* 0010 ... */
/* 00 */ V(2, 1, 1), /* 48 */
/* 01 */ V(2, 1, 1),
/* 10 */ V(0, 2, 2),
/* 11 */ V(2, 0, 2),
/* 0000 0000 ... */
/* 00 */ V(5, 5, 2), /* 52 */
/* 01 */ V(4, 5, 2),
/* 10 */ V(5, 4, 2),
/* 11 */ V(5, 3, 2),
/* 0000 0001 ... */
/* 0 */ V(3, 5, 1), /* 56 */
/* 1 */ V(4, 4, 1),
/* 0000 0010 ... */
/* 0 */ V(2, 5, 1), /* 58 */
/* 1 */ V(5, 2, 1),
/* 0000 0101 ... */
/* 0 */ V(0, 5, 1), /* 60 */
/* 1 */ V(3, 4, 1),
/* 0000 0111 ... */
/* 0 */ V(4, 3, 1), /* 62 */
/* 1 */ V(3, 3, 1)
};
# if 0
/* this version saves 8 entries (16 bytes) at the expense of
an extra lookup in 4 out of 36 cases */
static
union huffpair const hufftab8[] = {
/* 0000 */ PTR(16, 4),
/* 0001 */ PTR(32, 2),
/* 0010 */ V(1, 2, 4),
/* 0011 */ V(2, 1, 4),
/* 0100 */ V(1, 1, 2),
/* 0101 */ V(1, 1, 2),
/* 0110 */ V(1, 1, 2),
/* 0111 */ V(1, 1, 2),
/* 1000 */ V(0, 1, 3),
/* 1001 */ V(0, 1, 3),
/* 1010 */ V(1, 0, 3),
/* 1011 */ V(1, 0, 3),
/* 1100 */ V(0, 0, 2),
/* 1101 */ V(0, 0, 2),
/* 1110 */ V(0, 0, 2),
/* 1111 */ V(0, 0, 2),
/* 0000 ... */
/* 0000 */ PTR(36, 3), /* 16 */
/* 0001 */ PTR(44, 2),
/* 0010 */ PTR(48, 1),
/* 0011 */ V(1, 5, 4),
/* 0100 */ V(5, 1, 4),
/* 0101 */ PTR(50, 1),
/* 0110 */ PTR(52, 1),
/* 0111 */ V(2, 4, 4),
/* 1000 */ V(4, 2, 4),
/* 1001 */ V(1, 4, 4),
/* 1010 */ V(4, 1, 3),
/* 1011 */ V(4, 1, 3),
/* 1100 */ V(0, 4, 4),
/* 1101 */ V(4, 0, 4),
/* 1110 */ V(2, 3, 4),
/* 1111 */ V(3, 2, 4),
/* 0001 ... */
/* 00 */ PTR(54, 2), /* 32 */
/* 01 */ V(2, 2, 2),
/* 10 */ V(0, 2, 2),
/* 11 */ V(2, 0, 2),
/* 0000 0000 ... */
/* 000 */ V(5, 5, 3), /* 36 */
/* 001 */ V(5, 4, 3),
/* 010 */ V(4, 5, 2),
/* 011 */ V(4, 5, 2),
/* 100 */ V(5, 3, 1),
/* 101 */ V(5, 3, 1),
/* 110 */ V(5, 3, 1),
/* 111 */ V(5, 3, 1),
/* 0000 0001 ... */
/* 00 */ V(3, 5, 2), /* 44 */
/* 01 */ V(4, 4, 2),
/* 10 */ V(2, 5, 1),
/* 11 */ V(2, 5, 1),
/* 0000 0010 ... */
/* 0 */ V(5, 2, 1), /* 48 */
/* 1 */ V(0, 5, 1),
/* 0000 0101 ... */
/* 0 */ V(3, 4, 1), /* 50 */
/* 1 */ V(4, 3, 1),
/* 0000 0110 ... */
/* 0 */ V(5, 0, 1), /* 52 */
/* 1 */ V(3, 3, 1),
/* 0001 00 ... */
/* 00 */ V(1, 3, 2), /* 54 */
/* 01 */ V(3, 1, 2),
/* 10 */ V(0, 3, 2),
/* 11 */ V(3, 0, 2),
};
# else
static
union huffpair const hufftab8[] = {
/* 0000 */ PTR(16, 4),
/* 0001 */ PTR(32, 4),
/* 0010 */ V(1, 2, 4),
/* 0011 */ V(2, 1, 4),
/* 0100 */ V(1, 1, 2),
/* 0101 */ V(1, 1, 2),
/* 0110 */ V(1, 1, 2),
/* 0111 */ V(1, 1, 2),
/* 1000 */ V(0, 1, 3),
/* 1001 */ V(0, 1, 3),
/* 1010 */ V(1, 0, 3),
/* 1011 */ V(1, 0, 3),
/* 1100 */ V(0, 0, 2),
/* 1101 */ V(0, 0, 2),
/* 1110 */ V(0, 0, 2),
/* 1111 */ V(0, 0, 2),
/* 0000 ... */
/* 0000 */ PTR(48, 3), /* 16 */
/* 0001 */ PTR(56, 2),
/* 0010 */ PTR(60, 1),
/* 0011 */ V(1, 5, 4),
/* 0100 */ V(5, 1, 4),
/* 0101 */ PTR(62, 1),
/* 0110 */ PTR(64, 1),
/* 0111 */ V(2, 4, 4),
/* 1000 */ V(4, 2, 4),
/* 1001 */ V(1, 4, 4),
/* 1010 */ V(4, 1, 3),
/* 1011 */ V(4, 1, 3),
/* 1100 */ V(0, 4, 4),
/* 1101 */ V(4, 0, 4),
/* 1110 */ V(2, 3, 4),
/* 1111 */ V(3, 2, 4),
/* 0001 ... */
/* 0000 */ V(1, 3, 4), /* 32 */
/* 0001 */ V(3, 1, 4),
/* 0010 */ V(0, 3, 4),
/* 0011 */ V(3, 0, 4),
/* 0100 */ V(2, 2, 2),
/* 0101 */ V(2, 2, 2),
/* 0110 */ V(2, 2, 2),
/* 0111 */ V(2, 2, 2),
/* 1000 */ V(0, 2, 2),
/* 1001 */ V(0, 2, 2),
/* 1010 */ V(0, 2, 2),
/* 1011 */ V(0, 2, 2),
/* 1100 */ V(2, 0, 2),
/* 1101 */ V(2, 0, 2),
/* 1110 */ V(2, 0, 2),
/* 1111 */ V(2, 0, 2),
/* 0000 0000 ... */
/* 000 */ V(5, 5, 3), /* 48 */
/* 001 */ V(5, 4, 3),
/* 010 */ V(4, 5, 2),
/* 011 */ V(4, 5, 2),
/* 100 */ V(5, 3, 1),
/* 101 */ V(5, 3, 1),
/* 110 */ V(5, 3, 1),
/* 111 */ V(5, 3, 1),
/* 0000 0001 ... */
/* 00 */ V(3, 5, 2), /* 56 */
/* 01 */ V(4, 4, 2),
/* 10 */ V(2, 5, 1),
/* 11 */ V(2, 5, 1),
/* 0000 0010 ... */
/* 0 */ V(5, 2, 1), /* 60 */
/* 1 */ V(0, 5, 1),
/* 0000 0101 ... */
/* 0 */ V(3, 4, 1), /* 62 */
/* 1 */ V(4, 3, 1),
/* 0000 0110 ... */
/* 0 */ V(5, 0, 1), /* 64 */
/* 1 */ V(3, 3, 1)
};
# endif
static
union huffpair const hufftab9[] = {
/* 0000 */ PTR(16, 4),
/* 0001 */ PTR(32, 3),
/* 0010 */ PTR(40, 2),
/* 0011 */ PTR(44, 2),
/* 0100 */ PTR(48, 1),
/* 0101 */ V(1, 2, 4),
/* 0110 */ V(2, 1, 4),
/* 0111 */ V(2, 0, 4),
/* 1000 */ V(1, 1, 3),
/* 1001 */ V(1, 1, 3),
/* 1010 */ V(0, 1, 3),
/* 1011 */ V(0, 1, 3),
/* 1100 */ V(1, 0, 3),
/* 1101 */ V(1, 0, 3),
/* 1110 */ V(0, 0, 3),
/* 1111 */ V(0, 0, 3),
/* 0000 ... */
/* 0000 */ PTR(50, 1), /* 16 */
/* 0001 */ V(3, 5, 4),
/* 0010 */ V(5, 3, 4),
/* 0011 */ PTR(52, 1),
/* 0100 */ V(4, 4, 4),
/* 0101 */ V(2, 5, 4),
/* 0110 */ V(5, 2, 4),
/* 0111 */ V(1, 5, 4),
/* 1000 */ V(5, 1, 3),
/* 1001 */ V(5, 1, 3),
/* 1010 */ V(3, 4, 3),
/* 1011 */ V(3, 4, 3),
/* 1100 */ V(4, 3, 3),
/* 1101 */ V(4, 3, 3),
/* 1110 */ V(5, 0, 4),
/* 1111 */ V(0, 4, 4),
/* 0001 ... */
/* 000 */ V(2, 4, 3), /* 32 */
/* 001 */ V(4, 2, 3),
/* 010 */ V(3, 3, 3),
/* 011 */ V(4, 0, 3),
/* 100 */ V(1, 4, 2),
/* 101 */ V(1, 4, 2),
/* 110 */ V(4, 1, 2),
/* 111 */ V(4, 1, 2),
/* 0010 ... */
/* 00 */ V(2, 3, 2), /* 40 */
/* 01 */ V(3, 2, 2),
/* 10 */ V(1, 3, 1),
/* 11 */ V(1, 3, 1),
/* 0011 ... */
/* 00 */ V(3, 1, 1), /* 44 */
/* 01 */ V(3, 1, 1),
/* 10 */ V(0, 3, 2),
/* 11 */ V(3, 0, 2),
/* 0100 ... */
/* 0 */ V(2, 2, 1), /* 48 */
/* 1 */ V(0, 2, 1),
/* 0000 0000 ... */
/* 0 */ V(5, 5, 1), /* 50 */
/* 1 */ V(4, 5, 1),
/* 0000 0011 ... */
/* 0 */ V(5, 4, 1), /* 52 */
/* 1 */ V(0, 5, 1)
};
static
union huffpair const hufftab10[] = {
/* 0000 */ PTR(16, 4),
/* 0001 */ PTR(32, 4),
/* 0010 */ PTR(48, 2),
/* 0011 */ V(1, 1, 4),
/* 0100 */ V(0, 1, 3),
/* 0101 */ V(0, 1, 3),
/* 0110 */ V(1, 0, 3),
/* 0111 */ V(1, 0, 3),
/* 1000 */ V(0, 0, 1),
/* 1001 */ V(0, 0, 1),
/* 1010 */ V(0, 0, 1),
/* 1011 */ V(0, 0, 1),
/* 1100 */ V(0, 0, 1),
/* 1101 */ V(0, 0, 1),
/* 1110 */ V(0, 0, 1),
/* 1111 */ V(0, 0, 1),
/* 0000 ... */
/* 0000 */ PTR(52, 3), /* 16 */
/* 0001 */ PTR(60, 2),
/* 0010 */ PTR(64, 3),
/* 0011 */ PTR(72, 1),
/* 0100 */ PTR(74, 2),
/* 0101 */ PTR(78, 2),
/* 0110 */ PTR(82, 2),
/* 0111 */ V(1, 7, 4),
/* 1000 */ V(7, 1, 4),
/* 1001 */ PTR(86, 1),
/* 1010 */ PTR(88, 2),
/* 1011 */ PTR(92, 2),
/* 1100 */ V(1, 6, 4),
/* 1101 */ V(6, 1, 4),
/* 1110 */ V(6, 0, 4),
/* 1111 */ PTR(96, 1),
/* 0001 ... */
/* 0000 */ PTR(98, 1), /* 32 */
/* 0001 */ PTR(100, 1),
/* 0010 */ V(1, 4, 4),
/* 0011 */ V(4, 1, 4),
/* 0100 */ V(4, 0, 4),
/* 0101 */ V(2, 3, 4),
/* 0110 */ V(3, 2, 4),
/* 0111 */ V(0, 3, 4),
/* 1000 */ V(1, 3, 3),
/* 1001 */ V(1, 3, 3),
/* 1010 */ V(3, 1, 3),
/* 1011 */ V(3, 1, 3),
/* 1100 */ V(3, 0, 3),
/* 1101 */ V(3, 0, 3),
/* 1110 */ V(2, 2, 3),
/* 1111 */ V(2, 2, 3),
/* 0010 ... */
/* 00 */ V(1, 2, 2), /* 48 */
/* 01 */ V(2, 1, 2),
/* 10 */ V(0, 2, 2),
/* 11 */ V(2, 0, 2),
/* 0000 0000 ... */
/* 000 */ V(7, 7, 3), /* 52 */
/* 001 */ V(6, 7, 3),
/* 010 */ V(7, 6, 3),
/* 011 */ V(5, 7, 3),
/* 100 */ V(7, 5, 3),
/* 101 */ V(6, 6, 3),
/* 110 */ V(4, 7, 2),
/* 111 */ V(4, 7, 2),
/* 0000 0001 ... */
/* 00 */ V(7, 4, 2), /* 60 */
/* 01 */ V(5, 6, 2),
/* 10 */ V(6, 5, 2),
/* 11 */ V(3, 7, 2),
/* 0000 0010 ... */
/* 000 */ V(7, 3, 2), /* 64 */
/* 001 */ V(7, 3, 2),
/* 010 */ V(4, 6, 2),
/* 011 */ V(4, 6, 2),
/* 100 */ V(5, 5, 3),
/* 101 */ V(5, 4, 3),
/* 110 */ V(6, 3, 2),
/* 111 */ V(6, 3, 2),
/* 0000 0011 ... */
/* 0 */ V(2, 7, 1), /* 72 */
/* 1 */ V(7, 2, 1),
/* 0000 0100 ... */
/* 00 */ V(6, 4, 2), /* 74 */
/* 01 */ V(0, 7, 2),
/* 10 */ V(7, 0, 1),
/* 11 */ V(7, 0, 1),
/* 0000 0101 ... */
/* 00 */ V(6, 2, 1), /* 78 */
/* 01 */ V(6, 2, 1),
/* 10 */ V(4, 5, 2),
/* 11 */ V(3, 5, 2),
/* 0000 0110 ... */
/* 00 */ V(0, 6, 1), /* 82 */
/* 01 */ V(0, 6, 1),
/* 10 */ V(5, 3, 2),
/* 11 */ V(4, 4, 2),
/* 0000 1001 ... */
/* 0 */ V(3, 6, 1), /* 86 */
/* 1 */ V(2, 6, 1),
/* 0000 1010 ... */
/* 00 */ V(2, 5, 2), /* 88 */
/* 01 */ V(5, 2, 2),
/* 10 */ V(1, 5, 1),
/* 11 */ V(1, 5, 1),
/* 0000 1011 ... */
/* 00 */ V(5, 1, 1), /* 92 */
/* 01 */ V(5, 1, 1),
/* 10 */ V(3, 4, 2),
/* 11 */ V(4, 3, 2),
/* 0000 1111 ... */
/* 0 */ V(0, 5, 1), /* 96 */
/* 1 */ V(5, 0, 1),
/* 0001 0000 ... */
/* 0 */ V(2, 4, 1), /* 98 */
/* 1 */ V(4, 2, 1),
/* 0001 0001 ... */
/* 0 */ V(3, 3, 1), /* 100 */
/* 1 */ V(0, 4, 1)
};
static
union huffpair const hufftab11[] = {
/* 0000 */ PTR(16, 4),
/* 0001 */ PTR(32, 4),
/* 0010 */ PTR(48, 4),
/* 0011 */ PTR(64, 3),
/* 0100 */ V(1, 2, 4),
/* 0101 */ PTR(72, 1),
/* 0110 */ V(1, 1, 3),
/* 0111 */ V(1, 1, 3),
/* 1000 */ V(0, 1, 3),
/* 1001 */ V(0, 1, 3),
/* 1010 */ V(1, 0, 3),
/* 1011 */ V(1, 0, 3),
/* 1100 */ V(0, 0, 2),
/* 1101 */ V(0, 0, 2),
/* 1110 */ V(0, 0, 2),
/* 1111 */ V(0, 0, 2),
/* 0000 ... */
/* 0000 */ PTR(74, 2), /* 16 */
/* 0001 */ PTR(78, 3),
/* 0010 */ PTR(86, 2),
/* 0011 */ PTR(90, 1),
/* 0100 */ PTR(92, 2),
/* 0101 */ V(2, 7, 4),
/* 0110 */ V(7, 2, 4),
/* 0111 */ PTR(96, 1),
/* 1000 */ V(7, 1, 3),
/* 1001 */ V(7, 1, 3),
/* 1010 */ V(1, 7, 4),
/* 1011 */ V(7, 0, 4),
/* 1100 */ V(3, 6, 4),
/* 1101 */ V(6, 3, 4),
/* 1110 */ V(6, 0, 4),
/* 1111 */ PTR(98, 1),
/* 0001 ... */
/* 0000 */ PTR(100, 1), /* 32 */
/* 0001 */ V(1, 5, 4),
/* 0010 */ V(6, 2, 3),
/* 0011 */ V(6, 2, 3),
/* 0100 */ V(2, 6, 4),
/* 0101 */ V(0, 6, 4),
/* 0110 */ V(1, 6, 3),
/* 0111 */ V(1, 6, 3),
/* 1000 */ V(6, 1, 3),
/* 1001 */ V(6, 1, 3),
/* 1010 */ V(5, 1, 4),
/* 1011 */ V(3, 4, 4),
/* 1100 */ V(5, 0, 4),
/* 1101 */ PTR(102, 1),
/* 1110 */ V(2, 4, 4),
/* 1111 */ V(4, 2, 4),
/* 0010 ... */
/* 0000 */ V(1, 4, 4), /* 48 */
/* 0001 */ V(4, 1, 4),
/* 0010 */ V(0, 4, 4),
/* 0011 */ V(4, 0, 4),
/* 0100 */ V(2, 3, 3),
/* 0101 */ V(2, 3, 3),
/* 0110 */ V(3, 2, 3),
/* 0111 */ V(3, 2, 3),
/* 1000 */ V(1, 3, 2),
/* 1001 */ V(1, 3, 2),
/* 1010 */ V(1, 3, 2),
/* 1011 */ V(1, 3, 2),
/* 1100 */ V(3, 1, 2),
/* 1101 */ V(3, 1, 2),
/* 1110 */ V(3, 1, 2),
/* 1111 */ V(3, 1, 2),
/* 0011 ... */
/* 000 */ V(0, 3, 3), /* 64 */
/* 001 */ V(3, 0, 3),
/* 010 */ V(2, 2, 2),
/* 011 */ V(2, 2, 2),
/* 100 */ V(2, 1, 1),
/* 101 */ V(2, 1, 1),
/* 110 */ V(2, 1, 1),
/* 111 */ V(2, 1, 1),
/* 0101 ... */
/* 0 */ V(0, 2, 1), /* 72 */
/* 1 */ V(2, 0, 1),
/* 0000 0000 ... */
/* 00 */ V(7, 7, 2), /* 74 */
/* 01 */ V(6, 7, 2),
/* 10 */ V(7, 6, 2),
/* 11 */ V(7, 5, 2),
/* 0000 0001 ... */
/* 000 */ V(6, 6, 2), /* 78 */
/* 001 */ V(6, 6, 2),
/* 010 */ V(4, 7, 2),
/* 011 */ V(4, 7, 2),
/* 100 */ V(7, 4, 2),
/* 101 */ V(7, 4, 2),
/* 110 */ V(5, 7, 3),
/* 111 */ V(5, 5, 3),
/* 0000 0010 ... */
/* 00 */ V(5, 6, 2), /* 86 */
/* 01 */ V(6, 5, 2),
/* 10 */ V(3, 7, 1),
/* 11 */ V(3, 7, 1),
/* 0000 0011 ... */
/* 0 */ V(7, 3, 1), /* 90 */
/* 1 */ V(4, 6, 1),
/* 0000 0100 ... */
/* 00 */ V(4, 5, 2), /* 92 */
/* 01 */ V(5, 4, 2),
/* 10 */ V(3, 5, 2),
/* 11 */ V(5, 3, 2),
/* 0000 0111 ... */
/* 0 */ V(6, 4, 1), /* 96 */
/* 1 */ V(0, 7, 1),
/* 0000 1111 ... */
/* 0 */ V(4, 4, 1), /* 98 */
/* 1 */ V(2, 5, 1),
/* 0001 0000 ... */
/* 0 */ V(5, 2, 1), /* 100 */
/* 1 */ V(0, 5, 1),
/* 0001 1101 ... */
/* 0 */ V(4, 3, 1), /* 102 */
/* 1 */ V(3, 3, 1)
};
static
union huffpair const hufftab12[] = {
/* 0000 */ PTR(16, 4),
/* 0001 */ PTR(32, 4),
/* 0010 */ PTR(48, 4),
/* 0011 */ PTR(64, 2),
/* 0100 */ PTR(68, 3),
/* 0101 */ PTR(76, 1),
/* 0110 */ V(1, 2, 4),
/* 0111 */ V(2, 1, 4),
/* 1000 */ PTR(78, 1),
/* 1001 */ V(0, 0, 4),
/* 1010 */ V(1, 1, 3),
/* 1011 */ V(1, 1, 3),
/* 1100 */ V(0, 1, 3),
/* 1101 */ V(0, 1, 3),
/* 1110 */ V(1, 0, 3),
/* 1111 */ V(1, 0, 3),
/* 0000 ... */
/* 0000 */ PTR(80, 2), /* 16 */
/* 0001 */ PTR(84, 1),
/* 0010 */ PTR(86, 1),
/* 0011 */ PTR(88, 1),
/* 0100 */ V(5, 6, 4),
/* 0101 */ V(3, 7, 4),
/* 0110 */ PTR(90, 1),
/* 0111 */ V(2, 7, 4),
/* 1000 */ V(7, 2, 4),
/* 1001 */ V(4, 6, 4),
/* 1010 */ V(6, 4, 4),
/* 1011 */ V(1, 7, 4),
/* 1100 */ V(7, 1, 4),
/* 1101 */ PTR(92, 1),
/* 1110 */ V(3, 6, 4),
/* 1111 */ V(6, 3, 4),
/* 0001 ... */
/* 0000 */ V(4, 5, 4), /* 32 */
/* 0001 */ V(5, 4, 4),
/* 0010 */ V(4, 4, 4),
/* 0011 */ PTR(94, 1),
/* 0100 */ V(2, 6, 3),
/* 0101 */ V(2, 6, 3),
/* 0110 */ V(6, 2, 3),
/* 0111 */ V(6, 2, 3),
/* 1000 */ V(6, 1, 3),
/* 1001 */ V(6, 1, 3),
/* 1010 */ V(1, 6, 4),
/* 1011 */ V(6, 0, 4),
/* 1100 */ V(3, 5, 4),
/* 1101 */ V(5, 3, 4),
/* 1110 */ V(2, 5, 4),
/* 1111 */ V(5, 2, 4),
/* 0010 ... */
/* 0000 */ V(1, 5, 3), /* 48 */
/* 0001 */ V(1, 5, 3),
/* 0010 */ V(5, 1, 3),
/* 0011 */ V(5, 1, 3),
/* 0100 */ V(3, 4, 3),
/* 0101 */ V(3, 4, 3),
/* 0110 */ V(4, 3, 3),
/* 0111 */ V(4, 3, 3),
/* 1000 */ V(5, 0, 4),
/* 1001 */ V(0, 4, 4),
/* 1010 */ V(2, 4, 3),
/* 1011 */ V(2, 4, 3),
/* 1100 */ V(4, 2, 3),
/* 1101 */ V(4, 2, 3),
/* 1110 */ V(1, 4, 3),
/* 1111 */ V(1, 4, 3),
/* 0011 ... */
/* 00 */ V(3, 3, 2), /* 64 */
/* 01 */ V(4, 1, 2),
/* 10 */ V(2, 3, 2),
/* 11 */ V(3, 2, 2),
/* 0100 ... */
/* 000 */ V(4, 0, 3), /* 68 */
/* 001 */ V(0, 3, 3),
/* 010 */ V(3, 0, 2),
/* 011 */ V(3, 0, 2),
/* 100 */ V(1, 3, 1),
/* 101 */ V(1, 3, 1),
/* 110 */ V(1, 3, 1),
/* 111 */ V(1, 3, 1),
/* 0101 ... */
/* 0 */ V(3, 1, 1), /* 76 */
/* 1 */ V(2, 2, 1),
/* 1000 ... */
/* 0 */ V(0, 2, 1), /* 78 */
/* 1 */ V(2, 0, 1),
/* 0000 0000 ... */
/* 00 */ V(7, 7, 2), /* 80 */
/* 01 */ V(6, 7, 2),
/* 10 */ V(7, 6, 1),
/* 11 */ V(7, 6, 1),
/* 0000 0001 ... */
/* 0 */ V(5, 7, 1), /* 84 */
/* 1 */ V(7, 5, 1),
/* 0000 0010 ... */
/* 0 */ V(6, 6, 1), /* 86 */
/* 1 */ V(4, 7, 1),
/* 0000 0011 ... */
/* 0 */ V(7, 4, 1), /* 88 */
/* 1 */ V(6, 5, 1),
/* 0000 0110 ... */
/* 0 */ V(7, 3, 1), /* 90 */
/* 1 */ V(5, 5, 1),
/* 0000 1101 ... */
/* 0 */ V(0, 7, 1), /* 92 */
/* 1 */ V(7, 0, 1),
/* 0001 0011 ... */
/* 0 */ V(0, 6, 1), /* 94 */
/* 1 */ V(0, 5, 1)
};
static
union huffpair const hufftab13[] = {
/* 0000 */ PTR(16, 4),
/* 0001 */ PTR(32, 4),
/* 0010 */ PTR(48, 4),
/* 0011 */ PTR(64, 2),
/* 0100 */ V(1, 1, 4),
/* 0101 */ V(0, 1, 4),
/* 0110 */ V(1, 0, 3),
/* 0111 */ V(1, 0, 3),
/* 1000 */ V(0, 0, 1),
/* 1001 */ V(0, 0, 1),
/* 1010 */ V(0, 0, 1),
/* 1011 */ V(0, 0, 1),
/* 1100 */ V(0, 0, 1),
/* 1101 */ V(0, 0, 1),
/* 1110 */ V(0, 0, 1),
/* 1111 */ V(0, 0, 1),
/* 0000 ... */
/* 0000 */ PTR(68, 4), /* 16 */
/* 0001 */ PTR(84, 4),
/* 0010 */ PTR(100, 4),
/* 0011 */ PTR(116, 4),
/* 0100 */ PTR(132, 4),
/* 0101 */ PTR(148, 4),
/* 0110 */ PTR(164, 3),
/* 0111 */ PTR(172, 3),
/* 1000 */ PTR(180, 3),
/* 1001 */ PTR(188, 3),
/* 1010 */ PTR(196, 3),
/* 1011 */ PTR(204, 3),
/* 1100 */ PTR(212, 1),
/* 1101 */ PTR(214, 2),
/* 1110 */ PTR(218, 3),
/* 1111 */ PTR(226, 1),
/* 0001 ... */
/* 0000 */ PTR(228, 2), /* 32 */
/* 0001 */ PTR(232, 2),
/* 0010 */ PTR(236, 2),
/* 0011 */ PTR(240, 2),
/* 0100 */ V(8, 1, 4),
/* 0101 */ PTR(244, 1),
/* 0110 */ PTR(246, 1),
/* 0111 */ PTR(248, 1),
/* 1000 */ PTR(250, 2),
/* 1001 */ PTR(254, 1),
/* 1010 */ V(1, 5, 4),
/* 1011 */ V(5, 1, 4),
/* 1100 */ PTR(256, 1),
/* 1101 */ PTR(258, 1),
/* 1110 */ PTR(260, 1),
/* 1111 */ V(1, 4, 4),
/* 0010 ... */
/* 0000 */ V(4, 1, 3), /* 48 */
/* 0001 */ V(4, 1, 3),
/* 0010 */ V(0, 4, 4),
/* 0011 */ V(4, 0, 4),
/* 0100 */ V(2, 3, 4),
/* 0101 */ V(3, 2, 4),
/* 0110 */ V(1, 3, 3),
/* 0111 */ V(1, 3, 3),
/* 1000 */ V(3, 1, 3),
/* 1001 */ V(3, 1, 3),
/* 1010 */ V(0, 3, 3),
/* 1011 */ V(0, 3, 3),
/* 1100 */ V(3, 0, 3),
/* 1101 */ V(3, 0, 3),
/* 1110 */ V(2, 2, 3),
/* 1111 */ V(2, 2, 3),
/* 0011 ... */
/* 00 */ V(1, 2, 2), /* 64 */
/* 01 */ V(2, 1, 2),
/* 10 */ V(0, 2, 2),
/* 11 */ V(2, 0, 2),
/* 0000 0000 ... */
/* 0000 */ PTR(262, 4), /* 68 */
/* 0001 */ PTR(278, 4),
/* 0010 */ PTR(294, 4),
/* 0011 */ PTR(310, 3),
/* 0100 */ PTR(318, 2),
/* 0101 */ PTR(322, 2),
/* 0110 */ PTR(326, 3),
/* 0111 */ PTR(334, 2),
/* 1000 */ PTR(338, 1),
/* 1001 */ PTR(340, 2),
/* 1010 */ PTR(344, 2),
/* 1011 */ PTR(348, 2),
/* 1100 */ PTR(352, 2),
/* 1101 */ PTR(356, 2),
/* 1110 */ V(1, 15, 4),
/* 1111 */ V(15, 1, 4),
/* 0000 0001 ... */
/* 0000 */ V(15, 0, 4), /* 84 */
/* 0001 */ PTR(360, 1),
/* 0010 */ PTR(362, 1),
/* 0011 */ PTR(364, 1),
/* 0100 */ V(14, 2, 4),
/* 0101 */ PTR(366, 1),
/* 0110 */ V(1, 14, 4),
/* 0111 */ V(14, 1, 4),
/* 1000 */ PTR(368, 1),
/* 1001 */ PTR(370, 1),
/* 1010 */ PTR(372, 1),
/* 1011 */ PTR(374, 1),
/* 1100 */ PTR(376, 1),
/* 1101 */ PTR(378, 1),
/* 1110 */ V(12, 6, 4),
/* 1111 */ V(3, 13, 4),
/* 0000 0010 ... */
/* 0000 */ PTR(380, 1), /* 100 */
/* 0001 */ V(2, 13, 4),
/* 0010 */ V(13, 2, 4),
/* 0011 */ V(1, 13, 4),
/* 0100 */ V(11, 7, 4),
/* 0101 */ PTR(382, 1),
/* 0110 */ PTR(384, 1),
/* 0111 */ V(12, 3, 4),
/* 1000 */ PTR(386, 1),
/* 1001 */ V(4, 11, 4),
/* 1010 */ V(13, 1, 3),
/* 1011 */ V(13, 1, 3),
/* 1100 */ V(0, 13, 4),
/* 1101 */ V(13, 0, 4),
/* 1110 */ V(8, 10, 4),
/* 1111 */ V(10, 8, 4),
/* 0000 0011 ... */
/* 0000 */ V(4, 12, 4), /* 116 */
/* 0001 */ V(12, 4, 4),
/* 0010 */ V(6, 11, 4),
/* 0011 */ V(11, 6, 4),
/* 0100 */ V(3, 12, 3),
/* 0101 */ V(3, 12, 3),
/* 0110 */ V(2, 12, 3),
/* 0111 */ V(2, 12, 3),
/* 1000 */ V(12, 2, 3),
/* 1001 */ V(12, 2, 3),
/* 1010 */ V(5, 11, 3),
/* 1011 */ V(5, 11, 3),
/* 1100 */ V(11, 5, 4),
/* 1101 */ V(8, 9, 4),
/* 1110 */ V(1, 12, 3),
/* 1111 */ V(1, 12, 3),
/* 0000 0100 ... */
/* 0000 */ V(12, 1, 3), /* 132 */
/* 0001 */ V(12, 1, 3),
/* 0010 */ V(9, 8, 4),
/* 0011 */ V(0, 12, 4),
/* 0100 */ V(12, 0, 3),
/* 0101 */ V(12, 0, 3),
/* 0110 */ V(11, 4, 4),
/* 0111 */ V(6, 10, 4),
/* 1000 */ V(10, 6, 4),
/* 1001 */ V(7, 9, 4),
/* 1010 */ V(3, 11, 3),
/* 1011 */ V(3, 11, 3),
/* 1100 */ V(11, 3, 3),
/* 1101 */ V(11, 3, 3),
/* 1110 */ V(8, 8, 4),
/* 1111 */ V(5, 10, 4),
/* 0000 0101 ... */
/* 0000 */ V(2, 11, 3), /* 148 */
/* 0001 */ V(2, 11, 3),
/* 0010 */ V(10, 5, 4),
/* 0011 */ V(6, 9, 4),
/* 0100 */ V(10, 4, 3),
/* 0101 */ V(10, 4, 3),
/* 0110 */ V(7, 8, 4),
/* 0111 */ V(8, 7, 4),
/* 1000 */ V(9, 4, 3),
/* 1001 */ V(9, 4, 3),
/* 1010 */ V(7, 7, 4),
/* 1011 */ V(7, 6, 4),
/* 1100 */ V(11, 2, 2),
/* 1101 */ V(11, 2, 2),
/* 1110 */ V(11, 2, 2),
/* 1111 */ V(11, 2, 2),
/* 0000 0110 ... */
/* 000 */ V(1, 11, 2), /* 164 */
/* 001 */ V(1, 11, 2),
/* 010 */ V(11, 1, 2),
/* 011 */ V(11, 1, 2),
/* 100 */ V(0, 11, 3),
/* 101 */ V(11, 0, 3),
/* 110 */ V(9, 6, 3),
/* 111 */ V(4, 10, 3),
/* 0000 0111 ... */
/* 000 */ V(3, 10, 3), /* 172 */
/* 001 */ V(10, 3, 3),
/* 010 */ V(5, 9, 3),
/* 011 */ V(9, 5, 3),
/* 100 */ V(2, 10, 2),
/* 101 */ V(2, 10, 2),
/* 110 */ V(10, 2, 2),
/* 111 */ V(10, 2, 2),
/* 0000 1000 ... */
/* 000 */ V(1, 10, 2), /* 180 */
/* 001 */ V(1, 10, 2),
/* 010 */ V(10, 1, 2),
/* 011 */ V(10, 1, 2),
/* 100 */ V(0, 10, 3),
/* 101 */ V(6, 8, 3),
/* 110 */ V(10, 0, 2),
/* 111 */ V(10, 0, 2),
/* 0000 1001 ... */
/* 000 */ V(8, 6, 3), /* 188 */
/* 001 */ V(4, 9, 3),
/* 010 */ V(9, 3, 2),
/* 011 */ V(9, 3, 2),
/* 100 */ V(3, 9, 3),
/* 101 */ V(5, 8, 3),
/* 110 */ V(8, 5, 3),
/* 111 */ V(6, 7, 3),
/* 0000 1010 ... */
/* 000 */ V(2, 9, 2), /* 196 */
/* 001 */ V(2, 9, 2),
/* 010 */ V(9, 2, 2),
/* 011 */ V(9, 2, 2),
/* 100 */ V(5, 7, 3),
/* 101 */ V(7, 5, 3),
/* 110 */ V(3, 8, 2),
/* 111 */ V(3, 8, 2),
/* 0000 1011 ... */
/* 000 */ V(8, 3, 2), /* 204 */
/* 001 */ V(8, 3, 2),
/* 010 */ V(6, 6, 3),
/* 011 */ V(4, 7, 3),
/* 100 */ V(7, 4, 3),
/* 101 */ V(5, 6, 3),
/* 110 */ V(6, 5, 3),
/* 111 */ V(7, 3, 3),
/* 0000 1100 ... */
/* 0 */ V(1, 9, 1), /* 212 */
/* 1 */ V(9, 1, 1),
/* 0000 1101 ... */
/* 00 */ V(0, 9, 2), /* 214 */
/* 01 */ V(9, 0, 2),
/* 10 */ V(4, 8, 2),
/* 11 */ V(8, 4, 2),
/* 0000 1110 ... */
/* 000 */ V(7, 2, 2), /* 218 */
/* 001 */ V(7, 2, 2),
/* 010 */ V(4, 6, 3),
/* 011 */ V(6, 4, 3),
/* 100 */ V(2, 8, 1),
/* 101 */ V(2, 8, 1),
/* 110 */ V(2, 8, 1),
/* 111 */ V(2, 8, 1),
/* 0000 1111 ... */
/* 0 */ V(8, 2, 1), /* 226 */
/* 1 */ V(1, 8, 1),
/* 0001 0000 ... */
/* 00 */ V(3, 7, 2), /* 228 */
/* 01 */ V(2, 7, 2),
/* 10 */ V(1, 7, 1),
/* 11 */ V(1, 7, 1),
/* 0001 0001 ... */
/* 00 */ V(7, 1, 1), /* 232 */
/* 01 */ V(7, 1, 1),
/* 10 */ V(5, 5, 2),
/* 11 */ V(0, 7, 2),
/* 0001 0010 ... */
/* 00 */ V(7, 0, 2), /* 236 */
/* 01 */ V(3, 6, 2),
/* 10 */ V(6, 3, 2),
/* 11 */ V(4, 5, 2),
/* 0001 0011 ... */
/* 00 */ V(5, 4, 2), /* 240 */
/* 01 */ V(2, 6, 2),
/* 10 */ V(6, 2, 2),
/* 11 */ V(3, 5, 2),
/* 0001 0101 ... */
/* 0 */ V(0, 8, 1), /* 244 */
/* 1 */ V(8, 0, 1),
/* 0001 0110 ... */
/* 0 */ V(1, 6, 1), /* 246 */
/* 1 */ V(6, 1, 1),
/* 0001 0111 ... */
/* 0 */ V(0, 6, 1), /* 248 */
/* 1 */ V(6, 0, 1),
/* 0001 1000 ... */
/* 00 */ V(5, 3, 2), /* 250 */
/* 01 */ V(4, 4, 2),
/* 10 */ V(2, 5, 1),
/* 11 */ V(2, 5, 1),
/* 0001 1001 ... */
/* 0 */ V(5, 2, 1), /* 254 */
/* 1 */ V(0, 5, 1),
/* 0001 1100 ... */
/* 0 */ V(3, 4, 1), /* 256 */
/* 1 */ V(4, 3, 1),
/* 0001 1101 ... */
/* 0 */ V(5, 0, 1), /* 258 */
/* 1 */ V(2, 4, 1),
/* 0001 1110 ... */
/* 0 */ V(4, 2, 1), /* 260 */
/* 1 */ V(3, 3, 1),
/* 0000 0000 0000 ... */
/* 0000 */ PTR(388, 3), /* 262 */
/* 0001 */ V(15, 15, 4),
/* 0010 */ V(14, 15, 4),
/* 0011 */ V(13, 15, 4),
/* 0100 */ V(14, 14, 4),
/* 0101 */ V(12, 15, 4),
/* 0110 */ V(13, 14, 4),
/* 0111 */ V(11, 15, 4),
/* 1000 */ V(15, 11, 4),
/* 1001 */ V(12, 14, 4),
/* 1010 */ V(13, 12, 4),
/* 1011 */ PTR(396, 1),
/* 1100 */ V(14, 12, 3),
/* 1101 */ V(14, 12, 3),
/* 1110 */ V(13, 13, 3),
/* 1111 */ V(13, 13, 3),
/* 0000 0000 0001 ... */
/* 0000 */ V(15, 10, 4), /* 278 */
/* 0001 */ V(12, 13, 4),
/* 0010 */ V(11, 14, 3),
/* 0011 */ V(11, 14, 3),
/* 0100 */ V(14, 11, 3),
/* 0101 */ V(14, 11, 3),
/* 0110 */ V(9, 15, 3),
/* 0111 */ V(9, 15, 3),
/* 1000 */ V(15, 9, 3),
/* 1001 */ V(15, 9, 3),
/* 1010 */ V(14, 10, 3),
/* 1011 */ V(14, 10, 3),
/* 1100 */ V(11, 13, 3),
/* 1101 */ V(11, 13, 3),
/* 1110 */ V(13, 11, 3),
/* 1111 */ V(13, 11, 3),
/* 0000 0000 0010 ... */
/* 0000 */ V(8, 15, 3), /* 294 */
/* 0001 */ V(8, 15, 3),
/* 0010 */ V(15, 8, 3),
/* 0011 */ V(15, 8, 3),
/* 0100 */ V(12, 12, 3),
/* 0101 */ V(12, 12, 3),
/* 0110 */ V(10, 14, 4),
/* 0111 */ V(9, 14, 4),
/* 1000 */ V(8, 14, 3),
/* 1001 */ V(8, 14, 3),
/* 1010 */ V(7, 15, 4),
/* 1011 */ V(7, 14, 4),
/* 1100 */ V(15, 7, 2),
/* 1101 */ V(15, 7, 2),
/* 1110 */ V(15, 7, 2),
/* 1111 */ V(15, 7, 2),
/* 0000 0000 0011 ... */
/* 000 */ V(13, 10, 2), /* 310 */
/* 001 */ V(13, 10, 2),
/* 010 */ V(10, 13, 3),
/* 011 */ V(11, 12, 3),
/* 100 */ V(12, 11, 3),
/* 101 */ V(15, 6, 3),
/* 110 */ V(6, 15, 2),
/* 111 */ V(6, 15, 2),
/* 0000 0000 0100 ... */
/* 00 */ V(14, 8, 2), /* 318 */
/* 01 */ V(5, 15, 2),
/* 10 */ V(9, 13, 2),
/* 11 */ V(13, 9, 2),
/* 0000 0000 0101 ... */
/* 00 */ V(15, 5, 2), /* 322 */
/* 01 */ V(14, 7, 2),
/* 10 */ V(10, 12, 2),
/* 11 */ V(11, 11, 2),
/* 0000 0000 0110 ... */
/* 000 */ V(4, 15, 2), /* 326 */
/* 001 */ V(4, 15, 2),
/* 010 */ V(15, 4, 2),
/* 011 */ V(15, 4, 2),
/* 100 */ V(12, 10, 3),
/* 101 */ V(14, 6, 3),
/* 110 */ V(15, 3, 2),
/* 111 */ V(15, 3, 2),
/* 0000 0000 0111 ... */
/* 00 */ V(3, 15, 1), /* 334 */
/* 01 */ V(3, 15, 1),
/* 10 */ V(8, 13, 2),
/* 11 */ V(13, 8, 2),
/* 0000 0000 1000 ... */
/* 0 */ V(2, 15, 1), /* 338 */
/* 1 */ V(15, 2, 1),
/* 0000 0000 1001 ... */
/* 00 */ V(6, 14, 2), /* 340 */
/* 01 */ V(9, 12, 2),
/* 10 */ V(0, 15, 1),
/* 11 */ V(0, 15, 1),
/* 0000 0000 1010 ... */
/* 00 */ V(12, 9, 2), /* 344 */
/* 01 */ V(5, 14, 2),
/* 10 */ V(10, 11, 1),
/* 11 */ V(10, 11, 1),
/* 0000 0000 1011 ... */
/* 00 */ V(7, 13, 2), /* 348 */
/* 01 */ V(13, 7, 2),
/* 10 */ V(4, 14, 1),
/* 11 */ V(4, 14, 1),
/* 0000 0000 1100 ... */
/* 00 */ V(12, 8, 2), /* 352 */
/* 01 */ V(13, 6, 2),
/* 10 */ V(3, 14, 1),
/* 11 */ V(3, 14, 1),
/* 0000 0000 1101 ... */
/* 00 */ V(11, 9, 1), /* 356 */
/* 01 */ V(11, 9, 1),
/* 10 */ V(9, 11, 2),
/* 11 */ V(10, 10, 2),
/* 0000 0001 0001 ... */
/* 0 */ V(11, 10, 1), /* 360 */
/* 1 */ V(14, 5, 1),
/* 0000 0001 0010 ... */
/* 0 */ V(14, 4, 1), /* 362 */
/* 1 */ V(8, 12, 1),
/* 0000 0001 0011 ... */
/* 0 */ V(6, 13, 1), /* 364 */
/* 1 */ V(14, 3, 1),
/* 0000 0001 0101 ... */
/* 0 */ V(2, 14, 1), /* 366 */
/* 1 */ V(0, 14, 1),
/* 0000 0001 1000 ... */
/* 0 */ V(14, 0, 1), /* 368 */
/* 1 */ V(5, 13, 1),
/* 0000 0001 1001 ... */
/* 0 */ V(13, 5, 1), /* 370 */
/* 1 */ V(7, 12, 1),
/* 0000 0001 1010 ... */
/* 0 */ V(12, 7, 1), /* 372 */
/* 1 */ V(4, 13, 1),
/* 0000 0001 1011 ... */
/* 0 */ V(8, 11, 1), /* 374 */
/* 1 */ V(11, 8, 1),
/* 0000 0001 1100 ... */
/* 0 */ V(13, 4, 1), /* 376 */
/* 1 */ V(9, 10, 1),
/* 0000 0001 1101 ... */
/* 0 */ V(10, 9, 1), /* 378 */
/* 1 */ V(6, 12, 1),
/* 0000 0010 0000 ... */
/* 0 */ V(13, 3, 1), /* 380 */
/* 1 */ V(7, 11, 1),
/* 0000 0010 0101 ... */
/* 0 */ V(5, 12, 1), /* 382 */
/* 1 */ V(12, 5, 1),
/* 0000 0010 0110 ... */
/* 0 */ V(9, 9, 1), /* 384 */
/* 1 */ V(7, 10, 1),
/* 0000 0010 1000 ... */
/* 0 */ V(10, 7, 1), /* 386 */
/* 1 */ V(9, 7, 1),
/* 0000 0000 0000 0000 ... */
/* 000 */ V(15, 14, 3), /* 388 */
/* 001 */ V(15, 12, 3),
/* 010 */ V(15, 13, 2),
/* 011 */ V(15, 13, 2),
/* 100 */ V(14, 13, 1),
/* 101 */ V(14, 13, 1),
/* 110 */ V(14, 13, 1),
/* 111 */ V(14, 13, 1),
/* 0000 0000 0000 1011 ... */
/* 0 */ V(10, 15, 1), /* 396 */
/* 1 */ V(14, 9, 1)
};
static
union huffpair const hufftab15[] = {
/* 0000 */ PTR(16, 4),
/* 0001 */ PTR(32, 4),
/* 0010 */ PTR(48, 4),
/* 0011 */ PTR(64, 4),
/* 0100 */ PTR(80, 4),
/* 0101 */ PTR(96, 3),
/* 0110 */ PTR(104, 3),
/* 0111 */ PTR(112, 2),
/* 1000 */ PTR(116, 1),
/* 1001 */ PTR(118, 1),
/* 1010 */ V(1, 1, 3),
/* 1011 */ V(1, 1, 3),
/* 1100 */ V(0, 1, 4),
/* 1101 */ V(1, 0, 4),
/* 1110 */ V(0, 0, 3),
/* 1111 */ V(0, 0, 3),
/* 0000 ... */
/* 0000 */ PTR(120, 4), /* 16 */
/* 0001 */ PTR(136, 4),
/* 0010 */ PTR(152, 4),
/* 0011 */ PTR(168, 4),
/* 0100 */ PTR(184, 4),
/* 0101 */ PTR(200, 3),
/* 0110 */ PTR(208, 3),
/* 0111 */ PTR(216, 4),
/* 1000 */ PTR(232, 3),
/* 1001 */ PTR(240, 3),
/* 1010 */ PTR(248, 3),
/* 1011 */ PTR(256, 3),
/* 1100 */ PTR(264, 2),
/* 1101 */ PTR(268, 3),
/* 1110 */ PTR(276, 3),
/* 1111 */ PTR(284, 2),
/* 0001 ... */
/* 0000 */ PTR(288, 2), /* 32 */
/* 0001 */ PTR(292, 2),
/* 0010 */ PTR(296, 2),
/* 0011 */ PTR(300, 2),
/* 0100 */ PTR(304, 2),
/* 0101 */ PTR(308, 2),
/* 0110 */ PTR(312, 2),
/* 0111 */ PTR(316, 2),
/* 1000 */ PTR(320, 1),
/* 1001 */ PTR(322, 1),
/* 1010 */ PTR(324, 1),
/* 1011 */ PTR(326, 2),
/* 1100 */ PTR(330, 1),
/* 1101 */ PTR(332, 1),
/* 1110 */ PTR(334, 2),
/* 1111 */ PTR(338, 1),
/* 0010 ... */
/* 0000 */ PTR(340, 1), /* 48 */
/* 0001 */ PTR(342, 1),
/* 0010 */ V(9, 1, 4),
/* 0011 */ PTR(344, 1),
/* 0100 */ PTR(346, 1),
/* 0101 */ PTR(348, 1),
/* 0110 */ PTR(350, 1),
/* 0111 */ PTR(352, 1),
/* 1000 */ V(2, 8, 4),
/* 1001 */ V(8, 2, 4),
/* 1010 */ V(1, 8, 4),
/* 1011 */ V(8, 1, 4),
/* 1100 */ PTR(354, 1),
/* 1101 */ PTR(356, 1),
/* 1110 */ PTR(358, 1),
/* 1111 */ PTR(360, 1),
/* 0011 ... */
/* 0000 */ V(2, 7, 4), /* 64 */
/* 0001 */ V(7, 2, 4),
/* 0010 */ V(6, 4, 4),
/* 0011 */ V(1, 7, 4),
/* 0100 */ V(5, 5, 4),
/* 0101 */ V(7, 1, 4),
/* 0110 */ PTR(362, 1),
/* 0111 */ V(3, 6, 4),
/* 1000 */ V(6, 3, 4),
/* 1001 */ V(4, 5, 4),
/* 1010 */ V(5, 4, 4),
/* 1011 */ V(2, 6, 4),
/* 1100 */ V(6, 2, 4),
/* 1101 */ V(1, 6, 4),
/* 1110 */ PTR(364, 1),
/* 1111 */ V(3, 5, 4),
/* 0100 ... */
/* 0000 */ V(6, 1, 3), /* 80 */
/* 0001 */ V(6, 1, 3),
/* 0010 */ V(5, 3, 4),
/* 0011 */ V(4, 4, 4),
/* 0100 */ V(2, 5, 3),
/* 0101 */ V(2, 5, 3),
/* 0110 */ V(5, 2, 3),
/* 0111 */ V(5, 2, 3),
/* 1000 */ V(1, 5, 3),
/* 1001 */ V(1, 5, 3),
/* 1010 */ V(5, 1, 3),
/* 1011 */ V(5, 1, 3),
/* 1100 */ V(0, 5, 4),
/* 1101 */ V(5, 0, 4),
/* 1110 */ V(3, 4, 3),
/* 1111 */ V(3, 4, 3),
/* 0101 ... */
/* 000 */ V(4, 3, 3), /* 96 */
/* 001 */ V(2, 4, 3),
/* 010 */ V(4, 2, 3),
/* 011 */ V(3, 3, 3),
/* 100 */ V(4, 1, 2),
/* 101 */ V(4, 1, 2),
/* 110 */ V(1, 4, 3),
/* 111 */ V(0, 4, 3),
/* 0110 ... */
/* 000 */ V(2, 3, 2), /* 104 */
/* 001 */ V(2, 3, 2),
/* 010 */ V(3, 2, 2),
/* 011 */ V(3, 2, 2),
/* 100 */ V(4, 0, 3),
/* 101 */ V(0, 3, 3),
/* 110 */ V(1, 3, 2),
/* 111 */ V(1, 3, 2),
/* 0111 ... */
/* 00 */ V(3, 1, 2), /* 112 */
/* 01 */ V(3, 0, 2),
/* 10 */ V(2, 2, 1),
/* 11 */ V(2, 2, 1),
/* 1000 ... */
/* 0 */ V(1, 2, 1), /* 116 */
/* 1 */ V(2, 1, 1),
/* 1001 ... */
/* 0 */ V(0, 2, 1), /* 118 */
/* 1 */ V(2, 0, 1),
/* 0000 0000 ... */
/* 0000 */ PTR(366, 1), /* 120 */
/* 0001 */ PTR(368, 1),
/* 0010 */ V(14, 14, 4),
/* 0011 */ PTR(370, 1),
/* 0100 */ PTR(372, 1),
/* 0101 */ PTR(374, 1),
/* 0110 */ V(15, 11, 4),
/* 0111 */ PTR(376, 1),
/* 1000 */ V(13, 13, 4),
/* 1001 */ V(10, 15, 4),
/* 1010 */ V(15, 10, 4),
/* 1011 */ V(11, 14, 4),
/* 1100 */ V(14, 11, 4),
/* 1101 */ V(12, 13, 4),
/* 1110 */ V(13, 12, 4),
/* 1111 */ V(9, 15, 4),
/* 0000 0001 ... */
/* 0000 */ V(15, 9, 4), /* 136 */
/* 0001 */ V(14, 10, 4),
/* 0010 */ V(11, 13, 4),
/* 0011 */ V(13, 11, 4),
/* 0100 */ V(8, 15, 4),
/* 0101 */ V(15, 8, 4),
/* 0110 */ V(12, 12, 4),
/* 0111 */ V(9, 14, 4),
/* 1000 */ V(14, 9, 4),
/* 1001 */ V(7, 15, 4),
/* 1010 */ V(15, 7, 4),
/* 1011 */ V(10, 13, 4),
/* 1100 */ V(13, 10, 4),
/* 1101 */ V(11, 12, 4),
/* 1110 */ V(6, 15, 4),
/* 1111 */ PTR(378, 1),
/* 0000 0010 ... */
/* 0000 */ V(12, 11, 3), /* 152 */
/* 0001 */ V(12, 11, 3),
/* 0010 */ V(15, 6, 3),
/* 0011 */ V(15, 6, 3),
/* 0100 */ V(8, 14, 4),
/* 0101 */ V(14, 8, 4),
/* 0110 */ V(5, 15, 4),
/* 0111 */ V(9, 13, 4),
/* 1000 */ V(15, 5, 3),
/* 1001 */ V(15, 5, 3),
/* 1010 */ V(7, 14, 3),
/* 1011 */ V(7, 14, 3),
/* 1100 */ V(14, 7, 3),
/* 1101 */ V(14, 7, 3),
/* 1110 */ V(10, 12, 3),
/* 1111 */ V(10, 12, 3),
/* 0000 0011 ... */
/* 0000 */ V(12, 10, 3), /* 168 */
/* 0001 */ V(12, 10, 3),
/* 0010 */ V(11, 11, 3),
/* 0011 */ V(11, 11, 3),
/* 0100 */ V(13, 9, 4),
/* 0101 */ V(8, 13, 4),
/* 0110 */ V(4, 15, 3),
/* 0111 */ V(4, 15, 3),
/* 1000 */ V(15, 4, 3),
/* 1001 */ V(15, 4, 3),
/* 1010 */ V(3, 15, 3),
/* 1011 */ V(3, 15, 3),
/* 1100 */ V(15, 3, 3),
/* 1101 */ V(15, 3, 3),
/* 1110 */ V(13, 8, 3),
/* 1111 */ V(13, 8, 3),
/* 0000 0100 ... */
/* 0000 */ V(14, 6, 3), /* 184 */
/* 0001 */ V(14, 6, 3),
/* 0010 */ V(2, 15, 3),
/* 0011 */ V(2, 15, 3),
/* 0100 */ V(15, 2, 3),
/* 0101 */ V(15, 2, 3),
/* 0110 */ V(6, 14, 4),
/* 0111 */ V(15, 0, 4),
/* 1000 */ V(1, 15, 3),
/* 1001 */ V(1, 15, 3),
/* 1010 */ V(15, 1, 3),
/* 1011 */ V(15, 1, 3),
/* 1100 */ V(9, 12, 3),
/* 1101 */ V(9, 12, 3),
/* 1110 */ V(12, 9, 3),
/* 1111 */ V(12, 9, 3),
/* 0000 0101 ... */
/* 000 */ V(5, 14, 3), /* 200 */
/* 001 */ V(10, 11, 3),
/* 010 */ V(11, 10, 3),
/* 011 */ V(14, 5, 3),
/* 100 */ V(7, 13, 3),
/* 101 */ V(13, 7, 3),
/* 110 */ V(4, 14, 3),
/* 111 */ V(14, 4, 3),
/* 0000 0110 ... */
/* 000 */ V(8, 12, 3), /* 208 */
/* 001 */ V(12, 8, 3),
/* 010 */ V(3, 14, 3),
/* 011 */ V(6, 13, 3),
/* 100 */ V(13, 6, 3),
/* 101 */ V(14, 3, 3),
/* 110 */ V(9, 11, 3),
/* 111 */ V(11, 9, 3),
/* 0000 0111 ... */
/* 0000 */ V(2, 14, 3), /* 216 */
/* 0001 */ V(2, 14, 3),
/* 0010 */ V(10, 10, 3),
/* 0011 */ V(10, 10, 3),
/* 0100 */ V(14, 2, 3),
/* 0101 */ V(14, 2, 3),
/* 0110 */ V(1, 14, 3),
/* 0111 */ V(1, 14, 3),
/* 1000 */ V(14, 1, 3),
/* 1001 */ V(14, 1, 3),
/* 1010 */ V(0, 14, 4),
/* 1011 */ V(14, 0, 4),
/* 1100 */ V(5, 13, 3),
/* 1101 */ V(5, 13, 3),
/* 1110 */ V(13, 5, 3),
/* 1111 */ V(13, 5, 3),
/* 0000 1000 ... */
/* 000 */ V(7, 12, 3), /* 232 */
/* 001 */ V(12, 7, 3),
/* 010 */ V(4, 13, 3),
/* 011 */ V(8, 11, 3),
/* 100 */ V(13, 4, 2),
/* 101 */ V(13, 4, 2),
/* 110 */ V(11, 8, 3),
/* 111 */ V(9, 10, 3),
/* 0000 1001 ... */
/* 000 */ V(10, 9, 3), /* 240 */
/* 001 */ V(6, 12, 3),
/* 010 */ V(12, 6, 3),
/* 011 */ V(3, 13, 3),
/* 100 */ V(13, 3, 2),
/* 101 */ V(13, 3, 2),
/* 110 */ V(13, 2, 2),
/* 111 */ V(13, 2, 2),
/* 0000 1010 ... */
/* 000 */ V(2, 13, 3), /* 248 */
/* 001 */ V(0, 13, 3),
/* 010 */ V(1, 13, 2),
/* 011 */ V(1, 13, 2),
/* 100 */ V(7, 11, 2),
/* 101 */ V(7, 11, 2),
/* 110 */ V(11, 7, 2),
/* 111 */ V(11, 7, 2),
/* 0000 1011 ... */
/* 000 */ V(13, 1, 2), /* 256 */
/* 001 */ V(13, 1, 2),
/* 010 */ V(5, 12, 3),
/* 011 */ V(13, 0, 3),
/* 100 */ V(12, 5, 2),
/* 101 */ V(12, 5, 2),
/* 110 */ V(8, 10, 2),
/* 111 */ V(8, 10, 2),
/* 0000 1100 ... */
/* 00 */ V(10, 8, 2), /* 264 */
/* 01 */ V(4, 12, 2),
/* 10 */ V(12, 4, 2),
/* 11 */ V(6, 11, 2),
/* 0000 1101 ... */
/* 000 */ V(11, 6, 2), /* 268 */
/* 001 */ V(11, 6, 2),
/* 010 */ V(9, 9, 3),
/* 011 */ V(0, 12, 3),
/* 100 */ V(3, 12, 2),
/* 101 */ V(3, 12, 2),
/* 110 */ V(12, 3, 2),
/* 111 */ V(12, 3, 2),
/* 0000 1110 ... */
/* 000 */ V(7, 10, 2), /* 276 */
/* 001 */ V(7, 10, 2),
/* 010 */ V(10, 7, 2),
/* 011 */ V(10, 7, 2),
/* 100 */ V(10, 6, 2),
/* 101 */ V(10, 6, 2),
/* 110 */ V(12, 0, 3),
/* 111 */ V(0, 11, 3),
/* 0000 1111 ... */
/* 00 */ V(12, 2, 1), /* 284 */
/* 01 */ V(12, 2, 1),
/* 10 */ V(2, 12, 2),
/* 11 */ V(5, 11, 2),
/* 0001 0000 ... */
/* 00 */ V(11, 5, 2), /* 288 */
/* 01 */ V(1, 12, 2),
/* 10 */ V(8, 9, 2),
/* 11 */ V(9, 8, 2),
/* 0001 0001 ... */
/* 00 */ V(12, 1, 2), /* 292 */
/* 01 */ V(4, 11, 2),
/* 10 */ V(11, 4, 2),
/* 11 */ V(6, 10, 2),
/* 0001 0010 ... */
/* 00 */ V(3, 11, 2), /* 296 */
/* 01 */ V(7, 9, 2),
/* 10 */ V(11, 3, 1),
/* 11 */ V(11, 3, 1),
/* 0001 0011 ... */
/* 00 */ V(9, 7, 2), /* 300 */
/* 01 */ V(8, 8, 2),
/* 10 */ V(2, 11, 2),
/* 11 */ V(5, 10, 2),
/* 0001 0100 ... */
/* 00 */ V(11, 2, 1), /* 304 */
/* 01 */ V(11, 2, 1),
/* 10 */ V(10, 5, 2),
/* 11 */ V(1, 11, 2),
/* 0001 0101 ... */
/* 00 */ V(11, 1, 1), /* 308 */
/* 01 */ V(11, 1, 1),
/* 10 */ V(11, 0, 2),
/* 11 */ V(6, 9, 2),
/* 0001 0110 ... */
/* 00 */ V(9, 6, 2), /* 312 */
/* 01 */ V(4, 10, 2),
/* 10 */ V(10, 4, 2),
/* 11 */ V(7, 8, 2),
/* 0001 0111 ... */
/* 00 */ V(8, 7, 2), /* 316 */
/* 01 */ V(3, 10, 2),
/* 10 */ V(10, 3, 1),
/* 11 */ V(10, 3, 1),
/* 0001 1000 ... */
/* 0 */ V(5, 9, 1), /* 320 */
/* 1 */ V(9, 5, 1),
/* 0001 1001 ... */
/* 0 */ V(2, 10, 1), /* 322 */
/* 1 */ V(10, 2, 1),
/* 0001 1010 ... */
/* 0 */ V(1, 10, 1), /* 324 */
/* 1 */ V(10, 1, 1),
/* 0001 1011 ... */
/* 00 */ V(0, 10, 2), /* 326 */
/* 01 */ V(10, 0, 2),
/* 10 */ V(6, 8, 1),
/* 11 */ V(6, 8, 1),
/* 0001 1100 ... */
/* 0 */ V(8, 6, 1), /* 330 */
/* 1 */ V(4, 9, 1),
/* 0001 1101 ... */
/* 0 */ V(9, 4, 1), /* 332 */
/* 1 */ V(3, 9, 1),
/* 0001 1110 ... */
/* 00 */ V(9, 3, 1), /* 334 */
/* 01 */ V(9, 3, 1),
/* 10 */ V(7, 7, 2),
/* 11 */ V(0, 9, 2),
/* 0001 1111 ... */
/* 0 */ V(5, 8, 1), /* 338 */
/* 1 */ V(8, 5, 1),
/* 0010 0000 ... */
/* 0 */ V(2, 9, 1), /* 340 */
/* 1 */ V(6, 7, 1),
/* 0010 0001 ... */
/* 0 */ V(7, 6, 1), /* 342 */
/* 1 */ V(9, 2, 1),
/* 0010 0011 ... */
/* 0 */ V(1, 9, 1), /* 344 */
/* 1 */ V(9, 0, 1),
/* 0010 0100 ... */
/* 0 */ V(4, 8, 1), /* 346 */
/* 1 */ V(8, 4, 1),
/* 0010 0101 ... */
/* 0 */ V(5, 7, 1), /* 348 */
/* 1 */ V(7, 5, 1),
/* 0010 0110 ... */
/* 0 */ V(3, 8, 1), /* 350 */
/* 1 */ V(8, 3, 1),
/* 0010 0111 ... */
/* 0 */ V(6, 6, 1), /* 352 */
/* 1 */ V(4, 7, 1),
/* 0010 1100 ... */
/* 0 */ V(7, 4, 1), /* 354 */
/* 1 */ V(0, 8, 1),
/* 0010 1101 ... */
/* 0 */ V(8, 0, 1), /* 356 */
/* 1 */ V(5, 6, 1),
/* 0010 1110 ... */
/* 0 */ V(6, 5, 1), /* 358 */
/* 1 */ V(3, 7, 1),
/* 0010 1111 ... */
/* 0 */ V(7, 3, 1), /* 360 */
/* 1 */ V(4, 6, 1),
/* 0011 0110 ... */
/* 0 */ V(0, 7, 1), /* 362 */
/* 1 */ V(7, 0, 1),
/* 0011 1110 ... */
/* 0 */ V(0, 6, 1), /* 364 */
/* 1 */ V(6, 0, 1),
/* 0000 0000 0000 ... */
/* 0 */ V(15, 15, 1), /* 366 */
/* 1 */ V(14, 15, 1),
/* 0000 0000 0001 ... */
/* 0 */ V(15, 14, 1), /* 368 */
/* 1 */ V(13, 15, 1),
/* 0000 0000 0011 ... */
/* 0 */ V(15, 13, 1), /* 370 */
/* 1 */ V(12, 15, 1),
/* 0000 0000 0100 ... */
/* 0 */ V(15, 12, 1), /* 372 */
/* 1 */ V(13, 14, 1),
/* 0000 0000 0101 ... */
/* 0 */ V(14, 13, 1), /* 374 */
/* 1 */ V(11, 15, 1),
/* 0000 0000 0111 ... */
/* 0 */ V(12, 14, 1), /* 376 */
/* 1 */ V(14, 12, 1),
/* 0000 0001 1111 ... */
/* 0 */ V(10, 14, 1), /* 378 */
/* 1 */ V(0, 15, 1)
};
static
union huffpair const hufftab16[] = {
/* 0000 */ PTR(16, 4),
/* 0001 */ PTR(32, 4),
/* 0010 */ PTR(48, 4),
/* 0011 */ PTR(64, 2),
/* 0100 */ V(1, 1, 4),
/* 0101 */ V(0, 1, 4),
/* 0110 */ V(1, 0, 3),
/* 0111 */ V(1, 0, 3),
/* 1000 */ V(0, 0, 1),
/* 1001 */ V(0, 0, 1),
/* 1010 */ V(0, 0, 1),
/* 1011 */ V(0, 0, 1),
/* 1100 */ V(0, 0, 1),
/* 1101 */ V(0, 0, 1),
/* 1110 */ V(0, 0, 1),
/* 1111 */ V(0, 0, 1),
/* 0000 ... */
/* 0000 */ PTR(68, 3), /* 16 */
/* 0001 */ PTR(76, 3),
/* 0010 */ PTR(84, 2),
/* 0011 */ V(15, 15, 4),
/* 0100 */ PTR(88, 2),
/* 0101 */ PTR(92, 1),
/* 0110 */ PTR(94, 4),
/* 0111 */ V(15, 2, 4),
/* 1000 */ PTR(110, 1),
/* 1001 */ V(1, 15, 4),
/* 1010 */ V(15, 1, 4),
/* 1011 */ PTR(112, 4),
/* 1100 */ PTR(128, 4),
/* 1101 */ PTR(144, 4),
/* 1110 */ PTR(160, 4),
/* 1111 */ PTR(176, 4),
/* 0001 ... */
/* 0000 */ PTR(192, 4), /* 32 */
/* 0001 */ PTR(208, 3),
/* 0010 */ PTR(216, 3),
/* 0011 */ PTR(224, 3),
/* 0100 */ PTR(232, 3),
/* 0101 */ PTR(240, 3),
/* 0110 */ PTR(248, 3),
/* 0111 */ PTR(256, 3),
/* 1000 */ PTR(264, 2),
/* 1001 */ PTR(268, 2),
/* 1010 */ PTR(272, 1),
/* 1011 */ PTR(274, 2),
/* 1100 */ PTR(278, 2),
/* 1101 */ PTR(282, 1),
/* 1110 */ V(5, 1, 4),
/* 1111 */ PTR(284, 1),
/* 0010 ... */
/* 0000 */ PTR(286, 1), /* 48 */
/* 0001 */ PTR(288, 1),
/* 0010 */ PTR(290, 1),
/* 0011 */ V(1, 4, 4),
/* 0100 */ V(4, 1, 4),
/* 0101 */ PTR(292, 1),
/* 0110 */ V(2, 3, 4),
/* 0111 */ V(3, 2, 4),
/* 1000 */ V(1, 3, 3),
/* 1001 */ V(1, 3, 3),
/* 1010 */ V(3, 1, 3),
/* 1011 */ V(3, 1, 3),
/* 1100 */ V(0, 3, 4),
/* 1101 */ V(3, 0, 4),
/* 1110 */ V(2, 2, 3),
/* 1111 */ V(2, 2, 3),
/* 0011 ... */
/* 00 */ V(1, 2, 2), /* 64 */
/* 01 */ V(2, 1, 2),
/* 10 */ V(0, 2, 2),
/* 11 */ V(2, 0, 2),
/* 0000 0000 ... */
/* 000 */ V(14, 15, 3), /* 68 */
/* 001 */ V(15, 14, 3),
/* 010 */ V(13, 15, 3),
/* 011 */ V(15, 13, 3),
/* 100 */ V(12, 15, 3),
/* 101 */ V(15, 12, 3),
/* 110 */ V(11, 15, 3),
/* 111 */ V(15, 11, 3),
/* 0000 0001 ... */
/* 000 */ V(10, 15, 2), /* 76 */
/* 001 */ V(10, 15, 2),
/* 010 */ V(15, 10, 3),
/* 011 */ V(9, 15, 3),
/* 100 */ V(15, 9, 3),
/* 101 */ V(15, 8, 3),
/* 110 */ V(8, 15, 2),
/* 111 */ V(8, 15, 2),
/* 0000 0010 ... */
/* 00 */ V(7, 15, 2), /* 84 */
/* 01 */ V(15, 7, 2),
/* 10 */ V(6, 15, 2),
/* 11 */ V(15, 6, 2),
/* 0000 0100 ... */
/* 00 */ V(5, 15, 2), /* 88 */
/* 01 */ V(15, 5, 2),
/* 10 */ V(4, 15, 1),
/* 11 */ V(4, 15, 1),
/* 0000 0101 ... */
/* 0 */ V(15, 4, 1), /* 92 */
/* 1 */ V(15, 3, 1),
/* 0000 0110 ... */
/* 0000 */ V(15, 0, 1), /* 94 */
/* 0001 */ V(15, 0, 1),
/* 0010 */ V(15, 0, 1),
/* 0011 */ V(15, 0, 1),
/* 0100 */ V(15, 0, 1),
/* 0101 */ V(15, 0, 1),
/* 0110 */ V(15, 0, 1),
/* 0111 */ V(15, 0, 1),
/* 1000 */ V(3, 15, 2),
/* 1001 */ V(3, 15, 2),
/* 1010 */ V(3, 15, 2),
/* 1011 */ V(3, 15, 2),
/* 1100 */ PTR(294, 4),
/* 1101 */ PTR(310, 3),
/* 1110 */ PTR(318, 3),
/* 1111 */ PTR(326, 3),
/* 0000 1000 ... */
/* 0 */ V(2, 15, 1), /* 110 */
/* 1 */ V(0, 15, 1),
/* 0000 1011 ... */
/* 0000 */ PTR(334, 2), /* 112 */
/* 0001 */ PTR(338, 2),
/* 0010 */ PTR(342, 2),
/* 0011 */ PTR(346, 1),
/* 0100 */ PTR(348, 2),
/* 0101 */ PTR(352, 2),
/* 0110 */ PTR(356, 1),
/* 0111 */ PTR(358, 2),
/* 1000 */ PTR(362, 2),
/* 1001 */ PTR(366, 2),
/* 1010 */ PTR(370, 2),
/* 1011 */ V(14, 3, 4),
/* 1100 */ PTR(374, 1),
/* 1101 */ PTR(376, 1),
/* 1110 */ PTR(378, 1),
/* 1111 */ PTR(380, 1),
/* 0000 1100 ... */
/* 0000 */ PTR(382, 1), /* 128 */
/* 0001 */ PTR(384, 1),
/* 0010 */ PTR(386, 1),
/* 0011 */ V(0, 13, 4),
/* 0100 */ PTR(388, 1),
/* 0101 */ PTR(390, 1),
/* 0110 */ PTR(392, 1),
/* 0111 */ V(3, 12, 4),
/* 1000 */ PTR(394, 1),
/* 1001 */ V(1, 12, 4),
/* 1010 */ V(12, 0, 4),
/* 1011 */ PTR(396, 1),
/* 1100 */ V(14, 2, 3),
/* 1101 */ V(14, 2, 3),
/* 1110 */ V(2, 14, 4),
/* 1111 */ V(1, 14, 4),
/* 0000 1101 ... */
/* 0000 */ V(13, 3, 4), /* 144 */
/* 0001 */ V(2, 13, 4),
/* 0010 */ V(13, 2, 4),
/* 0011 */ V(13, 1, 4),
/* 0100 */ V(3, 11, 4),
/* 0101 */ PTR(398, 1),
/* 0110 */ V(1, 13, 3),
/* 0111 */ V(1, 13, 3),
/* 1000 */ V(12, 4, 4),
/* 1001 */ V(6, 11, 4),
/* 1010 */ V(12, 3, 4),
/* 1011 */ V(10, 7, 4),
/* 1100 */ V(2, 12, 3),
/* 1101 */ V(2, 12, 3),
/* 1110 */ V(12, 2, 4),
/* 1111 */ V(11, 5, 4),
/* 0000 1110 ... */
/* 0000 */ V(12, 1, 4), /* 160 */
/* 0001 */ V(0, 12, 4),
/* 0010 */ V(4, 11, 4),
/* 0011 */ V(11, 4, 4),
/* 0100 */ V(6, 10, 4),
/* 0101 */ V(10, 6, 4),
/* 0110 */ V(11, 3, 3),
/* 0111 */ V(11, 3, 3),
/* 1000 */ V(5, 10, 4),
/* 1001 */ V(10, 5, 4),
/* 1010 */ V(2, 11, 3),
/* 1011 */ V(2, 11, 3),
/* 1100 */ V(11, 2, 3),
/* 1101 */ V(11, 2, 3),
/* 1110 */ V(1, 11, 3),
/* 1111 */ V(1, 11, 3),
/* 0000 1111 ... */
/* 0000 */ V(11, 1, 3), /* 176 */
/* 0001 */ V(11, 1, 3),
/* 0010 */ V(0, 11, 4),
/* 0011 */ V(11, 0, 4),
/* 0100 */ V(6, 9, 4),
/* 0101 */ V(9, 6, 4),
/* 0110 */ V(4, 10, 4),
/* 0111 */ V(10, 4, 4),
/* 1000 */ V(7, 8, 4),
/* 1001 */ V(8, 7, 4),
/* 1010 */ V(10, 3, 3),
/* 1011 */ V(10, 3, 3),
/* 1100 */ V(3, 10, 4),
/* 1101 */ V(5, 9, 4),
/* 1110 */ V(2, 10, 3),
/* 1111 */ V(2, 10, 3),
/* 0001 0000 ... */
/* 0000 */ V(9, 5, 4), /* 192 */
/* 0001 */ V(6, 8, 4),
/* 0010 */ V(10, 1, 3),
/* 0011 */ V(10, 1, 3),
/* 0100 */ V(8, 6, 4),
/* 0101 */ V(7, 7, 4),
/* 0110 */ V(9, 4, 3),
/* 0111 */ V(9, 4, 3),
/* 1000 */ V(4, 9, 4),
/* 1001 */ V(5, 7, 4),
/* 1010 */ V(6, 7, 3),
/* 1011 */ V(6, 7, 3),
/* 1100 */ V(10, 2, 2),
/* 1101 */ V(10, 2, 2),
/* 1110 */ V(10, 2, 2),
/* 1111 */ V(10, 2, 2),
/* 0001 0001 ... */
/* 000 */ V(1, 10, 2), /* 208 */
/* 001 */ V(1, 10, 2),
/* 010 */ V(0, 10, 3),
/* 011 */ V(10, 0, 3),
/* 100 */ V(3, 9, 3),
/* 101 */ V(9, 3, 3),
/* 110 */ V(5, 8, 3),
/* 111 */ V(8, 5, 3),
/* 0001 0010 ... */
/* 000 */ V(2, 9, 2), /* 216 */
/* 001 */ V(2, 9, 2),
/* 010 */ V(9, 2, 2),
/* 011 */ V(9, 2, 2),
/* 100 */ V(7, 6, 3),
/* 101 */ V(0, 9, 3),
/* 110 */ V(1, 9, 2),
/* 111 */ V(1, 9, 2),
/* 0001 0011 ... */
/* 000 */ V(9, 1, 2), /* 224 */
/* 001 */ V(9, 1, 2),
/* 010 */ V(9, 0, 3),
/* 011 */ V(4, 8, 3),
/* 100 */ V(8, 4, 3),
/* 101 */ V(7, 5, 3),
/* 110 */ V(3, 8, 3),
/* 111 */ V(8, 3, 3),
/* 0001 0100 ... */
/* 000 */ V(6, 6, 3), /* 232 */
/* 001 */ V(2, 8, 3),
/* 010 */ V(8, 2, 2),
/* 011 */ V(8, 2, 2),
/* 100 */ V(4, 7, 3),
/* 101 */ V(7, 4, 3),
/* 110 */ V(1, 8, 2),
/* 111 */ V(1, 8, 2),
/* 0001 0101 ... */
/* 000 */ V(8, 1, 2), /* 240 */
/* 001 */ V(8, 1, 2),
/* 010 */ V(8, 0, 2),
/* 011 */ V(8, 0, 2),
/* 100 */ V(0, 8, 3),
/* 101 */ V(5, 6, 3),
/* 110 */ V(3, 7, 2),
/* 111 */ V(3, 7, 2),
/* 0001 0110 ... */
/* 000 */ V(7, 3, 2), /* 248 */
/* 001 */ V(7, 3, 2),
/* 010 */ V(6, 5, 3),
/* 011 */ V(4, 6, 3),
/* 100 */ V(2, 7, 2),
/* 101 */ V(2, 7, 2),
/* 110 */ V(7, 2, 2),
/* 111 */ V(7, 2, 2),
/* 0001 0111 ... */
/* 000 */ V(6, 4, 3), /* 256 */
/* 001 */ V(5, 5, 3),
/* 010 */ V(0, 7, 2),
/* 011 */ V(0, 7, 2),
/* 100 */ V(1, 7, 1),
/* 101 */ V(1, 7, 1),
/* 110 */ V(1, 7, 1),
/* 111 */ V(1, 7, 1),
/* 0001 1000 ... */
/* 00 */ V(7, 1, 1), /* 264 */
/* 01 */ V(7, 1, 1),
/* 10 */ V(7, 0, 2),
/* 11 */ V(3, 6, 2),
/* 0001 1001 ... */
/* 00 */ V(6, 3, 2), /* 268 */
/* 01 */ V(4, 5, 2),
/* 10 */ V(5, 4, 2),
/* 11 */ V(2, 6, 2),
/* 0001 1010 ... */
/* 0 */ V(6, 2, 1), /* 272 */
/* 1 */ V(1, 6, 1),
/* 0001 1011 ... */
/* 00 */ V(6, 1, 1), /* 274 */
/* 01 */ V(6, 1, 1),
/* 10 */ V(0, 6, 2),
/* 11 */ V(6, 0, 2),
/* 0001 1100 ... */
/* 00 */ V(5, 3, 1), /* 278 */
/* 01 */ V(5, 3, 1),
/* 10 */ V(3, 5, 2),
/* 11 */ V(4, 4, 2),
/* 0001 1101 ... */
/* 0 */ V(2, 5, 1), /* 282 */
/* 1 */ V(5, 2, 1),
/* 0001 1111 ... */
/* 0 */ V(1, 5, 1), /* 284 */
/* 1 */ V(0, 5, 1),
/* 0010 0000 ... */
/* 0 */ V(3, 4, 1), /* 286 */
/* 1 */ V(4, 3, 1),
/* 0010 0001 ... */
/* 0 */ V(5, 0, 1), /* 288 */
/* 1 */ V(2, 4, 1),
/* 0010 0010 ... */
/* 0 */ V(4, 2, 1), /* 290 */
/* 1 */ V(3, 3, 1),
/* 0010 0101 ... */
/* 0 */ V(0, 4, 1), /* 292 */
/* 1 */ V(4, 0, 1),
/* 0000 0110 1100 ... */
/* 0000 */ V(12, 14, 4), /* 294 */
/* 0001 */ PTR(400, 1),
/* 0010 */ V(13, 14, 3),
/* 0011 */ V(13, 14, 3),
/* 0100 */ V(14, 9, 3),
/* 0101 */ V(14, 9, 3),
/* 0110 */ V(14, 10, 4),
/* 0111 */ V(13, 9, 4),
/* 1000 */ V(14, 14, 2),
/* 1001 */ V(14, 14, 2),
/* 1010 */ V(14, 14, 2),
/* 1011 */ V(14, 14, 2),
/* 1100 */ V(14, 13, 3),
/* 1101 */ V(14, 13, 3),
/* 1110 */ V(14, 11, 3),
/* 1111 */ V(14, 11, 3),
/* 0000 0110 1101 ... */
/* 000 */ V(11, 14, 2), /* 310 */
/* 001 */ V(11, 14, 2),
/* 010 */ V(12, 13, 2),
/* 011 */ V(12, 13, 2),
/* 100 */ V(13, 12, 3),
/* 101 */ V(13, 11, 3),
/* 110 */ V(10, 14, 2),
/* 111 */ V(10, 14, 2),
/* 0000 0110 1110 ... */
/* 000 */ V(12, 12, 2), /* 318 */
/* 001 */ V(12, 12, 2),
/* 010 */ V(10, 13, 3),
/* 011 */ V(13, 10, 3),
/* 100 */ V(7, 14, 3),
/* 101 */ V(10, 12, 3),
/* 110 */ V(12, 10, 2),
/* 111 */ V(12, 10, 2),
/* 0000 0110 1111 ... */
/* 000 */ V(12, 9, 3), /* 326 */
/* 001 */ V(7, 13, 3),
/* 010 */ V(5, 14, 2),
/* 011 */ V(5, 14, 2),
/* 100 */ V(11, 13, 1),
/* 101 */ V(11, 13, 1),
/* 110 */ V(11, 13, 1),
/* 111 */ V(11, 13, 1),
/* 0000 1011 0000 ... */
/* 00 */ V(9, 14, 1), /* 334 */
/* 01 */ V(9, 14, 1),
/* 10 */ V(11, 12, 2),
/* 11 */ V(12, 11, 2),
/* 0000 1011 0001 ... */
/* 00 */ V(8, 14, 2), /* 338 */
/* 01 */ V(14, 8, 2),
/* 10 */ V(9, 13, 2),
/* 11 */ V(14, 7, 2),
/* 0000 1011 0010 ... */
/* 00 */ V(11, 11, 2), /* 342 */
/* 01 */ V(8, 13, 2),
/* 10 */ V(13, 8, 2),
/* 11 */ V(6, 14, 2),
/* 0000 1011 0011 ... */
/* 0 */ V(14, 6, 1), /* 346 */
/* 1 */ V(9, 12, 1),
/* 0000 1011 0100 ... */
/* 00 */ V(10, 11, 2), /* 348 */
/* 01 */ V(11, 10, 2),
/* 10 */ V(14, 5, 2),
/* 11 */ V(13, 7, 2),
/* 0000 1011 0101 ... */
/* 00 */ V(4, 14, 1), /* 352 */
/* 01 */ V(4, 14, 1),
/* 10 */ V(14, 4, 2),
/* 11 */ V(8, 12, 2),
/* 0000 1011 0110 ... */
/* 0 */ V(12, 8, 1), /* 356 */
/* 1 */ V(3, 14, 1),
/* 0000 1011 0111 ... */
/* 00 */ V(6, 13, 1), /* 358 */
/* 01 */ V(6, 13, 1),
/* 10 */ V(13, 6, 2),
/* 11 */ V(9, 11, 2),
/* 0000 1011 1000 ... */
/* 00 */ V(11, 9, 2), /* 362 */
/* 01 */ V(10, 10, 2),
/* 10 */ V(14, 1, 1),
/* 11 */ V(14, 1, 1),
/* 0000 1011 1001 ... */
/* 00 */ V(13, 4, 1), /* 366 */
/* 01 */ V(13, 4, 1),
/* 10 */ V(11, 8, 2),
/* 11 */ V(10, 9, 2),
/* 0000 1011 1010 ... */
/* 00 */ V(7, 11, 1), /* 370 */
/* 01 */ V(7, 11, 1),
/* 10 */ V(11, 7, 2),
/* 11 */ V(13, 0, 2),
/* 0000 1011 1100 ... */
/* 0 */ V(0, 14, 1), /* 374 */
/* 1 */ V(14, 0, 1),
/* 0000 1011 1101 ... */
/* 0 */ V(5, 13, 1), /* 376 */
/* 1 */ V(13, 5, 1),
/* 0000 1011 1110 ... */
/* 0 */ V(7, 12, 1), /* 378 */
/* 1 */ V(12, 7, 1),
/* 0000 1011 1111 ... */
/* 0 */ V(4, 13, 1), /* 380 */
/* 1 */ V(8, 11, 1),
/* 0000 1100 0000 ... */
/* 0 */ V(9, 10, 1), /* 382 */
/* 1 */ V(6, 12, 1),
/* 0000 1100 0001 ... */
/* 0 */ V(12, 6, 1), /* 384 */
/* 1 */ V(3, 13, 1),
/* 0000 1100 0010 ... */
/* 0 */ V(5, 12, 1), /* 386 */
/* 1 */ V(12, 5, 1),
/* 0000 1100 0100 ... */
/* 0 */ V(8, 10, 1), /* 388 */
/* 1 */ V(10, 8, 1),
/* 0000 1100 0101 ... */
/* 0 */ V(9, 9, 1), /* 390 */
/* 1 */ V(4, 12, 1),
/* 0000 1100 0110 ... */
/* 0 */ V(11, 6, 1), /* 392 */
/* 1 */ V(7, 10, 1),
/* 0000 1100 1000 ... */
/* 0 */ V(5, 11, 1), /* 394 */
/* 1 */ V(8, 9, 1),
/* 0000 1100 1011 ... */
/* 0 */ V(9, 8, 1), /* 396 */
/* 1 */ V(7, 9, 1),
/* 0000 1101 0101 ... */
/* 0 */ V(9, 7, 1), /* 398 */
/* 1 */ V(8, 8, 1),
/* 0000 0110 1100 0001 ... */
/* 0 */ V(14, 12, 1), /* 400 */
/* 1 */ V(13, 13, 1)
};
static
union huffpair const hufftab24[] = {
/* 0000 */ PTR(16, 4),
/* 0001 */ PTR(32, 4),
/* 0010 */ PTR(48, 4),
/* 0011 */ V(15, 15, 4),
/* 0100 */ PTR(64, 4),
/* 0101 */ PTR(80, 4),
/* 0110 */ PTR(96, 4),
/* 0111 */ PTR(112, 4),
/* 1000 */ PTR(128, 4),
/* 1001 */ PTR(144, 4),
/* 1010 */ PTR(160, 3),
/* 1011 */ PTR(168, 2),
/* 1100 */ V(1, 1, 4),
/* 1101 */ V(0, 1, 4),
/* 1110 */ V(1, 0, 4),
/* 1111 */ V(0, 0, 4),
/* 0000 ... */
/* 0000 */ V(14, 15, 4), /* 16 */
/* 0001 */ V(15, 14, 4),
/* 0010 */ V(13, 15, 4),
/* 0011 */ V(15, 13, 4),
/* 0100 */ V(12, 15, 4),
/* 0101 */ V(15, 12, 4),
/* 0110 */ V(11, 15, 4),
/* 0111 */ V(15, 11, 4),
/* 1000 */ V(15, 10, 3),
/* 1001 */ V(15, 10, 3),
/* 1010 */ V(10, 15, 4),
/* 1011 */ V(9, 15, 4),
/* 1100 */ V(15, 9, 3),
/* 1101 */ V(15, 9, 3),
/* 1110 */ V(15, 8, 3),
/* 1111 */ V(15, 8, 3),
/* 0001 ... */
/* 0000 */ V(8, 15, 4), /* 32 */
/* 0001 */ V(7, 15, 4),
/* 0010 */ V(15, 7, 3),
/* 0011 */ V(15, 7, 3),
/* 0100 */ V(6, 15, 3),
/* 0101 */ V(6, 15, 3),
/* 0110 */ V(15, 6, 3),
/* 0111 */ V(15, 6, 3),
/* 1000 */ V(5, 15, 3),
/* 1001 */ V(5, 15, 3),
/* 1010 */ V(15, 5, 3),
/* 1011 */ V(15, 5, 3),
/* 1100 */ V(4, 15, 3),
/* 1101 */ V(4, 15, 3),
/* 1110 */ V(15, 4, 3),
/* 1111 */ V(15, 4, 3),
/* 0010 ... */
/* 0000 */ V(3, 15, 3), /* 48 */
/* 0001 */ V(3, 15, 3),
/* 0010 */ V(15, 3, 3),
/* 0011 */ V(15, 3, 3),
/* 0100 */ V(2, 15, 3),
/* 0101 */ V(2, 15, 3),
/* 0110 */ V(15, 2, 3),
/* 0111 */ V(15, 2, 3),
/* 1000 */ V(15, 1, 3),
/* 1001 */ V(15, 1, 3),
/* 1010 */ V(1, 15, 4),
/* 1011 */ V(15, 0, 4),
/* 1100 */ PTR(172, 3),
/* 1101 */ PTR(180, 3),
/* 1110 */ PTR(188, 3),
/* 1111 */ PTR(196, 3),
/* 0100 ... */
/* 0000 */ PTR(204, 4), /* 64 */
/* 0001 */ PTR(220, 3),
/* 0010 */ PTR(228, 3),
/* 0011 */ PTR(236, 3),
/* 0100 */ PTR(244, 2),
/* 0101 */ PTR(248, 2),
/* 0110 */ PTR(252, 2),
/* 0111 */ PTR(256, 2),
/* 1000 */ PTR(260, 2),
/* 1001 */ PTR(264, 2),
/* 1010 */ PTR(268, 2),
/* 1011 */ PTR(272, 2),
/* 1100 */ PTR(276, 2),
/* 1101 */ PTR(280, 3),
/* 1110 */ PTR(288, 2),
/* 1111 */ PTR(292, 2),
/* 0101 ... */
/* 0000 */ PTR(296, 2), /* 80 */
/* 0001 */ PTR(300, 3),
/* 0010 */ PTR(308, 2),
/* 0011 */ PTR(312, 3),
/* 0100 */ PTR(320, 1),
/* 0101 */ PTR(322, 2),
/* 0110 */ PTR(326, 2),
/* 0111 */ PTR(330, 1),
/* 1000 */ PTR(332, 2),
/* 1001 */ PTR(336, 1),
/* 1010 */ PTR(338, 1),
/* 1011 */ PTR(340, 1),
/* 1100 */ PTR(342, 1),
/* 1101 */ PTR(344, 1),
/* 1110 */ PTR(346, 1),
/* 1111 */ PTR(348, 1),
/* 0110 ... */
/* 0000 */ PTR(350, 1), /* 96 */
/* 0001 */ PTR(352, 1),
/* 0010 */ PTR(354, 1),
/* 0011 */ PTR(356, 1),
/* 0100 */ PTR(358, 1),
/* 0101 */ PTR(360, 1),
/* 0110 */ PTR(362, 1),
/* 0111 */ PTR(364, 1),
/* 1000 */ PTR(366, 1),
/* 1001 */ PTR(368, 1),
/* 1010 */ PTR(370, 2),
/* 1011 */ PTR(374, 1),
/* 1100 */ PTR(376, 2),
/* 1101 */ V(7, 3, 4),
/* 1110 */ PTR(380, 1),
/* 1111 */ V(7, 2, 4),
/* 0111 ... */
/* 0000 */ V(4, 6, 4), /* 112 */
/* 0001 */ V(6, 4, 4),
/* 0010 */ V(5, 5, 4),
/* 0011 */ V(7, 1, 4),
/* 0100 */ V(3, 6, 4),
/* 0101 */ V(6, 3, 4),
/* 0110 */ V(4, 5, 4),
/* 0111 */ V(5, 4, 4),
/* 1000 */ V(2, 6, 4),
/* 1001 */ V(6, 2, 4),
/* 1010 */ V(1, 6, 4),
/* 1011 */ V(6, 1, 4),
/* 1100 */ PTR(382, 1),
/* 1101 */ V(3, 5, 4),
/* 1110 */ V(5, 3, 4),
/* 1111 */ V(4, 4, 4),
/* 1000 ... */
/* 0000 */ V(2, 5, 4), /* 128 */
/* 0001 */ V(5, 2, 4),
/* 0010 */ V(1, 5, 4),
/* 0011 */ PTR(384, 1),
/* 0100 */ V(5, 1, 3),
/* 0101 */ V(5, 1, 3),
/* 0110 */ V(3, 4, 4),
/* 0111 */ V(4, 3, 4),
/* 1000 */ V(2, 4, 3),
/* 1001 */ V(2, 4, 3),
/* 1010 */ V(4, 2, 3),
/* 1011 */ V(4, 2, 3),
/* 1100 */ V(3, 3, 3),
/* 1101 */ V(3, 3, 3),
/* 1110 */ V(1, 4, 3),
/* 1111 */ V(1, 4, 3),
/* 1001 ... */
/* 0000 */ V(4, 1, 3), /* 144 */
/* 0001 */ V(4, 1, 3),
/* 0010 */ V(0, 4, 4),
/* 0011 */ V(4, 0, 4),
/* 0100 */ V(2, 3, 3),
/* 0101 */ V(2, 3, 3),
/* 0110 */ V(3, 2, 3),
/* 0111 */ V(3, 2, 3),
/* 1000 */ V(1, 3, 2),
/* 1001 */ V(1, 3, 2),
/* 1010 */ V(1, 3, 2),
/* 1011 */ V(1, 3, 2),
/* 1100 */ V(3, 1, 2),
/* 1101 */ V(3, 1, 2),
/* 1110 */ V(3, 1, 2),
/* 1111 */ V(3, 1, 2),
/* 1010 ... */
/* 000 */ V(0, 3, 3), /* 160 */
/* 001 */ V(3, 0, 3),
/* 010 */ V(2, 2, 2),
/* 011 */ V(2, 2, 2),
/* 100 */ V(1, 2, 1),
/* 101 */ V(1, 2, 1),
/* 110 */ V(1, 2, 1),
/* 111 */ V(1, 2, 1),
/* 1011 ... */
/* 00 */ V(2, 1, 1), /* 168 */
/* 01 */ V(2, 1, 1),
/* 10 */ V(0, 2, 2),
/* 11 */ V(2, 0, 2),
/* 0010 1100 ... */
/* 000 */ V(0, 15, 1), /* 172 */
/* 001 */ V(0, 15, 1),
/* 010 */ V(0, 15, 1),
/* 011 */ V(0, 15, 1),
/* 100 */ V(14, 14, 3),
/* 101 */ V(13, 14, 3),
/* 110 */ V(14, 13, 3),
/* 111 */ V(12, 14, 3),
/* 0010 1101 ... */
/* 000 */ V(14, 12, 3), /* 180 */
/* 001 */ V(13, 13, 3),
/* 010 */ V(11, 14, 3),
/* 011 */ V(14, 11, 3),
/* 100 */ V(12, 13, 3),
/* 101 */ V(13, 12, 3),
/* 110 */ V(10, 14, 3),
/* 111 */ V(14, 10, 3),
/* 0010 1110 ... */
/* 000 */ V(11, 13, 3), /* 188 */
/* 001 */ V(13, 11, 3),
/* 010 */ V(12, 12, 3),
/* 011 */ V(9, 14, 3),
/* 100 */ V(14, 9, 3),
/* 101 */ V(10, 13, 3),
/* 110 */ V(13, 10, 3),
/* 111 */ V(11, 12, 3),
/* 0010 1111 ... */
/* 000 */ V(12, 11, 3), /* 196 */
/* 001 */ V(8, 14, 3),
/* 010 */ V(14, 8, 3),
/* 011 */ V(9, 13, 3),
/* 100 */ V(13, 9, 3),
/* 101 */ V(7, 14, 3),
/* 110 */ V(14, 7, 3),
/* 111 */ V(10, 12, 3),
/* 0100 0000 ... */
/* 0000 */ V(12, 10, 3), /* 204 */
/* 0001 */ V(12, 10, 3),
/* 0010 */ V(11, 11, 3),
/* 0011 */ V(11, 11, 3),
/* 0100 */ V(8, 13, 3),
/* 0101 */ V(8, 13, 3),
/* 0110 */ V(13, 8, 3),
/* 0111 */ V(13, 8, 3),
/* 1000 */ V(0, 14, 4),
/* 1001 */ V(14, 0, 4),
/* 1010 */ V(0, 13, 3),
/* 1011 */ V(0, 13, 3),
/* 1100 */ V(14, 6, 2),
/* 1101 */ V(14, 6, 2),
/* 1110 */ V(14, 6, 2),
/* 1111 */ V(14, 6, 2),
/* 0100 0001 ... */
/* 000 */ V(6, 14, 3), /* 220 */
/* 001 */ V(9, 12, 3),
/* 010 */ V(12, 9, 2),
/* 011 */ V(12, 9, 2),
/* 100 */ V(5, 14, 2),
/* 101 */ V(5, 14, 2),
/* 110 */ V(11, 10, 2),
/* 111 */ V(11, 10, 2),
/* 0100 0010 ... */
/* 000 */ V(14, 5, 2), /* 228 */
/* 001 */ V(14, 5, 2),
/* 010 */ V(10, 11, 3),
/* 011 */ V(7, 13, 3),
/* 100 */ V(13, 7, 2),
/* 101 */ V(13, 7, 2),
/* 110 */ V(14, 4, 2),
/* 111 */ V(14, 4, 2),
/* 0100 0011 ... */
/* 000 */ V(8, 12, 2), /* 236 */
/* 001 */ V(8, 12, 2),
/* 010 */ V(12, 8, 2),
/* 011 */ V(12, 8, 2),
/* 100 */ V(4, 14, 3),
/* 101 */ V(2, 14, 3),
/* 110 */ V(3, 14, 2),
/* 111 */ V(3, 14, 2),
/* 0100 0100 ... */
/* 00 */ V(6, 13, 2), /* 244 */
/* 01 */ V(13, 6, 2),
/* 10 */ V(14, 3, 2),
/* 11 */ V(9, 11, 2),
/* 0100 0101 ... */
/* 00 */ V(11, 9, 2), /* 248 */
/* 01 */ V(10, 10, 2),
/* 10 */ V(14, 2, 2),
/* 11 */ V(1, 14, 2),
/* 0100 0110 ... */
/* 00 */ V(14, 1, 2), /* 252 */
/* 01 */ V(5, 13, 2),
/* 10 */ V(13, 5, 2),
/* 11 */ V(7, 12, 2),
/* 0100 0111 ... */
/* 00 */ V(12, 7, 2), /* 256 */
/* 01 */ V(4, 13, 2),
/* 10 */ V(8, 11, 2),
/* 11 */ V(11, 8, 2),
/* 0100 1000 ... */
/* 00 */ V(13, 4, 2), /* 260 */
/* 01 */ V(9, 10, 2),
/* 10 */ V(10, 9, 2),
/* 11 */ V(6, 12, 2),
/* 0100 1001 ... */
/* 00 */ V(12, 6, 2), /* 264 */
/* 01 */ V(3, 13, 2),
/* 10 */ V(13, 3, 2),
/* 11 */ V(2, 13, 2),
/* 0100 1010 ... */
/* 00 */ V(13, 2, 2), /* 268 */
/* 01 */ V(1, 13, 2),
/* 10 */ V(7, 11, 2),
/* 11 */ V(11, 7, 2),
/* 0100 1011 ... */
/* 00 */ V(13, 1, 2), /* 272 */
/* 01 */ V(5, 12, 2),
/* 10 */ V(12, 5, 2),
/* 11 */ V(8, 10, 2),
/* 0100 1100 ... */
/* 00 */ V(10, 8, 2), /* 276 */
/* 01 */ V(9, 9, 2),
/* 10 */ V(4, 12, 2),
/* 11 */ V(12, 4, 2),
/* 0100 1101 ... */
/* 000 */ V(6, 11, 2), /* 280 */
/* 001 */ V(6, 11, 2),
/* 010 */ V(11, 6, 2),
/* 011 */ V(11, 6, 2),
/* 100 */ V(13, 0, 3),
/* 101 */ V(0, 12, 3),
/* 110 */ V(3, 12, 2),
/* 111 */ V(3, 12, 2),
/* 0100 1110 ... */
/* 00 */ V(12, 3, 2), /* 288 */
/* 01 */ V(7, 10, 2),
/* 10 */ V(10, 7, 2),
/* 11 */ V(2, 12, 2),
/* 0100 1111 ... */
/* 00 */ V(12, 2, 2), /* 292 */
/* 01 */ V(5, 11, 2),
/* 10 */ V(11, 5, 2),
/* 11 */ V(1, 12, 2),
/* 0101 0000 ... */
/* 00 */ V(8, 9, 2), /* 296 */
/* 01 */ V(9, 8, 2),
/* 10 */ V(12, 1, 2),
/* 11 */ V(4, 11, 2),
/* 0101 0001 ... */
/* 000 */ V(12, 0, 3), /* 300 */
/* 001 */ V(0, 11, 3),
/* 010 */ V(3, 11, 2),
/* 011 */ V(3, 11, 2),
/* 100 */ V(11, 0, 3),
/* 101 */ V(0, 10, 3),
/* 110 */ V(1, 10, 2),
/* 111 */ V(1, 10, 2),
/* 0101 0010 ... */
/* 00 */ V(11, 4, 1), /* 308 */
/* 01 */ V(11, 4, 1),
/* 10 */ V(6, 10, 2),
/* 11 */ V(10, 6, 2),
/* 0101 0011 ... */
/* 000 */ V(7, 9, 2), /* 312 */
/* 001 */ V(7, 9, 2),
/* 010 */ V(9, 7, 2),
/* 011 */ V(9, 7, 2),
/* 100 */ V(10, 0, 3),
/* 101 */ V(0, 9, 3),
/* 110 */ V(9, 0, 2),
/* 111 */ V(9, 0, 2),
/* 0101 0100 ... */
/* 0 */ V(11, 3, 1), /* 320 */
/* 1 */ V(8, 8, 1),
/* 0101 0101 ... */
/* 00 */ V(2, 11, 2), /* 322 */
/* 01 */ V(5, 10, 2),
/* 10 */ V(11, 2, 1),
/* 11 */ V(11, 2, 1),
/* 0101 0110 ... */
/* 00 */ V(10, 5, 2), /* 326 */
/* 01 */ V(1, 11, 2),
/* 10 */ V(11, 1, 2),
/* 11 */ V(6, 9, 2),
/* 0101 0111 ... */
/* 0 */ V(9, 6, 1), /* 330 */
/* 1 */ V(10, 4, 1),
/* 0101 1000 ... */
/* 00 */ V(4, 10, 2), /* 332 */
/* 01 */ V(7, 8, 2),
/* 10 */ V(8, 7, 1),
/* 11 */ V(8, 7, 1),
/* 0101 1001 ... */
/* 0 */ V(3, 10, 1), /* 336 */
/* 1 */ V(10, 3, 1),
/* 0101 1010 ... */
/* 0 */ V(5, 9, 1), /* 338 */
/* 1 */ V(9, 5, 1),
/* 0101 1011 ... */
/* 0 */ V(2, 10, 1), /* 340 */
/* 1 */ V(10, 2, 1),
/* 0101 1100 ... */
/* 0 */ V(10, 1, 1), /* 342 */
/* 1 */ V(6, 8, 1),
/* 0101 1101 ... */
/* 0 */ V(8, 6, 1), /* 344 */
/* 1 */ V(7, 7, 1),
/* 0101 1110 ... */
/* 0 */ V(4, 9, 1), /* 346 */
/* 1 */ V(9, 4, 1),
/* 0101 1111 ... */
/* 0 */ V(3, 9, 1), /* 348 */
/* 1 */ V(9, 3, 1),
/* 0110 0000 ... */
/* 0 */ V(5, 8, 1), /* 350 */
/* 1 */ V(8, 5, 1),
/* 0110 0001 ... */
/* 0 */ V(2, 9, 1), /* 352 */
/* 1 */ V(6, 7, 1),
/* 0110 0010 ... */
/* 0 */ V(7, 6, 1), /* 354 */
/* 1 */ V(9, 2, 1),
/* 0110 0011 ... */
/* 0 */ V(1, 9, 1), /* 356 */
/* 1 */ V(9, 1, 1),
/* 0110 0100 ... */
/* 0 */ V(4, 8, 1), /* 358 */
/* 1 */ V(8, 4, 1),
/* 0110 0101 ... */
/* 0 */ V(5, 7, 1), /* 360 */
/* 1 */ V(7, 5, 1),
/* 0110 0110 ... */
/* 0 */ V(3, 8, 1), /* 362 */
/* 1 */ V(8, 3, 1),
/* 0110 0111 ... */
/* 0 */ V(6, 6, 1), /* 364 */
/* 1 */ V(2, 8, 1),
/* 0110 1000 ... */
/* 0 */ V(8, 2, 1), /* 366 */
/* 1 */ V(1, 8, 1),
/* 0110 1001 ... */
/* 0 */ V(4, 7, 1), /* 368 */
/* 1 */ V(7, 4, 1),
/* 0110 1010 ... */
/* 00 */ V(8, 1, 1), /* 370 */
/* 01 */ V(8, 1, 1),
/* 10 */ V(0, 8, 2),
/* 11 */ V(8, 0, 2),
/* 0110 1011 ... */
/* 0 */ V(5, 6, 1), /* 374 */
/* 1 */ V(6, 5, 1),
/* 0110 1100 ... */
/* 00 */ V(1, 7, 1), /* 376 */
/* 01 */ V(1, 7, 1),
/* 10 */ V(0, 7, 2),
/* 11 */ V(7, 0, 2),
/* 0110 1110 ... */
/* 0 */ V(3, 7, 1), /* 380 */
/* 1 */ V(2, 7, 1),
/* 0111 1100 ... */
/* 0 */ V(0, 6, 1), /* 382 */
/* 1 */ V(6, 0, 1),
/* 1000 0011 ... */
/* 0 */ V(0, 5, 1), /* 384 */
/* 1 */ V(5, 0, 1)
};
# undef V
# undef PTR
/* external tables */
union huffquad const *const mad_huff_quad_table[2] = { hufftabA, hufftabB };
struct hufftable const mad_huff_pair_table[32] = {
/* 0 */ { hufftab0, 0, 0 },
/* 1 */ { hufftab1, 0, 3 },
/* 2 */ { hufftab2, 0, 3 },
/* 3 */ { hufftab3, 0, 3 },
/* 4 */ { 0 /* not used */ },
/* 5 */ { hufftab5, 0, 3 },
/* 6 */ { hufftab6, 0, 4 },
/* 7 */ { hufftab7, 0, 4 },
/* 8 */ { hufftab8, 0, 4 },
/* 9 */ { hufftab9, 0, 4 },
/* 10 */ { hufftab10, 0, 4 },
/* 11 */ { hufftab11, 0, 4 },
/* 12 */ { hufftab12, 0, 4 },
/* 13 */ { hufftab13, 0, 4 },
/* 14 */ { 0 /* not used */ },
/* 15 */ { hufftab15, 0, 4 },
/* 16 */ { hufftab16, 1, 4 },
/* 17 */ { hufftab16, 2, 4 },
/* 18 */ { hufftab16, 3, 4 },
/* 19 */ { hufftab16, 4, 4 },
/* 20 */ { hufftab16, 6, 4 },
/* 21 */ { hufftab16, 8, 4 },
/* 22 */ { hufftab16, 10, 4 },
/* 23 */ { hufftab16, 13, 4 },
/* 24 */ { hufftab24, 4, 4 },
/* 25 */ { hufftab24, 5, 4 },
/* 26 */ { hufftab24, 6, 4 },
/* 27 */ { hufftab24, 7, 4 },
/* 28 */ { hufftab24, 8, 4 },
/* 29 */ { hufftab24, 9, 4 },
/* 30 */ { hufftab24, 11, 4 },
/* 31 */ { hufftab24, 13, 4 }
};
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: huffman.h,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifndef LIBMAD_HUFFMAN_H
# define LIBMAD_HUFFMAN_H
union huffquad {
struct {
unsigned short final : 1;
unsigned short bits : 3;
unsigned short offset : 12;
} ptr;
struct {
unsigned short final : 1;
unsigned short hlen : 3;
unsigned short v : 1;
unsigned short w : 1;
unsigned short x : 1;
unsigned short y : 1;
} value;
unsigned short final : 1;
};
union huffpair {
struct {
unsigned short final : 1;
unsigned short bits : 3;
unsigned short offset : 12;
} ptr;
struct {
unsigned short final : 1;
unsigned short hlen : 3;
unsigned short x : 4;
unsigned short y : 4;
} value;
unsigned short final : 1;
};
struct hufftable {
union huffpair const *table;
unsigned short linbits;
unsigned short startbits;
};
extern union huffquad const *const mad_huff_quad_table[2];
extern struct hufftable const mad_huff_pair_table[32];
# endif
/*****************************************************************************
* Copyright (C) 2000-2001 Andre McCurdy <armccurdy@yahoo.co.uk>
*
* This program is free software. you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation@ either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY, without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program@ if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*****************************************************************************
*
* Notes:
*
*
*****************************************************************************
*
* $Id: imdct_l_arm.S,v 1.1 2003/06/18 19:19:19 shank Exp $
*
* 2001/03/24: Andre McCurdy <armccurdy@yahoo.co.uk>
* - Corrected PIC unsafe loading of address of 'imdct36_long_karray'
*
* 2000/09/20: Robert Leslie <rob@mars.org>
* - Added a global symbol with leading underscore per suggestion of
* Simon Burge to support linking with the a.out format.
*
* 2000/09/15: Robert Leslie <rob@mars.org>
* - Fixed a small bug where flags were changed before a conditional branch.
*
* 2000/09/15: Andre McCurdy <armccurdy@yahoo.co.uk>
* - Applied Nicolas Pitre's rounding optimisation in all remaining places.
*
* 2000/09/09: Nicolas Pitre <nico@cam.org>
* - Optimized rounding + scaling operations.
*
* 2000/08/09: Andre McCurdy <armccurdy@yahoo.co.uk>
* - Original created.
*
****************************************************************************/
/*
On entry:
r0 = pointer to 18 element input array
r1 = pointer to 36 element output array
r2 = windowing block type
Stack frame created during execution of the function:
Initial Holds:
Stack
pointer
minus:
0
4 lr
8 r11
12 r10
16 r9
20 r8
24 r7
28 r6
32 r5
36 r4
40 r2 : windowing block type
44 ct00 high
48 ct00 low
52 ct01 high
56 ct01 low
60 ct04 high
64 ct04 low
68 ct06 high
72 ct06 low
76 ct05 high
80 ct05 low
84 ct03 high
88 ct03 low
92 -ct05 high
96 -ct05 low
100 -ct07 high
104 -ct07 low
108 ct07 high
112 ct07 low
116 ct02 high
120 ct02 low
*/
#define BLOCK_MODE_NORMAL 0
#define BLOCK_MODE_START 1
#define BLOCK_MODE_STOP 3
#define X0 0x00
#define X1 0x04
#define X2 0x08
#define X3 0x0C
#define X4 0x10
#define X5 0x14
#define X6 0x18
#define X7 0x1c
#define X8 0x20
#define X9 0x24
#define X10 0x28
#define X11 0x2c
#define X12 0x30
#define X13 0x34
#define X14 0x38
#define X15 0x3c
#define X16 0x40
#define X17 0x44
#define x0 0x00
#define x1 0x04
#define x2 0x08
#define x3 0x0C
#define x4 0x10
#define x5 0x14
#define x6 0x18
#define x7 0x1c
#define x8 0x20
#define x9 0x24
#define x10 0x28
#define x11 0x2c
#define x12 0x30
#define x13 0x34
#define x14 0x38
#define x15 0x3c
#define x16 0x40
#define x17 0x44
#define x18 0x48
#define x19 0x4c
#define x20 0x50
#define x21 0x54
#define x22 0x58
#define x23 0x5c
#define x24 0x60
#define x25 0x64
#define x26 0x68
#define x27 0x6c
#define x28 0x70
#define x29 0x74
#define x30 0x78
#define x31 0x7c
#define x32 0x80
#define x33 0x84
#define x34 0x88
#define x35 0x8c
#define K00 0x0ffc19fd
#define K01 0x00b2aa3e
#define K02 0x0fdcf549
#define K03 0x0216a2a2
#define K04 0x0f9ee890
#define K05 0x03768962
#define K06 0x0f426cb5
#define K07 0x04cfb0e2
#define K08 0x0ec835e8
#define K09 0x061f78aa
#define K10 0x0e313245
#define K11 0x07635284
#define K12 0x0d7e8807
#define K13 0x0898c779
#define K14 0x0cb19346
#define K15 0x09bd7ca0
#define K16 0x0bcbe352
#define K17 0x0acf37ad
#define minus_K02 0xf0230ab7
#define WL0 0x00b2aa3e
#define WL1 0x0216a2a2
#define WL2 0x03768962
#define WL3 0x04cfb0e2
#define WL4 0x061f78aa
#define WL5 0x07635284
#define WL6 0x0898c779
#define WL7 0x09bd7ca0
#define WL8 0x0acf37ad
#define WL9 0x0bcbe352
#define WL10 0x0cb19346
#define WL11 0x0d7e8807
#define WL12 0x0e313245
#define WL13 0x0ec835e8
#define WL14 0x0f426cb5
#define WL15 0x0f9ee890
#define WL16 0x0fdcf549
#define WL17 0x0ffc19fd
@*****************************************************************************
.text
.align
.global III_imdct_l
.global _III_imdct_l
III_imdct_l:
_III_imdct_l:
stmdb sp!, { r2, r4 - r11, lr } @ all callee saved regs, plus arg3
ldr r4, =K08 @ r4 = K08
ldr r5, =K09 @ r5 = K09
ldr r8, [r0, #X4] @ r8 = X4
ldr r9, [r0, #X13] @ r9 = X13
rsb r6, r4, #0 @ r6 = -K08
rsb r7, r5, #0 @ r7 = -K09
smull r2, r3, r4, r8 @ r2..r3 = (X4 * K08)
smlal r2, r3, r5, r9 @ r2..r3 = (X4 * K08) + (X13 * K09) = ct01
smull r10, lr, r8, r5 @ r10..lr = (X4 * K09)
smlal r10, lr, r9, r6 @ r10..lr = (X4 * K09) + (X13 * -K08) = ct00
ldr r8, [r0, #X7] @ r8 = X7
ldr r9, [r0, #X16] @ r9 = X16
stmdb sp!, { r2, r3, r10, lr } @ stack ct00_h, ct00_l, ct01_h, ct01_l
add r8, r8, r9 @ r8 = (X7 + X16)
ldr r9, [r0, #X1] @ r9 = X1
smlal r2, r3, r6, r8 @ r2..r3 = ct01 + ((X7 + X16) * -K08)
smlal r2, r3, r7, r9 @ r2..r3 += (X1 * -K09)
ldr r7, [r0, #X10] @ r7 = X10
rsbs r10, r10, #0
rsc lr, lr, #0 @ r10..lr = -ct00
smlal r2, r3, r5, r7 @ r2..r3 += (X10 * K09) = ct06
smlal r10, lr, r9, r6 @ r10..lr = -ct00 + ( X1 * -K08)
smlal r10, lr, r8, r5 @ r10..lr += ((X7 + X16) * K09)
smlal r10, lr, r7, r4 @ r10..lr += ( X10 * K08) = ct04
stmdb sp!, { r2, r3, r10, lr } @ stack ct04_h, ct04_l, ct06_h, ct06_l
@----
ldr r7, [r0, #X0]
ldr r8, [r0, #X11]
ldr r9, [r0, #X12]
sub r7, r7, r8
sub r7, r7, r9 @ r7 = (X0 - X11 -X12) = ct14
ldr r9, [r0, #X3]
ldr r8, [r0, #X8]
ldr r11, [r0, #X15]
sub r8, r8, r9
add r8, r8, r11 @ r8 = (X8 - X3 + X15) = ct16
add r11, r7, r8 @ r11 = ct14 + ct16 = ct18
smlal r2, r3, r6, r11 @ r2..r3 = ct06 + ((X0 - X11 - X3 + X15 + X8 - X12) * -K08)
ldr r6, [r0, #X2]
ldr r9, [r0, #X9]
ldr r12, [r0, #X14]
sub r6, r6, r9
sub r6, r6, r12 @ r6 = (X2 - X9 - X14) = ct15
ldr r9, [r0, #X5]
ldr r12, [r0, #X6]
sub r9, r9, r12
ldr r12, [r0, #X17]
sub r9, r9, r12 @ r9 = (X5 - X6 - X17) = ct17
add r12, r9, r6 @ r12 = ct15 + ct17 = ct19
smlal r2, r3, r5, r12 @ r2..r3 += ((X2 - X9 + X5 - X6 - X17 - X14) * K09)
smlal r10, lr, r11, r5 @ r10..lr = ct04 + (ct18 * K09)
smlal r10, lr, r12, r4 @ r10..lr = ct04 + (ct18 * K09) + (ct19 * K08)
movs r2, r2, lsr #28
adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3
str r2, [r1, #x22] @ store result x22
movs r10, r10, lsr #28
adc r10, r10, lr, lsl #4 @ r10 = bits[59..28] of r10..lr
str r10, [r1, #x4] @ store result x4
@----
ldmia sp, { r2, r3, r4, r5 } @ r2..r3 = ct06, r4..r5 = ct04 (dont update sp)
@ r2..r3 = ct06
@ r4..r5 = ct04
@ r6 = ct15
@ r7 = ct14
@ r8 = ct16
@ r9 = ct17
@ r10 = .
@ r11 = .
@ r12 = .
@ lr = .
ldr r10, =K03 @ r10 = K03
ldr lr, =K15 @ lr = K15
smlal r2, r3, r10, r7 @ r2..r3 = ct06 + (ct14 * K03)
smlal r4, r5, lr, r7 @ r4..r5 = ct04 + (ct14 * K15)
ldr r12, =K14 @ r12 = K14
rsb r10, r10, #0 @ r10 = -K03
smlal r2, r3, lr, r6 @ r2..r3 += (ct15 * K15)
smlal r4, r5, r10, r6 @ r4..r5 += (ct15 * -K03)
smlal r2, r3, r12, r8 @ r2..r3 += (ct16 * K14)
ldr r11, =minus_K02 @ r11 = -K02
rsb r12, r12, #0 @ r12 = -K14
smlal r4, r5, r12, r9 @ r4..r5 += (ct17 * -K14)
smlal r2, r3, r11, r9 @ r2..r3 += (ct17 * -K02)
smlal r4, r5, r11, r8 @ r4..r5 += (ct16 * -K02)
movs r2, r2, lsr #28
adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3
str r2, [r1, #x7] @ store result x7
movs r4, r4, lsr #28
adc r4, r4, r5, lsl #4 @ r4 = bits[59..28] of r4..r5
str r4, [r1, #x1] @ store result x1
@----
ldmia sp, { r2, r3, r4, r5 } @ r2..r3 = ct06, r4..r5 = ct04 (dont update sp)
@ r2..r3 = ct06
@ r4..r5 = ct04
@ r6 = ct15
@ r7 = ct14
@ r8 = ct16
@ r9 = ct17
@ r10 = -K03
@ r11 = -K02
@ r12 = -K14
@ lr = K15
rsbs r2, r2, #0
rsc r3, r3, #0 @ r2..r3 = -ct06
smlal r2, r3, r12, r7 @ r2..r3 = -ct06 + (ct14 * -K14)
smlal r2, r3, r10, r8 @ r2..r3 += (ct16 * -K03)
smlal r4, r5, r12, r6 @ r4..r5 = ct04 + (ct15 * -K14)
smlal r4, r5, r10, r9 @ r4..r5 += (ct17 * -K03)
smlal r4, r5, lr, r8 @ r4..r5 += (ct16 * K15)
smlal r4, r5, r11, r7 @ r4..r5 += (ct14 * -K02)
rsb lr, lr, #0 @ lr = -K15
rsb r11, r11, #0 @ r11 = K02
smlal r2, r3, lr, r9 @ r2..r3 += (ct17 * -K15)
smlal r2, r3, r11, r6 @ r2..r3 += (ct15 * K02)
movs r4, r4, lsr #28
adc r4, r4, r5, lsl #4 @ r4 = bits[59..28] of r4..r5
str r4, [r1, #x25] @ store result x25
movs r2, r2, lsr #28
adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3
str r2, [r1, #x19] @ store result x19
@----
ldr r2, [sp, #16] @ r2 = ct01_l
ldr r3, [sp, #20] @ r3 = ct01_h
ldr r6, [r0, #X1]
ldr r8, [r0, #X7]
ldr r9, [r0, #X10]
ldr r7, [r0, #X16]
rsbs r2, r2, #0
rsc r3, r3, #0 @ r2..r3 = -ct01
mov r4, r2
mov r5, r3 @ r4..r5 = -ct01
@ r2..r3 = -ct01
@ r4..r5 = -ct01
@ r6 = X1
@ r7 = X16
@ r8 = X7
@ r9 = X10
@ r10 = -K03
@ r11 = K02
@ r12 = -K14
@ lr = -K15
smlal r4, r5, r12, r7 @ r4..r5 = -ct01 + (X16 * -K14)
smlal r2, r3, lr, r9 @ r2..r3 = -ct01 + (X10 * -K15)
smlal r4, r5, r10, r8 @ r4..r5 += (X7 * -K03)
smlal r2, r3, r10, r7 @ r2..r3 += (X16 * -K03)
smlal r4, r5, r11, r9 @ r4..r5 += (X10 * K02)
smlal r2, r3, r12, r8 @ r2..r3 += (X7 * -K14)
rsb lr, lr, #0 @ lr = K15
rsb r11, r11, #0 @ r11 = -K02
smlal r4, r5, lr, r6 @ r4..r5 += (X1 * K15) = ct05
smlal r2, r3, r11, r6 @ r2..r3 += (X1 * -K02) = ct03
stmdb sp!, { r2, r3, r4, r5 } @ stack ct05_h, ct05_l, ct03_h, ct03_l
rsbs r4, r4, #0
rsc r5, r5, #0 @ r4..r5 = -ct05
stmdb sp!, { r4, r5 } @ stack -ct05_h, -ct05_l
ldr r2, [sp, #48] @ r2 = ct00_l
ldr r3, [sp, #52] @ r3 = ct00_h
rsb r10, r10, #0 @ r10 = K03
rsbs r4, r2, #0
rsc r5, r3, #0 @ r4..r5 = -ct00
@ r2..r3 = ct00
@ r4..r5 = -ct00
@ r6 = X1
@ r7 = X16
@ r8 = X7
@ r9 = X10
@ r10 = K03
@ r11 = -K02
@ r12 = -K14
@ lr = K15
smlal r4, r5, r10, r6 @ r4..r5 = -ct00 + (X1 * K03)
smlal r2, r3, r10, r9 @ r2..r3 = ct00 + (X10 * K03)
smlal r4, r5, r12, r9 @ r4..r5 += (X10 * -K14)
smlal r2, r3, r12, r6 @ r2..r3 += (X1 * -K14)
smlal r4, r5, r11, r7 @ r4..r5 += (X16 * -K02)
smlal r4, r5, lr, r8 @ r4..r5 += (X7 * K15) = ct07
rsb lr, lr, #0 @ lr = -K15
rsb r11, r11, #0 @ r11 = K02
smlal r2, r3, r11, r8 @ r2..r3 += (X7 * K02)
smlal r2, r3, lr, r7 @ r2..r3 += (X16 * -K15) = ct02
rsbs r6, r4, #0
rsc r7, r5, #0 @ r6..r7 = -ct07
stmdb sp!, { r2 - r7 } @ stack -ct07_h, -ct07_l, ct07_h, ct07_l, ct02_h, ct02_l
@----
add r2, pc, #(imdct36_long_karray-.-8) @ r2 = base address of Knn array (PIC safe ?)
loop:
ldr r12, [r0, #X0]
ldmia r2!, { r5 - r11 } @ first 7 words from Karray element
smull r3, r4, r5, r12 @ sum = (Kxx * X0)
ldr r12, [r0, #X2]
ldr r5, [r0, #X3]
smlal r3, r4, r6, r12 @ sum += (Kxx * X2)
ldr r12, [r0, #X5]
ldr r6, [r0, #X6]
smlal r3, r4, r7, r5 @ sum += (Kxx * X3)
smlal r3, r4, r8, r12 @ sum += (Kxx * X5)
ldr r12, [r0, #X8]
ldr r5, [r0, #X9]
smlal r3, r4, r9, r6 @ sum += (Kxx * X6)
smlal r3, r4, r10, r12 @ sum += (Kxx * X8)
smlal r3, r4, r11, r5 @ sum += (Kxx * X9)
ldmia r2!, { r5 - r10 } @ final 6 words from Karray element
ldr r11, [r0, #X11]
ldr r12, [r0, #X12]
smlal r3, r4, r5, r11 @ sum += (Kxx * X11)
ldr r11, [r0, #X14]
ldr r5, [r0, #X15]
smlal r3, r4, r6, r12 @ sum += (Kxx * X12)
smlal r3, r4, r7, r11 @ sum += (Kxx * X14)
ldr r11, [r0, #X17]
smlal r3, r4, r8, r5 @ sum += (Kxx * X15)
smlal r3, r4, r9, r11 @ sum += (Kxx * X17)
add r5, sp, r10, lsr #16 @ create index back into stack for required ctxx
ldmia r5, { r6, r7 } @ r6..r7 = ctxx
mov r8, r10, lsl #16 @ push ctxx index off the top end
adds r3, r3, r6 @ add low words
adc r4, r4, r7 @ add high words, with carry
movs r3, r3, lsr #28
adc r3, r3, r4, lsl #4 @ r3 = bits[59..28] of r3..r4
str r3, [r1, r8, lsr #24] @ push completion flag off the bottom end
movs r8, r8, lsl #8 @ push result location index off the top end
beq loop @ loop back if completion flag not set
b imdct_l_windowing @ branch to windowing stage if looping finished
imdct36_long_karray:
.word K17, -K13, K10, -K06, -K05, K01, -K00, K04, -K07, K11, K12, -K16, 0x00000000
.word K13, K07, K16, K01, K10, -K05, K04, -K11, K00, -K17, K06, -K12, 0x00200800
.word K11, K17, K05, K12, -K01, K06, -K07, K00, -K13, K04, -K16, K10, 0x00200c00
.word K07, K00, -K12, K05, -K16, -K10, K11, -K17, K04, K13, K01, K06, 0x00001400
.word K05, K10, -K00, -K17, K07, -K13, K12, K06, -K16, K01, -K11, -K04, 0x00181800
.word K01, K05, -K07, -K11, K13, K17, -K16, -K12, K10, K06, -K04, -K00, 0x00102000
.word -K16, K12, -K11, K07, K04, -K00, -K01, K05, -K06, K10, K13, -K17, 0x00284800
.word -K12, K06, K17, -K00, -K11, K04, K05, -K10, K01, K16, -K07, -K13, 0x00085000
.word -K10, K16, K04, -K13, -K00, K07, K06, -K01, -K12, -K05, K17, K11, 0x00105400
.word -K06, -K01, K13, K04, K17, -K11, -K10, -K16, -K05, K12, K00, K07, 0x00185c00
.word -K04, -K11, -K01, K16, K06, K12, K13, -K07, -K17, -K00, -K10, -K05, 0x00006000
.word -K00, -K04, -K06, -K10, -K12, -K16, -K17, -K13, -K11, -K07, -K05, -K01, 0x00206801
@----
@-------------------------------------------------------------------------
@----
imdct_l_windowing:
ldr r11, [sp, #80] @ fetch function parameter 3 from out of the stack
ldmia r1!, { r0, r2 - r9 } @ load 9 words from x0, update pointer
@ r0 = x0
@ r1 = &x[9]
@ r2 = x1
@ r3 = x2
@ r4 = x3
@ r5 = x4
@ r6 = x5
@ r7 = x6
@ r8 = x7
@ r9 = x8
@ r10 = .
@ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block)
@ r12 = .
@ lr = .
cmp r11, #BLOCK_MODE_STOP @ setup flags
rsb r10, r0, #0 @ r10 = -x0 (DONT change flags !!)
beq stop_block_x0_to_x17
@ start and normal blocks are treated the same for x[0]..x[17]
normal_block_x0_to_x17:
ldr r12, =WL9 @ r12 = window_l[9]
rsb r0, r9, #0 @ r0 = -x8
rsb r9, r2, #0 @ r9 = -x1
rsb r2, r8, #0 @ r2 = -x7
rsb r8, r3, #0 @ r8 = -x2
rsb r3, r7, #0 @ r3 = -x6
rsb r7, r4, #0 @ r7 = -x3
rsb r4, r6, #0 @ r4 = -x5
rsb r6, r5, #0 @ r6 = -x4
@ r0 = -x8
@ r1 = &x[9]
@ r2 = -x7
@ r3 = -x6
@ r4 = -x5
@ r5 = .
@ r6 = -x4
@ r7 = -x3
@ r8 = -x2
@ r9 = -x1
@ r10 = -x0
@ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block)
@ r12 = window_l[9]
@ lr = .
smull r5, lr, r12, r0 @ r5..lr = (window_l[9] * (x[9] == -x[8]))
ldr r12, =WL10 @ r12 = window_l[10]
movs r5, r5, lsr #28
adc r0, r5, lr, lsl #4 @ r0 = bits[59..28] of windowed x9
smull r5, lr, r12, r2 @ r5..lr = (window_l[10] * (x[10] == -x[7]))
ldr r12, =WL11 @ r12 = window_l[11]
movs r5, r5, lsr #28
adc r2, r5, lr, lsl #4 @ r2 = bits[59..28] of windowed x10
smull r5, lr, r12, r3 @ r5..lr = (window_l[11] * (x[11] == -x[6]))
ldr r12, =WL12 @ r12 = window_l[12]
movs r5, r5, lsr #28
adc r3, r5, lr, lsl #4 @ r3 = bits[59..28] of windowed x11
smull r5, lr, r12, r4 @ r5..lr = (window_l[12] * (x[12] == -x[5]))
ldr r12, =WL13 @ r12 = window_l[13]
movs r5, r5, lsr #28
adc r4, r5, lr, lsl #4 @ r4 = bits[59..28] of windowed x12
smull r5, lr, r12, r6 @ r5..lr = (window_l[13] * (x[13] == -x[4]))
ldr r12, =WL14 @ r12 = window_l[14]
movs r5, r5, lsr #28
adc r6, r5, lr, lsl #4 @ r6 = bits[59..28] of windowed x13
smull r5, lr, r12, r7 @ r5..lr = (window_l[14] * (x[14] == -x[3]))
ldr r12, =WL15 @ r12 = window_l[15]
movs r5, r5, lsr #28
adc r7, r5, lr, lsl #4 @ r7 = bits[59..28] of windowed x14
smull r5, lr, r12, r8 @ r5..lr = (window_l[15] * (x[15] == -x[2]))
ldr r12, =WL16 @ r12 = window_l[16]
movs r5, r5, lsr #28
adc r8, r5, lr, lsl #4 @ r8 = bits[59..28] of windowed x15
smull r5, lr, r12, r9 @ r5..lr = (window_l[16] * (x[16] == -x[1]))
ldr r12, =WL17 @ r12 = window_l[17]
movs r5, r5, lsr #28
adc r9, r5, lr, lsl #4 @ r9 = bits[59..28] of windowed x16
smull r5, lr, r12, r10 @ r5..lr = (window_l[17] * (x[17] == -x[0]))
ldr r12, =WL0 @ r12 = window_l[0]
movs r5, r5, lsr #28
adc r10, r5, lr, lsl #4 @ r10 = bits[59..28] of windowed x17
stmia r1, { r0, r2 - r4, r6 - r10 } @ store windowed x[9] .. x[17]
ldmdb r1!, { r0, r2 - r9 } @ load 9 words downto (and including) x0
smull r10, lr, r12, r0 @ r10..lr = (window_l[0] * x[0])
ldr r12, =WL1 @ r12 = window_l[1]
movs r10, r10, lsr #28
adc r0, r10, lr, lsl #4 @ r0 = bits[59..28] of windowed x0
smull r10, lr, r12, r2 @ r10..lr = (window_l[1] * x[1])
ldr r12, =WL2 @ r12 = window_l[2]
movs r10, r10, lsr #28
adc r2, r10, lr, lsl #4 @ r2 = bits[59..28] of windowed x1
smull r10, lr, r12, r3 @ r10..lr = (window_l[2] * x[2])
ldr r12, =WL3 @ r12 = window_l[3]
movs r10, r10, lsr #28
adc r3, r10, lr, lsl #4 @ r3 = bits[59..28] of windowed x2
smull r10, lr, r12, r4 @ r10..lr = (window_l[3] * x[3])
ldr r12, =WL4 @ r12 = window_l[4]
movs r10, r10, lsr #28
adc r4, r10, lr, lsl #4 @ r4 = bits[59..28] of windowed x3
smull r10, lr, r12, r5 @ r10..lr = (window_l[4] * x[4])
ldr r12, =WL5 @ r12 = window_l[5]
movs r10, r10, lsr #28
adc r5, r10, lr, lsl #4 @ r5 = bits[59..28] of windowed x4
smull r10, lr, r12, r6 @ r10..lr = (window_l[5] * x[5])
ldr r12, =WL6 @ r12 = window_l[6]
movs r10, r10, lsr #28
adc r6, r10, lr, lsl #4 @ r6 = bits[59..28] of windowed x5
smull r10, lr, r12, r7 @ r10..lr = (window_l[6] * x[6])
ldr r12, =WL7 @ r12 = window_l[7]
movs r10, r10, lsr #28
adc r7, r10, lr, lsl #4 @ r7 = bits[59..28] of windowed x6
smull r10, lr, r12, r8 @ r10..lr = (window_l[7] * x[7])
ldr r12, =WL8 @ r12 = window_l[8]
movs r10, r10, lsr #28
adc r8, r10, lr, lsl #4 @ r8 = bits[59..28] of windowed x7
smull r10, lr, r12, r9 @ r10..lr = (window_l[8] * x[8])
movs r10, r10, lsr #28
adc r9, r10, lr, lsl #4 @ r9 = bits[59..28] of windowed x8
stmia r1, { r0, r2 - r9 } @ store windowed x[0] .. x[8]
cmp r11, #BLOCK_MODE_START
beq start_block_x18_to_x35
@----
normal_block_x18_to_x35:
ldr r11, =WL3 @ r11 = window_l[3]
ldr r12, =WL4 @ r12 = window_l[4]
add r1, r1, #(18*4) @ r1 = &x[18]
ldmia r1!, { r0, r2 - r4, r6 - r10 } @ load 9 words from x18, update pointer
@ r0 = x18
@ r1 = &x[27]
@ r2 = x19
@ r3 = x20
@ r4 = x21
@ r5 = .
@ r6 = x22
@ r7 = x23
@ r8 = x24
@ r9 = x25
@ r10 = x26
@ r11 = window_l[3]
@ r12 = window_l[4]
@ lr = .
smull r5, lr, r12, r6 @ r5..lr = (window_l[4] * (x[22] == x[31]))
movs r5, r5, lsr #28
adc r5, r5, lr, lsl #4 @ r5 = bits[59..28] of windowed x31
smull r6, lr, r11, r4 @ r5..lr = (window_l[3] * (x[21] == x[32]))
ldr r12, =WL5 @ r12 = window_l[5]
movs r6, r6, lsr #28
adc r6, r6, lr, lsl #4 @ r6 = bits[59..28] of windowed x32
smull r4, lr, r12, r7 @ r4..lr = (window_l[5] * (x[23] == x[30]))
ldr r11, =WL1 @ r11 = window_l[1]
ldr r12, =WL2 @ r12 = window_l[2]
movs r4, r4, lsr #28
adc r4, r4, lr, lsl #4 @ r4 = bits[59..28] of windowed x30
smull r7, lr, r12, r3 @ r7..lr = (window_l[2] * (x[20] == x[33]))
ldr r12, =WL6 @ r12 = window_l[6]
movs r7, r7, lsr #28
adc r7, r7, lr, lsl #4 @ r7 = bits[59..28] of windowed x33
smull r3, lr, r12, r8 @ r3..lr = (window_l[6] * (x[24] == x[29]))
movs r3, r3, lsr #28
adc r3, r3, lr, lsl #4 @ r3 = bits[59..28] of windowed x29
smull r8, lr, r11, r2 @ r7..lr = (window_l[1] * (x[19] == x[34]))
ldr r12, =WL7 @ r12 = window_l[7]
ldr r11, =WL8 @ r11 = window_l[8]
movs r8, r8, lsr #28
adc r8, r8, lr, lsl #4 @ r8 = bits[59..28] of windowed x34
smull r2, lr, r12, r9 @ r7..lr = (window_l[7] * (x[25] == x[28]))
ldr r12, =WL0 @ r12 = window_l[0]
movs r2, r2, lsr #28
adc r2, r2, lr, lsl #4 @ r2 = bits[59..28] of windowed x28
smull r9, lr, r12, r0 @ r3..lr = (window_l[0] * (x[18] == x[35]))
movs r9, r9, lsr #28
adc r9, r9, lr, lsl #4 @ r9 = bits[59..28] of windowed x35
smull r0, lr, r11, r10 @ r7..lr = (window_l[8] * (x[26] == x[27]))
ldr r11, =WL16 @ r11 = window_l[16]
ldr r12, =WL17 @ r12 = window_l[17]
movs r0, r0, lsr #28
adc r0, r0, lr, lsl #4 @ r0 = bits[59..28] of windowed x27
stmia r1, { r0, r2 - r9 } @ store windowed x[27] .. x[35]
ldmdb r1!, { r0, r2 - r9 } @ load 9 words downto (and including) x18
smull r10, lr, r12, r0 @ r10..lr = (window_l[17] * x[18])
movs r10, r10, lsr #28
adc r0, r10, lr, lsl #4 @ r0 = bits[59..28] of windowed x0
smull r10, lr, r11, r2 @ r10..lr = (window_l[16] * x[19])
ldr r11, =WL14 @ r11 = window_l[14]
ldr r12, =WL15 @ r12 = window_l[15]
movs r10, r10, lsr #28
adc r2, r10, lr, lsl #4 @ r2 = bits[59..28] of windowed x1
smull r10, lr, r12, r3 @ r10..lr = (window_l[15] * x[20])
movs r10, r10, lsr #28
adc r3, r10, lr, lsl #4 @ r3 = bits[59..28] of windowed x2
smull r10, lr, r11, r4 @ r10..lr = (window_l[14] * x[21])
ldr r11, =WL12 @ r11 = window_l[12]
ldr r12, =WL13 @ r12 = window_l[13]
movs r10, r10, lsr #28
adc r4, r10, lr, lsl #4 @ r4 = bits[59..28] of windowed x3
smull r10, lr, r12, r5 @ r10..lr = (window_l[13] * x[22])
movs r10, r10, lsr #28
adc r5, r10, lr, lsl #4 @ r5 = bits[59..28] of windowed x4
smull r10, lr, r11, r6 @ r10..lr = (window_l[12] * x[23])
ldr r11, =WL10 @ r12 = window_l[10]
ldr r12, =WL11 @ r12 = window_l[11]
movs r10, r10, lsr #28
adc r6, r10, lr, lsl #4 @ r6 = bits[59..28] of windowed x5
smull r10, lr, r12, r7 @ r10..lr = (window_l[11] * x[24])
movs r10, r10, lsr #28
adc r7, r10, lr, lsl #4 @ r7 = bits[59..28] of windowed x6
smull r10, lr, r11, r8 @ r10..lr = (window_l[10] * x[25])
ldr r12, =WL9 @ r12 = window_l[9]
movs r10, r10, lsr #28
adc r8, r10, lr, lsl #4 @ r8 = bits[59..28] of windowed x7
smull r10, lr, r12, r9 @ r10..lr = (window_l[9] * x[26])
movs r10, r10, lsr #28
adc r9, r10, lr, lsl #4 @ r9 = bits[59..28] of windowed x8
stmia r1, { r0, r2 - r9 } @ store windowed x[18] .. x[26]
@----
@ NB there are 2 possible exits from this function - this is only one of them
@----
add sp, sp, #(21*4) @ return stack frame
ldmia sp!, { r4 - r11, pc } @ restore callee saved regs, and return
@----
stop_block_x0_to_x17:
@ r0 = x0
@ r1 = &x[9]
@ r2 = x1
@ r3 = x2
@ r4 = x3
@ r5 = x4
@ r6 = x5
@ r7 = x6
@ r8 = x7
@ r9 = x8
@ r10 = -x0
@ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block)
@ r12 = .
@ lr = .
rsb r0, r6, #0 @ r0 = -x5
rsb r6, r2, #0 @ r6 = -x1
rsb r2, r5, #0 @ r2 = -x4
rsb r5, r3, #0 @ r5 = -x2
rsb r3, r4, #0 @ r3 = -x3
add r1, r1, #(3*4) @ r1 = &x[12]
stmia r1, { r0, r2, r3, r5, r6, r10 } @ store unchanged x[12] .. x[17]
ldr r0, =WL1 @ r0 = window_l[1] == window_s[0]
rsb r10, r9, #0 @ r10 = -x8
rsb r12, r8, #0 @ r12 = -x7
rsb lr, r7, #0 @ lr = -x6
@ r0 = WL1
@ r1 = &x[12]
@ r2 = .
@ r3 = .
@ r4 = .
@ r5 = .
@ r6 = .
@ r7 = x6
@ r8 = x7
@ r9 = x8
@ r10 = -x8
@ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block)
@ r12 = -x7
@ lr = -x6
smull r5, r6, r0, r7 @ r5..r6 = (window_l[1] * x[6])
ldr r2, =WL4 @ r2 = window_l[4] == window_s[1]
movs r5, r5, lsr #28
adc r7, r5, r6, lsl #4 @ r7 = bits[59..28] of windowed x6
smull r5, r6, r2, r8 @ r5..r6 = (window_l[4] * x[7])
ldr r3, =WL7 @ r3 = window_l[7] == window_s[2]
movs r5, r5, lsr #28
adc r8, r5, r6, lsl #4 @ r8 = bits[59..28] of windowed x7
smull r5, r6, r3, r9 @ r5..r6 = (window_l[7] * x[8])
ldr r4, =WL10 @ r4 = window_l[10] == window_s[3]
movs r5, r5, lsr #28
adc r9, r5, r6, lsl #4 @ r9 = bits[59..28] of windowed x8
smull r5, r6, r4, r10 @ r5..r6 = (window_l[10] * (x[9] == -x[8]))
ldr r0, =WL13 @ r0 = window_l[13] == window_s[4]
movs r5, r5, lsr #28
adc r10, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9
smull r5, r6, r0, r12 @ r5..r6 = (window_l[13] * (x[10] == -x[7]))
ldr r2, =WL16 @ r2 = window_l[16] == window_s[5]
movs r5, r5, lsr #28
adc r12, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9
smull r5, r6, r2, lr @ r5..r6 = (window_l[16] * (x[11] == -x[6]))
ldr r0, =0x00
movs r5, r5, lsr #28
adc lr, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9
stmdb r1!, { r7 - r10, r12, lr } @ store windowed x[6] .. x[11]
ldr r5, =0x00
ldr r6, =0x00
ldr r2, =0x00
ldr r3, =0x00
ldr r4, =0x00
stmdb r1!, { r0, r2 - r6 } @ store windowed x[0] .. x[5]
b normal_block_x18_to_x35
@----
start_block_x18_to_x35:
ldr r4, =WL1 @ r0 = window_l[1] == window_s[0]
add r1, r1, #(24*4) @ r1 = &x[24]
ldmia r1, { r0, r2, r3 } @ load 3 words from x24, dont update pointer
@ r0 = x24
@ r1 = &x[24]
@ r2 = x25
@ r3 = x26
@ r4 = WL1
@ r5 = WL4
@ r6 = WL7
@ r7 = WL10
@ r8 = WL13
@ r9 = WL16
@ r10 = .
@ r11 = .
@ r12 = .
@ lr = .
ldr r5, =WL4 @ r5 = window_l[4] == window_s[1]
smull r10, r11, r4, r0 @ r10..r11 = (window_l[1] * (x[24] == x[29]))
ldr r6, =WL7 @ r6 = window_l[7] == window_s[2]
movs r10, r10, lsr #28
adc lr, r10, r11, lsl #4 @ lr = bits[59..28] of windowed x29
smull r10, r11, r5, r2 @ r10..r11 = (window_l[4] * (x[25] == x[28]))
ldr r7, =WL10 @ r7 = window_l[10] == window_s[3]
movs r10, r10, lsr #28
adc r12, r10, r11, lsl #4 @ r12 = bits[59..28] of windowed x28
smull r10, r11, r6, r3 @ r10..r11 = (window_l[7] * (x[26] == x[27]))
ldr r8, =WL13 @ r8 = window_l[13] == window_s[4]
movs r10, r10, lsr #28
adc r4, r10, r11, lsl #4 @ r4 = bits[59..28] of windowed x27
smull r10, r11, r7, r3 @ r10..r11 = (window_l[10] * x[26])
ldr r9, =WL16 @ r9 = window_l[16] == window_s[5]
movs r10, r10, lsr #28
adc r3, r10, r11, lsl #4 @ r3 = bits[59..28] of windowed x26
smull r10, r11, r8, r2 @ r10..r11 = (window_l[13] * x[25])
ldr r5, =0x00
movs r10, r10, lsr #28
adc r2, r10, r11, lsl #4 @ r2 = bits[59..28] of windowed x25
smull r10, r11, r9, r0 @ r10..r11 = (window_l[16] * x[24])
ldr r6, =0x00
movs r10, r10, lsr #28
adc r0, r10, r11, lsl #4 @ r0 = bits[59..28] of windowed x24
stmia r1!, { r0, r2, r3, r4, r12, lr } @ store windowed x[24] .. x[29]
ldr r7, =0x00
ldr r8, =0x00
ldr r9, =0x00
ldr r10, =0x00
stmia r1!, { r5 - r10 } @ store windowed x[30] .. x[35]
@----
@ NB there are 2 possible exits from this function - this is only one of them
@----
add sp, sp, #(21*4) @ return stack frame
ldmia sp!, { r4 - r11, pc } @ restore callee saved regs, and return
@----
@END
@----
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: imdct_s.dat,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
/* 0 */ { MAD_F(0x09bd7ca0) /* 0.608761429 */,
-MAD_F(0x0ec835e8) /* -0.923879533 */,
-MAD_F(0x0216a2a2) /* -0.130526192 */,
MAD_F(0x0fdcf549) /* 0.991444861 */,
-MAD_F(0x061f78aa) /* -0.382683432 */,
-MAD_F(0x0cb19346) /* -0.793353340 */ },
/* 6 */ { -MAD_F(0x0cb19346) /* -0.793353340 */,
MAD_F(0x061f78aa) /* 0.382683432 */,
MAD_F(0x0fdcf549) /* 0.991444861 */,
MAD_F(0x0216a2a2) /* 0.130526192 */,
-MAD_F(0x0ec835e8) /* -0.923879533 */,
-MAD_F(0x09bd7ca0) /* -0.608761429 */ },
/* 1 */ { MAD_F(0x061f78aa) /* 0.382683432 */,
-MAD_F(0x0ec835e8) /* -0.923879533 */,
MAD_F(0x0ec835e8) /* 0.923879533 */,
-MAD_F(0x061f78aa) /* -0.382683432 */,
-MAD_F(0x061f78aa) /* -0.382683432 */,
MAD_F(0x0ec835e8) /* 0.923879533 */ },
/* 7 */ { -MAD_F(0x0ec835e8) /* -0.923879533 */,
-MAD_F(0x061f78aa) /* -0.382683432 */,
MAD_F(0x061f78aa) /* 0.382683432 */,
MAD_F(0x0ec835e8) /* 0.923879533 */,
MAD_F(0x0ec835e8) /* 0.923879533 */,
MAD_F(0x061f78aa) /* 0.382683432 */ },
/* 2 */ { MAD_F(0x0216a2a2) /* 0.130526192 */,
-MAD_F(0x061f78aa) /* -0.382683432 */,
MAD_F(0x09bd7ca0) /* 0.608761429 */,
-MAD_F(0x0cb19346) /* -0.793353340 */,
MAD_F(0x0ec835e8) /* 0.923879533 */,
-MAD_F(0x0fdcf549) /* -0.991444861 */ },
/* 8 */ { -MAD_F(0x0fdcf549) /* -0.991444861 */,
-MAD_F(0x0ec835e8) /* -0.923879533 */,
-MAD_F(0x0cb19346) /* -0.793353340 */,
-MAD_F(0x09bd7ca0) /* -0.608761429 */,
-MAD_F(0x061f78aa) /* -0.382683432 */,
-MAD_F(0x0216a2a2) /* -0.130526192 */ }
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: layer12.c,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# ifdef HAVE_LIMITS_H
# include <limits.h>
# else
# define CHAR_BIT 8
# endif
# include "fixed.h"
# include "bit.h"
# include "stream.h"
# include "frame.h"
# include "layer12.h"
/*
* scalefactor table
* used in both Layer I and Layer II decoding
*/
static
mad_fixed_t const sf_table[63] = {
# include "sf_table.dat"
};
/* --- Layer I ------------------------------------------------------------- */
/* linear scaling table */
static
mad_fixed_t const linear_table[14] = {
MAD_F(0x15555555), /* 2^2 / (2^2 - 1) == 1.33333333333333 */
MAD_F(0x12492492), /* 2^3 / (2^3 - 1) == 1.14285714285714 */
MAD_F(0x11111111), /* 2^4 / (2^4 - 1) == 1.06666666666667 */
MAD_F(0x10842108), /* 2^5 / (2^5 - 1) == 1.03225806451613 */
MAD_F(0x10410410), /* 2^6 / (2^6 - 1) == 1.01587301587302 */
MAD_F(0x10204081), /* 2^7 / (2^7 - 1) == 1.00787401574803 */
MAD_F(0x10101010), /* 2^8 / (2^8 - 1) == 1.00392156862745 */
MAD_F(0x10080402), /* 2^9 / (2^9 - 1) == 1.00195694716243 */
MAD_F(0x10040100), /* 2^10 / (2^10 - 1) == 1.00097751710655 */
MAD_F(0x10020040), /* 2^11 / (2^11 - 1) == 1.00048851978505 */
MAD_F(0x10010010), /* 2^12 / (2^12 - 1) == 1.00024420024420 */
MAD_F(0x10008004), /* 2^13 / (2^13 - 1) == 1.00012208521548 */
MAD_F(0x10004001), /* 2^14 / (2^14 - 1) == 1.00006103888177 */
MAD_F(0x10002000) /* 2^15 / (2^15 - 1) == 1.00003051850948 */
};
/*
* NAME: I_sample()
* DESCRIPTION: decode one requantized Layer I sample from a bitstream
*/
static
mad_fixed_t I_sample(struct mad_bitptr *ptr, unsigned int nb)
{
mad_fixed_t sample;
sample = mad_bit_read(ptr, nb);
/* invert most significant bit, extend sign, then scale to fixed format */
sample ^= 1 << (nb - 1);
sample |= -(sample & (1 << (nb - 1)));
sample <<= MAD_F_FRACBITS - (nb - 1);
/* requantize the sample */
/* s'' = (2^nb / (2^nb - 1)) * (s''' + 2^(-nb + 1)) */
sample += MAD_F_ONE >> (nb - 1);
return mad_f_mul(sample, linear_table[nb - 2]);
/* s' = factor * s'' */
/* (to be performed by caller) */
}
/*
* NAME: layer->I()
* DESCRIPTION: decode a single Layer I frame
*/
int mad_layer_I(struct mad_stream *stream, struct mad_frame *frame)
{
struct mad_header *header = &frame->header;
unsigned int nch, bound, ch, s, sb, nb;
unsigned char allocation[2][32], scalefactor[2][32];
nch = MAD_NCHANNELS(header);
bound = 32;
if (header->mode == MAD_MODE_JOINT_STEREO) {
header->flags |= MAD_FLAG_I_STEREO;
bound = 4 + header->mode_extension * 4;
}
/* check CRC word */
if (header->flags & MAD_FLAG_PROTECTION) {
header->crc_check =
mad_bit_crc(stream->ptr, 4 * (bound * nch + (32 - bound)),
header->crc_check);
if (header->crc_check != header->crc_target &&
!(frame->options & MAD_OPTION_IGNORECRC)) {
stream->error = MAD_ERROR_BADCRC;
return -1;
}
}
/* decode bit allocations */
for (sb = 0; sb < bound; ++sb) {
for (ch = 0; ch < nch; ++ch) {
nb = mad_bit_read(&stream->ptr, 4);
if (nb == 15) {
stream->error = MAD_ERROR_BADBITALLOC;
return -1;
}
allocation[ch][sb] = nb ? nb + 1 : 0;
}
}
for (sb = bound; sb < 32; ++sb) {
nb = mad_bit_read(&stream->ptr, 4);
if (nb == 15) {
stream->error = MAD_ERROR_BADBITALLOC;
return -1;
}
allocation[0][sb] =
allocation[1][sb] = nb ? nb + 1 : 0;
}
/* decode scalefactors */
for (sb = 0; sb < 32; ++sb) {
for (ch = 0; ch < nch; ++ch) {
if (allocation[ch][sb]) {
scalefactor[ch][sb] = mad_bit_read(&stream->ptr, 6);
if (scalefactor[ch][sb] == 63) {
stream->error = MAD_ERROR_BADSCALEFACTOR;
return -1;
}
}
}
}
/* decode samples */
for (s = 0; s < 12; ++s) {
for (sb = 0; sb < bound; ++sb) {
for (ch = 0; ch < nch; ++ch) {
nb = allocation[ch][sb];
frame->sbsample[ch][s][sb] = nb ?
mad_f_mul(I_sample(&stream->ptr, nb),
sf_table[scalefactor[ch][sb]]) : 0;
}
}
for (sb = bound; sb < 32; ++sb) {
if ((nb = allocation[0][sb])) {
mad_fixed_t sample;
sample = I_sample(&stream->ptr, nb);
for (ch = 0; ch < nch; ++ch) {
frame->sbsample[ch][s][sb] =
mad_f_mul(sample, sf_table[scalefactor[ch][sb]]);
}
}
else {
for (ch = 0; ch < nch; ++ch)
frame->sbsample[ch][s][sb] = 0;
}
}
}
return 0;
}
/* --- Layer II ------------------------------------------------------------ */
/* possible quantization per subband table */
static
struct {
unsigned int sblimit;
unsigned char const offsets[30];
} const sbquant_table[5] = {
/* ISO/IEC 11172-3 Table B.2a */
{ 27, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, /* 0 */
3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0 } },
/* ISO/IEC 11172-3 Table B.2b */
{ 30, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, /* 1 */
3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0 } },
/* ISO/IEC 11172-3 Table B.2c */
{ 8, { 5, 5, 2, 2, 2, 2, 2, 2 } }, /* 2 */
/* ISO/IEC 11172-3 Table B.2d */
{ 12, { 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 } }, /* 3 */
/* ISO/IEC 13818-3 Table B.1 */
{ 30, { 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, /* 4 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }
};
/* bit allocation table */
static
struct {
unsigned short nbal;
unsigned short offset;
} const bitalloc_table[8] = {
{ 2, 0 }, /* 0 */
{ 2, 3 }, /* 1 */
{ 3, 3 }, /* 2 */
{ 3, 1 }, /* 3 */
{ 4, 2 }, /* 4 */
{ 4, 3 }, /* 5 */
{ 4, 4 }, /* 6 */
{ 4, 5 } /* 7 */
};
/* offsets into quantization class table */
static
unsigned char const offset_table[6][15] = {
{ 0, 1, 16 }, /* 0 */
{ 0, 1, 2, 3, 4, 5, 16 }, /* 1 */
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, /* 2 */
{ 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, /* 3 */
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 }, /* 4 */
{ 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 } /* 5 */
};
/* quantization class table */
static
struct quantclass {
unsigned short nlevels;
unsigned char group;
unsigned char bits;
mad_fixed_t C;
mad_fixed_t D;
} const qc_table[17] = {
# include "qc_table.dat"
};
/*
* NAME: II_samples()
* DESCRIPTION: decode three requantized Layer II samples from a bitstream
*/
static
void II_samples(struct mad_bitptr *ptr,
struct quantclass const *quantclass,
mad_fixed_t output[3])
{
unsigned int nb, s, sample[3];
if ((nb = quantclass->group)) {
unsigned int c, nlevels;
/* degrouping */
c = mad_bit_read(ptr, quantclass->bits);
nlevels = quantclass->nlevels;
for (s = 0; s < 3; ++s) {
sample[s] = c % nlevels;
c /= nlevels;
}
}
else {
nb = quantclass->bits;
for (s = 0; s < 3; ++s)
sample[s] = mad_bit_read(ptr, nb);
}
for (s = 0; s < 3; ++s) {
mad_fixed_t requantized;
/* invert most significant bit, extend sign, then scale to fixed format */
requantized = sample[s] ^ (1 << (nb - 1));
requantized |= -(requantized & (1 << (nb - 1)));
requantized <<= MAD_F_FRACBITS - (nb - 1);
/* requantize the sample */
/* s'' = C * (s''' + D) */
output[s] = mad_f_mul(requantized + quantclass->D, quantclass->C);
/* s' = factor * s'' */
/* (to be performed by caller) */
}
}
/*
* NAME: layer->II()
* DESCRIPTION: decode a single Layer II frame
*/
int mad_layer_II(struct mad_stream *stream, struct mad_frame *frame)
{
struct mad_header *header = &frame->header;
struct mad_bitptr start;
unsigned int index, sblimit, nbal, nch, bound, gr, ch, s, sb;
unsigned char const *offsets;
unsigned char allocation[2][32], scfsi[2][32], scalefactor[2][32][3];
mad_fixed_t samples[3];
nch = MAD_NCHANNELS(header);
if (header->flags & MAD_FLAG_LSF_EXT)
index = 4;
else {
switch (nch == 2 ? header->bitrate / 2 : header->bitrate) {
case 32000:
case 48000:
index = (header->samplerate == 32000) ? 3 : 2;
break;
case 56000:
case 64000:
case 80000:
index = 0;
break;
default:
index = (header->samplerate == 48000) ? 0 : 1;
}
}
sblimit = sbquant_table[index].sblimit;
offsets = sbquant_table[index].offsets;
bound = 32;
if (header->mode == MAD_MODE_JOINT_STEREO) {
header->flags |= MAD_FLAG_I_STEREO;
bound = 4 + header->mode_extension * 4;
}
if (bound > sblimit)
bound = sblimit;
start = stream->ptr;
/* decode bit allocations */
for (sb = 0; sb < bound; ++sb) {
nbal = bitalloc_table[offsets[sb]].nbal;
for (ch = 0; ch < nch; ++ch)
allocation[ch][sb] = mad_bit_read(&stream->ptr, nbal);
}
for (sb = bound; sb < sblimit; ++sb) {
nbal = bitalloc_table[offsets[sb]].nbal;
allocation[0][sb] =
allocation[1][sb] = mad_bit_read(&stream->ptr, nbal);
}
/* decode scalefactor selection info */
for (sb = 0; sb < sblimit; ++sb) {
for (ch = 0; ch < nch; ++ch) {
if (allocation[ch][sb])
scfsi[ch][sb] = mad_bit_read(&stream->ptr, 2);
}
}
/* check CRC word */
if (header->flags & MAD_FLAG_PROTECTION) {
header->crc_check =
mad_bit_crc(start, mad_bit_length(&start, &stream->ptr),
header->crc_check);
if (header->crc_check != header->crc_target &&
!(frame->options & MAD_OPTION_IGNORECRC)) {
stream->error = MAD_ERROR_BADCRC;
return -1;
}
}
/* decode scalefactors */
for (sb = 0; sb < sblimit; ++sb) {
for (ch = 0; ch < nch; ++ch) {
if (allocation[ch][sb]) {
scalefactor[ch][sb][0] = mad_bit_read(&stream->ptr, 6);
switch (scfsi[ch][sb]) {
case 2:
scalefactor[ch][sb][2] =
scalefactor[ch][sb][1] =
scalefactor[ch][sb][0];
break;
case 0:
scalefactor[ch][sb][1] = mad_bit_read(&stream->ptr, 6);
/* fall through */
case 1:
case 3:
scalefactor[ch][sb][2] = mad_bit_read(&stream->ptr, 6);
}
if (scfsi[ch][sb] & 1)
scalefactor[ch][sb][1] = scalefactor[ch][sb][scfsi[ch][sb] - 1];
if (scalefactor[ch][sb][0] == 63 ||
scalefactor[ch][sb][1] == 63 ||
scalefactor[ch][sb][2] == 63) {
stream->error = MAD_ERROR_BADSCALEFACTOR;
return -1;
}
}
}
}
/* decode samples */
for (gr = 0; gr < 12; ++gr) {
for (sb = 0; sb < bound; ++sb) {
for (ch = 0; ch < nch; ++ch) {
if ((index = allocation[ch][sb])) {
index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1];
II_samples(&stream->ptr, &qc_table[index], samples);
for (s = 0; s < 3; ++s) {
frame->sbsample[ch][3 * gr + s][sb] =
mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]);
}
}
else {
for (s = 0; s < 3; ++s)
frame->sbsample[ch][3 * gr + s][sb] = 0;
}
}
}
for (sb = bound; sb < sblimit; ++sb) {
if ((index = allocation[0][sb])) {
index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1];
II_samples(&stream->ptr, &qc_table[index], samples);
for (ch = 0; ch < nch; ++ch) {
for (s = 0; s < 3; ++s) {
frame->sbsample[ch][3 * gr + s][sb] =
mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]);
}
}
}
else {
for (ch = 0; ch < nch; ++ch) {
for (s = 0; s < 3; ++s)
frame->sbsample[ch][3 * gr + s][sb] = 0;
}
}
}
for (ch = 0; ch < nch; ++ch) {
for (s = 0; s < 3; ++s) {
for (sb = sblimit; sb < 32; ++sb)
frame->sbsample[ch][3 * gr + s][sb] = 0;
}
}
}
return 0;
}
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: layer12.h,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifndef LIBMAD_LAYER12_H
# define LIBMAD_LAYER12_H
# include "stream.h"
# include "frame.h"
int mad_layer_I(struct mad_stream *, struct mad_frame *);
int mad_layer_II(struct mad_stream *, struct mad_frame *);
# endif
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: layer3.c,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include <stdlib.h>
# include <string.h>
# ifdef HAVE_ASSERT_H
# include <assert.h>
# endif
# ifdef HAVE_LIMITS_H
# include <limits.h>
# else
# define CHAR_BIT 8
# endif
# include "fixed.h"
# include "bit.h"
# include "stream.h"
# include "frame.h"
# include "huffman.h"
# include "layer3.h"
/* --- Layer III ----------------------------------------------------------- */
enum {
count1table_select = 0x01,
scalefac_scale = 0x02,
preflag = 0x04,
mixed_block_flag = 0x08
};
enum {
I_STEREO = 0x1,
MS_STEREO = 0x2
};
struct sideinfo {
unsigned int main_data_begin;
unsigned int private_bits;
unsigned char scfsi[2];
struct granule {
struct channel {
/* from side info */
unsigned short part2_3_length;
unsigned short big_values;
unsigned short global_gain;
unsigned short scalefac_compress;
unsigned char flags;
unsigned char block_type;
unsigned char table_select[3];
unsigned char subblock_gain[3];
unsigned char region0_count;
unsigned char region1_count;
/* from main_data */
unsigned char scalefac[39]; /* scalefac_l and/or scalefac_s */
} ch[2];
} gr[2];
};
/*
* scalefactor bit lengths
* derived from section 2.4.2.7 of ISO/IEC 11172-3
*/
static
struct {
unsigned char slen1;
unsigned char slen2;
} const sflen_table[16] = {
{ 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 },
{ 3, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 },
{ 2, 1 }, { 2, 2 }, { 2, 3 }, { 3, 1 },
{ 3, 2 }, { 3, 3 }, { 4, 2 }, { 4, 3 }
};
/*
* number of LSF scalefactor band values
* derived from section 2.4.3.2 of ISO/IEC 13818-3
*/
static
unsigned char const nsfb_table[6][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 } }
};
/*
* MPEG-1 scalefactor band widths
* derived from Table B.8 of ISO/IEC 11172-3
*/
static
unsigned char const sfb_48000_long[] = {
4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10,
12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192
};
static
unsigned char const sfb_44100_long[] = {
4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10,
12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158
};
static
unsigned char const sfb_32000_long[] = {
4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12,
16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26
};
static
unsigned char const sfb_48000_short[] = {
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
6, 6, 6, 6, 6, 10, 10, 10, 12, 12, 12, 14, 14,
14, 16, 16, 16, 20, 20, 20, 26, 26, 26, 66, 66, 66
};
static
unsigned char const sfb_44100_short[] = {
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14,
14, 18, 18, 18, 22, 22, 22, 30, 30, 30, 56, 56, 56
};
static
unsigned char const sfb_32000_short[] = {
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
6, 6, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20,
20, 26, 26, 26, 34, 34, 34, 42, 42, 42, 12, 12, 12
};
static
unsigned char const sfb_48000_mixed[] = {
/* long */ 4, 4, 4, 4, 4, 4, 6, 6,
/* short */ 4, 4, 4, 6, 6, 6, 6, 6, 6, 10,
10, 10, 12, 12, 12, 14, 14, 14, 16, 16,
16, 20, 20, 20, 26, 26, 26, 66, 66, 66
};
static
unsigned char const sfb_44100_mixed[] = {
/* long */ 4, 4, 4, 4, 4, 4, 6, 6,
/* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 10,
10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
18, 22, 22, 22, 30, 30, 30, 56, 56, 56
};
static
unsigned char const sfb_32000_mixed[] = {
/* long */ 4, 4, 4, 4, 4, 4, 6, 6,
/* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 12,
12, 12, 16, 16, 16, 20, 20, 20, 26, 26,
26, 34, 34, 34, 42, 42, 42, 12, 12, 12
};
/*
* MPEG-2 scalefactor band widths
* derived from Table B.2 of ISO/IEC 13818-3
*/
static
unsigned char const sfb_24000_long[] = {
6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
18, 22, 26, 32, 38, 46, 54, 62, 70, 76, 36
};
static
unsigned char const sfb_22050_long[] = {
6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54
};
# define sfb_16000_long sfb_22050_long
static
unsigned char const sfb_24000_short[] = {
4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8,
8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
18, 24, 24, 24, 32, 32, 32, 44, 44, 44, 12, 12, 12
};
static
unsigned char const sfb_22050_short[] = {
4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6,
6, 6, 8, 8, 8, 10, 10, 10, 14, 14, 14, 18, 18,
18, 26, 26, 26, 32, 32, 32, 42, 42, 42, 18, 18, 18
};
static
unsigned char const sfb_16000_short[] = {
4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8,
8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
18, 24, 24, 24, 30, 30, 30, 40, 40, 40, 18, 18, 18
};
static
unsigned char const sfb_24000_mixed[] = {
/* long */ 6, 6, 6, 6, 6, 6,
/* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12,
12, 12, 14, 14, 14, 18, 18, 18, 24, 24,
24, 32, 32, 32, 44, 44, 44, 12, 12, 12
};
static
unsigned char const sfb_22050_mixed[] = {
/* long */ 6, 6, 6, 6, 6, 6,
/* short */ 6, 6, 6, 6, 6, 6, 8, 8, 8, 10,
10, 10, 14, 14, 14, 18, 18, 18, 26, 26,
26, 32, 32, 32, 42, 42, 42, 18, 18, 18
};
static
unsigned char const sfb_16000_mixed[] = {
/* long */ 6, 6, 6, 6, 6, 6,
/* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12,
12, 12, 14, 14, 14, 18, 18, 18, 24, 24,
24, 30, 30, 30, 40, 40, 40, 18, 18, 18
};
/*
* MPEG 2.5 scalefactor band widths
* derived from public sources
*/
# define sfb_12000_long sfb_16000_long
# define sfb_11025_long sfb_12000_long
static
unsigned char const sfb_8000_long[] = {
12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32,
40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2
};
# define sfb_12000_short sfb_16000_short
# define sfb_11025_short sfb_12000_short
static
unsigned char const sfb_8000_short[] = {
8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 16,
16, 16, 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36,
36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26
};
# define sfb_12000_mixed sfb_16000_mixed
# define sfb_11025_mixed sfb_12000_mixed
/* the 8000 Hz short block scalefactor bands do not break after the first 36
frequency lines, so this is probably wrong */
static
unsigned char const sfb_8000_mixed[] = {
/* long */ 12, 12, 12,
/* short */ 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16,
20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, 36,
2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26
};
static
struct {
unsigned char const *l;
unsigned char const *s;
unsigned char const *m;
} const sfbwidth_table[9] = {
{ sfb_48000_long, sfb_48000_short, sfb_48000_mixed },
{ sfb_44100_long, sfb_44100_short, sfb_44100_mixed },
{ sfb_32000_long, sfb_32000_short, sfb_32000_mixed },
{ sfb_24000_long, sfb_24000_short, sfb_24000_mixed },
{ sfb_22050_long, sfb_22050_short, sfb_22050_mixed },
{ sfb_16000_long, sfb_16000_short, sfb_16000_mixed },
{ sfb_12000_long, sfb_12000_short, sfb_12000_mixed },
{ sfb_11025_long, sfb_11025_short, sfb_11025_mixed },
{ sfb_8000_long, sfb_8000_short, sfb_8000_mixed }
};
/*
* scalefactor band preemphasis (used only when preflag is set)
* derived from Table B.6 of ISO/IEC 11172-3
*/
static
unsigned char const pretab[22] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0
};
/*
* table for requantization
*
* rq_table[x].mantissa * 2^(rq_table[x].exponent) = x^(4/3)
*/
static
struct fixedfloat {
unsigned long mantissa : 27;
unsigned short exponent : 5;
} const rq_table[8207] = {
# include "rq_table.dat"
};
/*
* fractional powers of two
* used for requantization and joint stereo decoding
*
* root_table[3 + x] = 2^(x/4)
*/
static
mad_fixed_t const root_table[7] = {
MAD_F(0x09837f05) /* 2^(-3/4) == 0.59460355750136 */,
MAD_F(0x0b504f33) /* 2^(-2/4) == 0.70710678118655 */,
MAD_F(0x0d744fcd) /* 2^(-1/4) == 0.84089641525371 */,
MAD_F(0x10000000) /* 2^( 0/4) == 1.00000000000000 */,
MAD_F(0x1306fe0a) /* 2^(+1/4) == 1.18920711500272 */,
MAD_F(0x16a09e66) /* 2^(+2/4) == 1.41421356237310 */,
MAD_F(0x1ae89f99) /* 2^(+3/4) == 1.68179283050743 */
};
/*
* coefficients for aliasing reduction
* derived from Table B.9 of ISO/IEC 11172-3
*
* c[] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 }
* cs[i] = 1 / sqrt(1 + c[i]^2)
* ca[i] = c[i] / sqrt(1 + c[i]^2)
*/
static
mad_fixed_t const cs[8] = {
+MAD_F(0x0db84a81) /* +0.857492926 */, +MAD_F(0x0e1b9d7f) /* +0.881741997 */,
+MAD_F(0x0f31adcf) /* +0.949628649 */, +MAD_F(0x0fbba815) /* +0.983314592 */,
+MAD_F(0x0feda417) /* +0.995517816 */, +MAD_F(0x0ffc8fc8) /* +0.999160558 */,
+MAD_F(0x0fff964c) /* +0.999899195 */, +MAD_F(0x0ffff8d3) /* +0.999993155 */
};
static
mad_fixed_t const ca[8] = {
-MAD_F(0x083b5fe7) /* -0.514495755 */, -MAD_F(0x078c36d2) /* -0.471731969 */,
-MAD_F(0x05039814) /* -0.313377454 */, -MAD_F(0x02e91dd1) /* -0.181913200 */,
-MAD_F(0x0183603a) /* -0.094574193 */, -MAD_F(0x00a7cb87) /* -0.040965583 */,
-MAD_F(0x003a2847) /* -0.014198569 */, -MAD_F(0x000f27b4) /* -0.003699975 */
};
/*
* IMDCT coefficients for short blocks
* derived from section 2.4.3.4.10.2 of ISO/IEC 11172-3
*
* imdct_s[i/even][k] = cos((PI / 24) * (2 * (i / 2) + 7) * (2 * k + 1))
* imdct_s[i /odd][k] = cos((PI / 24) * (2 * (6 + (i-1)/2) + 7) * (2 * k + 1))
*/
static
mad_fixed_t const imdct_s[6][6] = {
# include "imdct_s.dat"
};
# if !defined(ASO_IMDCT)
/*
* windowing coefficients for long blocks
* derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3
*
* window_l[i] = sin((PI / 36) * (i + 1/2))
*/
static
mad_fixed_t const window_l[36] = {
MAD_F(0x00b2aa3e) /* 0.043619387 */, MAD_F(0x0216a2a2) /* 0.130526192 */,
MAD_F(0x03768962) /* 0.216439614 */, MAD_F(0x04cfb0e2) /* 0.300705800 */,
MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x07635284) /* 0.461748613 */,
MAD_F(0x0898c779) /* 0.537299608 */, MAD_F(0x09bd7ca0) /* 0.608761429 */,
MAD_F(0x0acf37ad) /* 0.675590208 */, MAD_F(0x0bcbe352) /* 0.737277337 */,
MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x0d7e8807) /* 0.843391446 */,
MAD_F(0x0e313245) /* 0.887010833 */, MAD_F(0x0ec835e8) /* 0.923879533 */,
MAD_F(0x0f426cb5) /* 0.953716951 */, MAD_F(0x0f9ee890) /* 0.976296007 */,
MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ffc19fd) /* 0.999048222 */,
MAD_F(0x0ffc19fd) /* 0.999048222 */, MAD_F(0x0fdcf549) /* 0.991444861 */,
MAD_F(0x0f9ee890) /* 0.976296007 */, MAD_F(0x0f426cb5) /* 0.953716951 */,
MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0e313245) /* 0.887010833 */,
MAD_F(0x0d7e8807) /* 0.843391446 */, MAD_F(0x0cb19346) /* 0.793353340 */,
MAD_F(0x0bcbe352) /* 0.737277337 */, MAD_F(0x0acf37ad) /* 0.675590208 */,
MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0898c779) /* 0.537299608 */,
MAD_F(0x07635284) /* 0.461748613 */, MAD_F(0x061f78aa) /* 0.382683432 */,
MAD_F(0x04cfb0e2) /* 0.300705800 */, MAD_F(0x03768962) /* 0.216439614 */,
MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x00b2aa3e) /* 0.043619387 */,
};
# endif /* ASO_IMDCT */
/*
* windowing coefficients for short blocks
* derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3
*
* window_s[i] = sin((PI / 12) * (i + 1/2))
*/
static
mad_fixed_t const window_s[12] = {
MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x061f78aa) /* 0.382683432 */,
MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0cb19346) /* 0.793353340 */,
MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0fdcf549) /* 0.991444861 */,
MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ec835e8) /* 0.923879533 */,
MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x09bd7ca0) /* 0.608761429 */,
MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0216a2a2) /* 0.130526192 */,
};
/*
* coefficients for intensity stereo processing
* derived from section 2.4.3.4.9.3 of ISO/IEC 11172-3
*
* is_ratio[i] = tan(i * (PI / 12))
* is_table[i] = is_ratio[i] / (1 + is_ratio[i])
*/
static
mad_fixed_t const is_table[7] = {
MAD_F(0x00000000) /* 0.000000000 */,
MAD_F(0x0361962f) /* 0.211324865 */,
MAD_F(0x05db3d74) /* 0.366025404 */,
MAD_F(0x08000000) /* 0.500000000 */,
MAD_F(0x0a24c28c) /* 0.633974596 */,
MAD_F(0x0c9e69d1) /* 0.788675135 */,
MAD_F(0x10000000) /* 1.000000000 */
};
/*
* coefficients for LSF intensity stereo processing
* derived from section 2.4.3.2 of ISO/IEC 13818-3
*
* is_lsf_table[0][i] = (1 / sqrt(sqrt(2)))^(i + 1)
* is_lsf_table[1][i] = (1 / sqrt(2))^(i + 1)
*/
static
mad_fixed_t const is_lsf_table[2][15] = {
{
MAD_F(0x0d744fcd) /* 0.840896415 */,
MAD_F(0x0b504f33) /* 0.707106781 */,
MAD_F(0x09837f05) /* 0.594603558 */,
MAD_F(0x08000000) /* 0.500000000 */,
MAD_F(0x06ba27e6) /* 0.420448208 */,
MAD_F(0x05a8279a) /* 0.353553391 */,
MAD_F(0x04c1bf83) /* 0.297301779 */,
MAD_F(0x04000000) /* 0.250000000 */,
MAD_F(0x035d13f3) /* 0.210224104 */,
MAD_F(0x02d413cd) /* 0.176776695 */,
MAD_F(0x0260dfc1) /* 0.148650889 */,
MAD_F(0x02000000) /* 0.125000000 */,
MAD_F(0x01ae89fa) /* 0.105112052 */,
MAD_F(0x016a09e6) /* 0.088388348 */,
MAD_F(0x01306fe1) /* 0.074325445 */
}, {
MAD_F(0x0b504f33) /* 0.707106781 */,
MAD_F(0x08000000) /* 0.500000000 */,
MAD_F(0x05a8279a) /* 0.353553391 */,
MAD_F(0x04000000) /* 0.250000000 */,
MAD_F(0x02d413cd) /* 0.176776695 */,
MAD_F(0x02000000) /* 0.125000000 */,
MAD_F(0x016a09e6) /* 0.088388348 */,
MAD_F(0x01000000) /* 0.062500000 */,
MAD_F(0x00b504f3) /* 0.044194174 */,
MAD_F(0x00800000) /* 0.031250000 */,
MAD_F(0x005a827a) /* 0.022097087 */,
MAD_F(0x00400000) /* 0.015625000 */,
MAD_F(0x002d413d) /* 0.011048543 */,
MAD_F(0x00200000) /* 0.007812500 */,
MAD_F(0x0016a09e) /* 0.005524272 */
}
};
/*
* NAME: III_sideinfo()
* DESCRIPTION: decode frame side information from a bitstream
*/
static
enum mad_error III_sideinfo(struct mad_bitptr *ptr, unsigned int nch,
int lsf, struct sideinfo *si,
unsigned int *data_bitlen,
unsigned int *priv_bitlen)
{
unsigned int ngr, gr, ch, i;
enum mad_error result = MAD_ERROR_NONE;
*data_bitlen = 0;
*priv_bitlen = lsf ? ((nch == 1) ? 1 : 2) : ((nch == 1) ? 5 : 3);
si->main_data_begin = mad_bit_read(ptr, lsf ? 8 : 9);
si->private_bits = mad_bit_read(ptr, *priv_bitlen);
ngr = 1;
if (!lsf) {
ngr = 2;
for (ch = 0; ch < nch; ++ch)
si->scfsi[ch] = mad_bit_read(ptr, 4);
}
for (gr = 0; gr < ngr; ++gr) {
struct granule *granule = &si->gr[gr];
for (ch = 0; ch < nch; ++ch) {
struct channel *channel = &granule->ch[ch];
channel->part2_3_length = mad_bit_read(ptr, 12);
channel->big_values = mad_bit_read(ptr, 9);
channel->global_gain = mad_bit_read(ptr, 8);
channel->scalefac_compress = mad_bit_read(ptr, lsf ? 9 : 4);
*data_bitlen += channel->part2_3_length;
if (channel->big_values > 288 && result == 0)
result = MAD_ERROR_BADBIGVALUES;
channel->flags = 0;
/* window_switching_flag */
if (mad_bit_read(ptr, 1)) {
channel->block_type = mad_bit_read(ptr, 2);
if (channel->block_type == 0 && result == 0)
result = MAD_ERROR_BADBLOCKTYPE;
if (!lsf && channel->block_type == 2 && si->scfsi[ch] && result == 0)
result = MAD_ERROR_BADSCFSI;
channel->region0_count = 7;
channel->region1_count = 36;
if (mad_bit_read(ptr, 1))
channel->flags |= mixed_block_flag;
else if (channel->block_type == 2)
channel->region0_count = 8;
for (i = 0; i < 2; ++i)
channel->table_select[i] = mad_bit_read(ptr, 5);
# if defined(DEBUG)
channel->table_select[2] = 4; /* not used */
# endif
for (i = 0; i < 3; ++i)
channel->subblock_gain[i] = mad_bit_read(ptr, 3);
}
else {
channel->block_type = 0;
for (i = 0; i < 3; ++i)
channel->table_select[i] = mad_bit_read(ptr, 5);
channel->region0_count = mad_bit_read(ptr, 4);
channel->region1_count = mad_bit_read(ptr, 3);
}
/* [preflag,] scalefac_scale, count1table_select */
channel->flags |= mad_bit_read(ptr, lsf ? 2 : 3);
}
}
return result;
}
/*
* NAME: III_scalefactors_lsf()
* DESCRIPTION: decode channel scalefactors for LSF from a bitstream
*/
static
unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr,
struct channel *channel,
struct channel *gr1ch, int mode_extension)
{
struct mad_bitptr start;
unsigned int scalefac_compress, index, slen[4], part, n, i;
unsigned char const *nsfb;
start = *ptr;
scalefac_compress = channel->scalefac_compress;
index = (channel->block_type == 2) ?
((channel->flags & mixed_block_flag) ? 2 : 1) : 0;
if (!((mode_extension & I_STEREO) && gr1ch)) {
if (scalefac_compress < 400) {
slen[0] = (scalefac_compress >> 4) / 5;
slen[1] = (scalefac_compress >> 4) % 5;
slen[2] = (scalefac_compress % 16) >> 2;
slen[3] = scalefac_compress % 4;
nsfb = nsfb_table[0][index];
}
else if (scalefac_compress < 500) {
scalefac_compress -= 400;
slen[0] = (scalefac_compress >> 2) / 5;
slen[1] = (scalefac_compress >> 2) % 5;
slen[2] = scalefac_compress % 4;
slen[3] = 0;
nsfb = nsfb_table[1][index];
}
else {
scalefac_compress -= 500;
slen[0] = scalefac_compress / 3;
slen[1] = scalefac_compress % 3;
slen[2] = 0;
slen[3] = 0;
channel->flags |= preflag;
nsfb = nsfb_table[2][index];
}
n = 0;
for (part = 0; part < 4; ++part) {
for (i = 0; i < nsfb[part]; ++i)
channel->scalefac[n++] = mad_bit_read(ptr, slen[part]);
}
while (n < 39)
channel->scalefac[n++] = 0;
}
else { /* (mode_extension & I_STEREO) && gr1ch (i.e. ch == 1) */
scalefac_compress >>= 1;
if (scalefac_compress < 180) {
slen[0] = scalefac_compress / 36;
slen[1] = (scalefac_compress % 36) / 6;
slen[2] = (scalefac_compress % 36) % 6;
slen[3] = 0;
nsfb = nsfb_table[3][index];
}
else if (scalefac_compress < 244) {
scalefac_compress -= 180;
slen[0] = (scalefac_compress % 64) >> 4;
slen[1] = (scalefac_compress % 16) >> 2;
slen[2] = scalefac_compress % 4;
slen[3] = 0;
nsfb = nsfb_table[4][index];
}
else {
scalefac_compress -= 244;
slen[0] = scalefac_compress / 3;
slen[1] = scalefac_compress % 3;
slen[2] = 0;
slen[3] = 0;
nsfb = nsfb_table[5][index];
}
n = 0;
for (part = 0; part < 4; ++part) {
unsigned int max, is_pos;
max = (1 << slen[part]) - 1;
for (i = 0; i < nsfb[part]; ++i) {
is_pos = mad_bit_read(ptr, slen[part]);
channel->scalefac[n] = is_pos;
gr1ch->scalefac[n++] = (is_pos == max);
}
}
while (n < 39) {
channel->scalefac[n] = 0;
gr1ch->scalefac[n++] = 0; /* apparently not illegal */
}
}
return mad_bit_length(&start, ptr);
}
/*
* NAME: III_scalefactors()
* DESCRIPTION: decode channel scalefactors of one granule from a bitstream
*/
static
unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel,
struct channel const *gr0ch, unsigned int scfsi)
{
struct mad_bitptr start;
unsigned int slen1, slen2, sfbi;
start = *ptr;
slen1 = sflen_table[channel->scalefac_compress].slen1;
slen2 = sflen_table[channel->scalefac_compress].slen2;
if (channel->block_type == 2) {
unsigned int nsfb;
sfbi = 0;
nsfb = (channel->flags & mixed_block_flag) ? 8 + 3 * 3 : 6 * 3;
while (nsfb--)
channel->scalefac[sfbi++] = mad_bit_read(ptr, slen1);
nsfb = 6 * 3;
while (nsfb--)
channel->scalefac[sfbi++] = mad_bit_read(ptr, slen2);
nsfb = 1 * 3;
while (nsfb--)
channel->scalefac[sfbi++] = 0;
}
else { /* channel->block_type != 2 */
if (scfsi & 0x8) {
for (sfbi = 0; sfbi < 6; ++sfbi)
channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
}
else {
for (sfbi = 0; sfbi < 6; ++sfbi)
channel->scalefac[sfbi] = mad_bit_read(ptr, slen1);
}
if (scfsi & 0x4) {
for (sfbi = 6; sfbi < 11; ++sfbi)
channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
}
else {
for (sfbi = 6; sfbi < 11; ++sfbi)
channel->scalefac[sfbi] = mad_bit_read(ptr, slen1);
}
if (scfsi & 0x2) {
for (sfbi = 11; sfbi < 16; ++sfbi)
channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
}
else {
for (sfbi = 11; sfbi < 16; ++sfbi)
channel->scalefac[sfbi] = mad_bit_read(ptr, slen2);
}
if (scfsi & 0x1) {
for (sfbi = 16; sfbi < 21; ++sfbi)
channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
}
else {
for (sfbi = 16; sfbi < 21; ++sfbi)
channel->scalefac[sfbi] = mad_bit_read(ptr, slen2);
}
channel->scalefac[21] = 0;
}
return mad_bit_length(&start, ptr);
}
/*
* The Layer III formula for requantization and scaling is defined by
* section 2.4.3.4.7.1 of ISO/IEC 11172-3, as follows:
*
* long blocks:
* xr[i] = sign(is[i]) * abs(is[i])^(4/3) *
* 2^((1/4) * (global_gain - 210)) *
* 2^-(scalefac_multiplier *
* (scalefac_l[sfb] + preflag * pretab[sfb]))
*
* short blocks:
* xr[i] = sign(is[i]) * abs(is[i])^(4/3) *
* 2^((1/4) * (global_gain - 210 - 8 * subblock_gain[w])) *
* 2^-(scalefac_multiplier * scalefac_s[sfb][w])
*
* where:
* scalefac_multiplier = (scalefac_scale + 1) / 2
*
* The routines III_exponents() and III_requantize() facilitate this
* calculation.
*/
/*
* NAME: III_exponents()
* DESCRIPTION: calculate scalefactor exponents
*/
static
void III_exponents(struct channel const *channel,
unsigned char const *sfbwidth, signed int exponents[39])
{
signed int gain;
unsigned int scalefac_multiplier, sfbi;
gain = (signed int) channel->global_gain - 210;
scalefac_multiplier = (channel->flags & scalefac_scale) ? 2 : 1;
if (channel->block_type == 2) {
unsigned int l;
signed int gain0, gain1, gain2;
sfbi = l = 0;
if (channel->flags & mixed_block_flag) {
unsigned int premask;
premask = (channel->flags & preflag) ? ~0 : 0;
/* long block subbands 0-1 */
while (l < 36) {
exponents[sfbi] = gain -
(signed int) ((channel->scalefac[sfbi] + (pretab[sfbi] & premask)) <<
scalefac_multiplier);
l += sfbwidth[sfbi++];
}
}
/* this is probably wrong for 8000 Hz short/mixed blocks */
gain0 = gain - 8 * (signed int) channel->subblock_gain[0];
gain1 = gain - 8 * (signed int) channel->subblock_gain[1];
gain2 = gain - 8 * (signed int) channel->subblock_gain[2];
while (l < 576) {
exponents[sfbi + 0] = gain0 -
(signed int) (channel->scalefac[sfbi + 0] << scalefac_multiplier);
exponents[sfbi + 1] = gain1 -
(signed int) (channel->scalefac[sfbi + 1] << scalefac_multiplier);
exponents[sfbi + 2] = gain2 -
(signed int) (channel->scalefac[sfbi + 2] << scalefac_multiplier);
l += 3 * sfbwidth[sfbi];
sfbi += 3;
}
}
else { /* channel->block_type != 2 */
if (channel->flags & preflag) {
for (sfbi = 0; sfbi < 22; ++sfbi) {
exponents[sfbi] = gain -
(signed int) ((channel->scalefac[sfbi] + pretab[sfbi]) <<
scalefac_multiplier);
}
}
else {
for (sfbi = 0; sfbi < 22; ++sfbi) {
exponents[sfbi] = gain -
(signed int) (channel->scalefac[sfbi] << scalefac_multiplier);
}
}
}
}
/*
* NAME: III_requantize()
* DESCRIPTION: requantize one (positive) value
*/
static
mad_fixed_t III_requantize(unsigned int value, signed int exp)
{
mad_fixed_t requantized;
signed int frac;
struct fixedfloat const *power;
frac = exp % 4; /* assumes sign(frac) == sign(exp) */
exp /= 4;
power = &rq_table[value];
requantized = power->mantissa;
exp += power->exponent;
if (exp < 0) {
if (-exp >= sizeof(mad_fixed_t) * CHAR_BIT) {
/* underflow */
requantized = 0;
}
else {
requantized += 1L << (-exp - 1);
requantized >>= -exp;
}
}
else {
if (exp >= 5) {
/* overflow */
# if defined(DEBUG)
fprintf(stderr, "requantize overflow (%f * 2^%d)\n",
mad_f_todouble(requantized), exp);
# endif
requantized = MAD_F_MAX;
}
else
requantized <<= exp;
}
return frac ? mad_f_mul(requantized, root_table[3 + frac]) : requantized;
}
/* we must take care that sz >= bits and sz < sizeof(long) lest bits == 0 */
# define MASK(cache, sz, bits) \
(((cache) >> ((sz) - (bits))) & ((1 << (bits)) - 1))
# define MASK1BIT(cache, sz) \
((cache) & (1 << ((sz) - 1)))
/*
* NAME: III_huffdecode()
* DESCRIPTION: decode Huffman code words of one channel of one granule
*/
static
enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576],
struct channel *channel,
unsigned char const *sfbwidth,
unsigned int part2_length)
{
signed int exponents[39], exp;
signed int const *expptr;
struct mad_bitptr peek;
signed int bits_left, cachesz;
register mad_fixed_t *xrptr;
mad_fixed_t const *sfbound;
register unsigned long bitcache;
bits_left = (signed) channel->part2_3_length - (signed) part2_length;
if (bits_left < 0)
return MAD_ERROR_BADPART3LEN;
III_exponents(channel, sfbwidth, exponents);
peek = *ptr;
mad_bit_skip(ptr, bits_left);
/* align bit reads to byte boundaries */
cachesz = mad_bit_bitsleft(&peek);
cachesz += ((32 - 1 - 24) + (24 - cachesz)) & ~7;
bitcache = mad_bit_read(&peek, cachesz);
bits_left -= cachesz;
xrptr = &xr[0];
/* big_values */
{
unsigned int region, rcount;
struct hufftable const *entry;
union huffpair const *table;
unsigned int linbits, startbits, big_values, reqhits;
mad_fixed_t reqcache[16];
sfbound = xrptr + *sfbwidth++;
rcount = channel->region0_count + 1;
entry = &mad_huff_pair_table[channel->table_select[region = 0]];
table = entry->table;
linbits = entry->linbits;
startbits = entry->startbits;
if (table == 0)
return MAD_ERROR_BADHUFFTABLE;
expptr = &exponents[0];
exp = *expptr++;
reqhits = 0;
big_values = channel->big_values;
while (big_values-- && cachesz + bits_left > 0) {
union huffpair const *pair;
unsigned int clumpsz, value;
register mad_fixed_t requantized;
if (xrptr == sfbound) {
sfbound += *sfbwidth++;
/* change table if region boundary */
if (--rcount == 0) {
if (region == 0)
rcount = channel->region1_count + 1;
else
rcount = 0; /* all remaining */
entry = &mad_huff_pair_table[channel->table_select[++region]];
table = entry->table;
linbits = entry->linbits;
startbits = entry->startbits;
if (table == 0)
return MAD_ERROR_BADHUFFTABLE;
}
if (exp != *expptr) {
exp = *expptr;
reqhits = 0;
}
++expptr;
}
if (cachesz < 21) {
unsigned int bits;
bits = ((32 - 1 - 21) + (21 - cachesz)) & ~7;
bitcache = (bitcache << bits) | mad_bit_read(&peek, bits);
cachesz += bits;
bits_left -= bits;
}
/* hcod (0..19) */
clumpsz = startbits;
pair = &table[MASK(bitcache, cachesz, clumpsz)];
while (!pair->final) {
cachesz -= clumpsz;
clumpsz = pair->ptr.bits;
pair = &table[pair->ptr.offset + MASK(bitcache, cachesz, clumpsz)];
}
cachesz -= pair->value.hlen;
if (linbits) {
/* x (0..14) */
value = pair->value.x;
switch (value) {
case 0:
xrptr[0] = 0;
break;
case 15:
if (cachesz < linbits + 2) {
bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
cachesz += 16;
bits_left -= 16;
}
value += MASK(bitcache, cachesz, linbits);
cachesz -= linbits;
requantized = III_requantize(value, exp);
goto x_final;
default:
if (reqhits & (1 << value))
requantized = reqcache[value];
else {
reqhits |= (1 << value);
requantized = reqcache[value] = III_requantize(value, exp);
}
x_final:
xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
-requantized : requantized;
}
/* y (0..14) */
value = pair->value.y;
switch (value) {
case 0:
xrptr[1] = 0;
break;
case 15:
if (cachesz < linbits + 1) {
bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
cachesz += 16;
bits_left -= 16;
}
value += MASK(bitcache, cachesz, linbits);
cachesz -= linbits;
requantized = III_requantize(value, exp);
goto y_final;
default:
if (reqhits & (1 << value))
requantized = reqcache[value];
else {
reqhits |= (1 << value);
requantized = reqcache[value] = III_requantize(value, exp);
}
y_final:
xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
-requantized : requantized;
}
}
else {
/* x (0..1) */
value = pair->value.x;
if (value == 0)
xrptr[0] = 0;
else {
if (reqhits & (1 << value))
requantized = reqcache[value];
else {
reqhits |= (1 << value);
requantized = reqcache[value] = III_requantize(value, exp);
}
xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
-requantized : requantized;
}
/* y (0..1) */
value = pair->value.y;
if (value == 0)
xrptr[1] = 0;
else {
if (reqhits & (1 << value))
requantized = reqcache[value];
else {
reqhits |= (1 << value);
requantized = reqcache[value] = III_requantize(value, exp);
}
xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
-requantized : requantized;
}
}
xrptr += 2;
}
}
if (cachesz + bits_left < 0)
return MAD_ERROR_BADHUFFDATA; /* big_values overrun */
/* count1 */
{
union huffquad const *table;
register mad_fixed_t requantized;
table = mad_huff_quad_table[channel->flags & count1table_select];
requantized = III_requantize(1, exp);
while (cachesz + bits_left > 0 && xrptr <= &xr[572]) {
union huffquad const *quad;
/* hcod (1..6) */
if (cachesz < 10) {
bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
cachesz += 16;
bits_left -= 16;
}
quad = &table[MASK(bitcache, cachesz, 4)];
/* quad tables guaranteed to have at most one extra lookup */
if (!quad->final) {
cachesz -= 4;
quad = &table[quad->ptr.offset +
MASK(bitcache, cachesz, quad->ptr.bits)];
}
cachesz -= quad->value.hlen;
if (xrptr == sfbound) {
sfbound += *sfbwidth++;
if (exp != *expptr) {
exp = *expptr;
requantized = III_requantize(1, exp);
}
++expptr;
}
/* v (0..1) */
xrptr[0] = quad->value.v ?
(MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
/* w (0..1) */
xrptr[1] = quad->value.w ?
(MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
xrptr += 2;
if (xrptr == sfbound) {
sfbound += *sfbwidth++;
if (exp != *expptr) {
exp = *expptr;
requantized = III_requantize(1, exp);
}
++expptr;
}
/* x (0..1) */
xrptr[0] = quad->value.x ?
(MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
/* y (0..1) */
xrptr[1] = quad->value.y ?
(MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
xrptr += 2;
}
if (cachesz + bits_left < 0) {
# if 0 && defined(DEBUG)
fprintf(stderr, "huffman count1 overrun (%d bits)\n",
-(cachesz + bits_left));
# endif
/* technically the bitstream is misformatted, but apparently
some encoders are just a bit sloppy with stuffing bits */
xrptr -= 4;
}
}
assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT);
# if 0 && defined(DEBUG)
if (bits_left < 0)
fprintf(stderr, "read %d bits too many\n", -bits_left);
else if (cachesz + bits_left > 0)
fprintf(stderr, "%d stuffing bits\n", cachesz + bits_left);
# endif
/* rzero */
while (xrptr < &xr[576]) {
xrptr[0] = 0;
xrptr[1] = 0;
xrptr += 2;
}
return MAD_ERROR_NONE;
}
# undef MASK
# undef MASK1BIT
/*
* NAME: III_reorder()
* DESCRIPTION: reorder frequency lines of a short block into subband order
*/
static
void III_reorder(mad_fixed_t xr[576], struct channel const *channel,
unsigned char const sfbwidth[39])
{
mad_fixed_t tmp[32][3][6];
unsigned int sb, l, f, w, sbw[3], sw[3];
/* this is probably wrong for 8000 Hz mixed blocks */
sb = 0;
if (channel->flags & mixed_block_flag) {
sb = 2;
l = 0;
while (l < 36)
l += *sfbwidth++;
}
for (w = 0; w < 3; ++w) {
sbw[w] = sb;
sw[w] = 0;
}
f = *sfbwidth++;
w = 0;
for (l = 18 * sb; l < 576; ++l) {
if (f-- == 0) {
f = *sfbwidth++ - 1;
w = (w + 1) % 3;
}
tmp[sbw[w]][w][sw[w]++] = xr[l];
if (sw[w] == 6) {
sw[w] = 0;
++sbw[w];
}
}
memcpy(&xr[18 * sb], &tmp[sb], (576 - 18 * sb) * sizeof(mad_fixed_t));
}
/*
* NAME: III_stereo()
* DESCRIPTION: perform joint stereo processing on a granule
*/
static
enum mad_error III_stereo(mad_fixed_t xr[2][576],
struct granule const *granule,
struct mad_header *header,
unsigned char const *sfbwidth)
{
short modes[39];
unsigned int sfbi, l, n, i;
if (granule->ch[0].block_type !=
granule->ch[1].block_type ||
(granule->ch[0].flags & mixed_block_flag) !=
(granule->ch[1].flags & mixed_block_flag))
return MAD_ERROR_BADSTEREO;
for (i = 0; i < 39; ++i)
modes[i] = header->mode_extension;
/* intensity stereo */
if (header->mode_extension & I_STEREO) {
struct channel const *right_ch = &granule->ch[1];
mad_fixed_t const *right_xr = xr[1];
unsigned int is_pos;
header->flags |= MAD_FLAG_I_STEREO;
/* first determine which scalefactor bands are to be processed */
if (right_ch->block_type == 2) {
unsigned int lower, start, max, bound[3], w;
lower = start = max = bound[0] = bound[1] = bound[2] = 0;
sfbi = l = 0;
if (right_ch->flags & mixed_block_flag) {
while (l < 36) {
n = sfbwidth[sfbi++];
for (i = 0; i < n; ++i) {
if (right_xr[i]) {
lower = sfbi;
break;
}
}
right_xr += n;
l += n;
}
start = sfbi;
}
w = 0;
while (l < 576) {
n = sfbwidth[sfbi++];
for (i = 0; i < n; ++i) {
if (right_xr[i]) {
max = bound[w] = sfbi;
break;
}
}
right_xr += n;
l += n;
w = (w + 1) % 3;
}
if (max)
lower = start;
/* long blocks */
for (i = 0; i < lower; ++i)
modes[i] = header->mode_extension & ~I_STEREO;
/* short blocks */
w = 0;
for (i = start; i < max; ++i) {
if (i < bound[w])
modes[i] = header->mode_extension & ~I_STEREO;
w = (w + 1) % 3;
}
}
else { /* right_ch->block_type != 2 */
unsigned int bound;
bound = 0;
for (sfbi = l = 0; l < 576; l += n) {
n = sfbwidth[sfbi++];
for (i = 0; i < n; ++i) {
if (right_xr[i]) {
bound = sfbi;
break;
}
}
right_xr += n;
}
for (i = 0; i < bound; ++i)
modes[i] = header->mode_extension & ~I_STEREO;
}
/* now do the actual processing */
if (header->flags & MAD_FLAG_LSF_EXT) {
unsigned char const *illegal_pos = granule[1].ch[1].scalefac;
mad_fixed_t const *lsf_scale;
/* intensity_scale */
lsf_scale = is_lsf_table[right_ch->scalefac_compress & 0x1];
for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
n = sfbwidth[sfbi];
if (!(modes[sfbi] & I_STEREO))
continue;
if (illegal_pos[sfbi]) {
modes[sfbi] &= ~I_STEREO;
continue;
}
is_pos = right_ch->scalefac[sfbi];
for (i = 0; i < n; ++i) {
register mad_fixed_t left;
left = xr[0][l + i];
if (is_pos == 0)
xr[1][l + i] = left;
else {
register mad_fixed_t opposite;
opposite = mad_f_mul(left, lsf_scale[(is_pos - 1) / 2]);
if (is_pos & 1) {
xr[0][l + i] = opposite;
xr[1][l + i] = left;
}
else
xr[1][l + i] = opposite;
}
}
}
}
else { /* !(header->flags & MAD_FLAG_LSF_EXT) */
for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
n = sfbwidth[sfbi];
if (!(modes[sfbi] & I_STEREO))
continue;
is_pos = right_ch->scalefac[sfbi];
if (is_pos >= 7) { /* illegal intensity position */
modes[sfbi] &= ~I_STEREO;
continue;
}
for (i = 0; i < n; ++i) {
register mad_fixed_t left;
left = xr[0][l + i];
xr[0][l + i] = mad_f_mul(left, is_table[ is_pos]);
xr[1][l + i] = mad_f_mul(left, is_table[6 - is_pos]);
}
}
}
}
/* middle/side stereo */
if (header->mode_extension & MS_STEREO) {
register mad_fixed_t invsqrt2;
header->flags |= MAD_FLAG_MS_STEREO;
invsqrt2 = root_table[3 + -2];
for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
n = sfbwidth[sfbi];
if (modes[sfbi] != MS_STEREO)
continue;
for (i = 0; i < n; ++i) {
register mad_fixed_t m, s;
m = xr[0][l + i];
s = xr[1][l + i];
xr[0][l + i] = mad_f_mul(m + s, invsqrt2); /* l = (m + s) / sqrt(2) */
xr[1][l + i] = mad_f_mul(m - s, invsqrt2); /* r = (m - s) / sqrt(2) */
}
}
}
return MAD_ERROR_NONE;
}
/*
* NAME: III_aliasreduce()
* DESCRIPTION: perform frequency line alias reduction
*/
static
void III_aliasreduce(mad_fixed_t xr[576], int lines)
{
mad_fixed_t const *bound;
int i;
bound = &xr[lines];
for (xr += 18; xr < bound; xr += 18) {
for (i = 0; i < 8; ++i) {
register mad_fixed_t a, b;
register mad_fixed64hi_t hi;
register mad_fixed64lo_t lo;
a = xr[-1 - i];
b = xr[ i];
# if defined(ASO_ZEROCHECK)
if (a | b) {
# endif
MAD_F_ML0(hi, lo, a, cs[i]);
MAD_F_MLA(hi, lo, -b, ca[i]);
xr[-1 - i] = MAD_F_MLZ(hi, lo);
MAD_F_ML0(hi, lo, b, cs[i]);
MAD_F_MLA(hi, lo, a, ca[i]);
xr[ i] = MAD_F_MLZ(hi, lo);
# if defined(ASO_ZEROCHECK)
}
# endif
}
}
}
# if defined(ASO_IMDCT)
void III_imdct_l(mad_fixed_t const [18], mad_fixed_t [36], unsigned int);
# else
/*
* NAME: imdct36
* DESCRIPTION: perform X[18]->x[36] IMDCT
*/
static inline
void imdct36(mad_fixed_t const X[18], mad_fixed_t x[36])
{
mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7;
mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15;
register mad_fixed64hi_t hi;
register mad_fixed64lo_t lo;
MAD_F_ML0(hi, lo, X[4], MAD_F(0x0ec835e8));
MAD_F_MLA(hi, lo, X[13], MAD_F(0x061f78aa));
t6 = MAD_F_MLZ(hi, lo);
MAD_F_MLA(hi, lo, (t14 = X[1] - X[10]), -MAD_F(0x061f78aa));
MAD_F_MLA(hi, lo, (t15 = X[7] + X[16]), -MAD_F(0x0ec835e8));
t0 = MAD_F_MLZ(hi, lo);
MAD_F_MLA(hi, lo, (t8 = X[0] - X[11] - X[12]), MAD_F(0x0216a2a2));
MAD_F_MLA(hi, lo, (t9 = X[2] - X[9] - X[14]), MAD_F(0x09bd7ca0));
MAD_F_MLA(hi, lo, (t10 = X[3] - X[8] - X[15]), -MAD_F(0x0cb19346));
MAD_F_MLA(hi, lo, (t11 = X[5] - X[6] - X[17]), -MAD_F(0x0fdcf549));
x[7] = MAD_F_MLZ(hi, lo);
x[10] = -x[7];
MAD_F_ML0(hi, lo, t8, -MAD_F(0x0cb19346));
MAD_F_MLA(hi, lo, t9, MAD_F(0x0fdcf549));
MAD_F_MLA(hi, lo, t10, MAD_F(0x0216a2a2));
MAD_F_MLA(hi, lo, t11, -MAD_F(0x09bd7ca0));
x[19] = x[34] = MAD_F_MLZ(hi, lo) - t0;
t12 = X[0] - X[3] + X[8] - X[11] - X[12] + X[15];
t13 = X[2] + X[5] - X[6] - X[9] - X[14] - X[17];
MAD_F_ML0(hi, lo, t12, -MAD_F(0x0ec835e8));
MAD_F_MLA(hi, lo, t13, MAD_F(0x061f78aa));
x[22] = x[31] = MAD_F_MLZ(hi, lo) + t0;
MAD_F_ML0(hi, lo, X[1], -MAD_F(0x09bd7ca0));
MAD_F_MLA(hi, lo, X[7], MAD_F(0x0216a2a2));
MAD_F_MLA(hi, lo, X[10], -MAD_F(0x0fdcf549));
MAD_F_MLA(hi, lo, X[16], MAD_F(0x0cb19346));
t1 = MAD_F_MLZ(hi, lo) + t6;
MAD_F_ML0(hi, lo, X[0], MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[2], MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[6], MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[9], MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[14], MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[15], -MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0f9ee890));
x[6] = MAD_F_MLZ(hi, lo) + t1;
x[11] = -x[6];
MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[2], -MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[3], MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[5], MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[6], MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[8], -MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[12], -MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[14], MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[15], MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[17], MAD_F(0x04cfb0e2));
x[23] = x[30] = MAD_F_MLZ(hi, lo) + t1;
MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[2], MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[3], -MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[5], MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[9], -MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[11], MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[14], MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[15], MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0acf37ad));
x[18] = x[35] = MAD_F_MLZ(hi, lo) - t1;
MAD_F_ML0(hi, lo, X[4], MAD_F(0x061f78aa));
MAD_F_MLA(hi, lo, X[13], -MAD_F(0x0ec835e8));
t7 = MAD_F_MLZ(hi, lo);
MAD_F_MLA(hi, lo, X[1], -MAD_F(0x0cb19346));
MAD_F_MLA(hi, lo, X[7], MAD_F(0x0fdcf549));
MAD_F_MLA(hi, lo, X[10], MAD_F(0x0216a2a2));
MAD_F_MLA(hi, lo, X[16], -MAD_F(0x09bd7ca0));
t2 = MAD_F_MLZ(hi, lo);
MAD_F_MLA(hi, lo, X[0], MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[2], MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[5], MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[9], MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[12], MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[14], MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[15], MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[17], MAD_F(0x0f426cb5));
x[5] = MAD_F_MLZ(hi, lo);
x[12] = -x[5];
MAD_F_ML0(hi, lo, X[0], MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[3], MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[6], -MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[8], MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[12], -MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[14], MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[15], MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0bcbe352));
x[0] = MAD_F_MLZ(hi, lo) + t2;
x[17] = -x[0];
MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[2], -MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[3], -MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[5], MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[8], MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[9], MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[11], -MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[17], -MAD_F(0x03768962));
x[24] = x[29] = MAD_F_MLZ(hi, lo) + t2;
MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0216a2a2));
MAD_F_MLA(hi, lo, X[7], -MAD_F(0x09bd7ca0));
MAD_F_MLA(hi, lo, X[10], MAD_F(0x0cb19346));
MAD_F_MLA(hi, lo, X[16], MAD_F(0x0fdcf549));
t3 = MAD_F_MLZ(hi, lo) + t7;
MAD_F_ML0(hi, lo, X[0], MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[2], MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[3], -MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[5], -MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[6], MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[8], MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[12], MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0ffc19fd));
x[8] = MAD_F_MLZ(hi, lo) + t3;
x[9] = -x[8];
MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[2], MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[3], MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[8], MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[11], -MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[14], -MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[15], MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[17], MAD_F(0x07635284));
x[21] = x[32] = MAD_F_MLZ(hi, lo) + t3;
MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[2], MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[3], MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[6], -MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[9], MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[12], MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[14], MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[15], -MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0898c779));
x[20] = x[33] = MAD_F_MLZ(hi, lo) - t3;
MAD_F_ML0(hi, lo, t14, -MAD_F(0x0ec835e8));
MAD_F_MLA(hi, lo, t15, MAD_F(0x061f78aa));
t4 = MAD_F_MLZ(hi, lo) - t7;
MAD_F_ML0(hi, lo, t12, MAD_F(0x061f78aa));
MAD_F_MLA(hi, lo, t13, MAD_F(0x0ec835e8));
x[4] = MAD_F_MLZ(hi, lo) + t4;
x[13] = -x[4];
MAD_F_ML0(hi, lo, t8, MAD_F(0x09bd7ca0));
MAD_F_MLA(hi, lo, t9, -MAD_F(0x0216a2a2));
MAD_F_MLA(hi, lo, t10, MAD_F(0x0fdcf549));
MAD_F_MLA(hi, lo, t11, -MAD_F(0x0cb19346));
x[1] = MAD_F_MLZ(hi, lo) + t4;
x[16] = -x[1];
MAD_F_ML0(hi, lo, t8, -MAD_F(0x0fdcf549));
MAD_F_MLA(hi, lo, t9, -MAD_F(0x0cb19346));
MAD_F_MLA(hi, lo, t10, -MAD_F(0x09bd7ca0));
MAD_F_MLA(hi, lo, t11, -MAD_F(0x0216a2a2));
x[25] = x[28] = MAD_F_MLZ(hi, lo) + t4;
MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0fdcf549));
MAD_F_MLA(hi, lo, X[7], -MAD_F(0x0cb19346));
MAD_F_MLA(hi, lo, X[10], -MAD_F(0x09bd7ca0));
MAD_F_MLA(hi, lo, X[16], -MAD_F(0x0216a2a2));
t5 = MAD_F_MLZ(hi, lo) - t6;
MAD_F_ML0(hi, lo, X[0], MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[2], MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[3], MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[5], MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[6], MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[8], -MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[11], -MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[12], MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[15], MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0d7e8807));
x[2] = MAD_F_MLZ(hi, lo) + t5;
x[15] = -x[2];
MAD_F_ML0(hi, lo, X[0], MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[2], MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[3], MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[5], MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[6], -MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[9], -MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[11], MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[17], MAD_F(0x0e313245));
x[3] = MAD_F_MLZ(hi, lo) + t5;
x[14] = -x[3];
MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[12], -MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[14], -MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[15], -MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[17], -MAD_F(0x00b2aa3e));
x[26] = x[27] = MAD_F_MLZ(hi, lo) + t5;
}
/*
* NAME: III_imdct_l()
* DESCRIPTION: perform IMDCT and windowing for long blocks
*/
static
void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36],
unsigned int block_type)
{
unsigned int i;
/* IMDCT */
imdct36(X, z);
/* windowing */
switch (block_type) {
case 0: /* normal window */
# if defined(ASO_INTERLEAVE1)
{
register mad_fixed_t tmp1, tmp2;
tmp1 = window_l[0];
tmp2 = window_l[1];
for (i = 0; i < 34; i += 2) {
z[i + 0] = mad_f_mul(z[i + 0], tmp1);
tmp1 = window_l[i + 2];
z[i + 1] = mad_f_mul(z[i + 1], tmp2);
tmp2 = window_l[i + 3];
}
z[34] = mad_f_mul(z[34], tmp1);
z[35] = mad_f_mul(z[35], tmp2);
}
# elif defined(ASO_INTERLEAVE2)
{
register mad_fixed_t tmp1, tmp2;
tmp1 = z[0];
tmp2 = window_l[0];
for (i = 0; i < 35; ++i) {
z[i] = mad_f_mul(tmp1, tmp2);
tmp1 = z[i + 1];
tmp2 = window_l[i + 1];
}
z[35] = mad_f_mul(tmp1, tmp2);
}
# elif 1
for (i = 0; i < 36; i += 4) {
z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);
z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);
z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);
z[i + 3] = mad_f_mul(z[i + 3], window_l[i + 3]);
}
# else
for (i = 0; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]);
# endif
break;
case 1: /* start block */
for (i = 0; i < 18; ++i) z[i] = mad_f_mul(z[i], window_l[i]);
/* (i = 18; i < 24; ++i) z[i] unchanged */
for (i = 24; i < 30; ++i) z[i] = mad_f_mul(z[i], window_s[i - 18]);
for (i = 30; i < 36; ++i) z[i] = 0;
break;
case 3: /* stop block */
for (i = 0; i < 6; ++i) z[i] = 0;
for (i = 6; i < 12; ++i) z[i] = mad_f_mul(z[i], window_s[i - 6]);
/* (i = 12; i < 18; ++i) z[i] unchanged */
for (i = 18; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]);
break;
}
}
# endif /* ASO_IMDCT */
/*
* NAME: III_imdct_s()
* DESCRIPTION: perform IMDCT and windowing for short blocks
*/
static
void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36])
{
mad_fixed_t y[36], *yptr;
mad_fixed_t const *wptr;
int w, i;
register mad_fixed64hi_t hi;
register mad_fixed64lo_t lo;
/* IMDCT */
yptr = &y[0];
for (w = 0; w < 3; ++w) {
register mad_fixed_t const (*s)[6];
s = imdct_s;
for (i = 0; i < 3; ++i) {
MAD_F_ML0(hi, lo, X[0], (*s)[0]);
MAD_F_MLA(hi, lo, X[1], (*s)[1]);
MAD_F_MLA(hi, lo, X[2], (*s)[2]);
MAD_F_MLA(hi, lo, X[3], (*s)[3]);
MAD_F_MLA(hi, lo, X[4], (*s)[4]);
MAD_F_MLA(hi, lo, X[5], (*s)[5]);
yptr[i + 0] = MAD_F_MLZ(hi, lo);
yptr[5 - i] = -yptr[i + 0];
++s;
MAD_F_ML0(hi, lo, X[0], (*s)[0]);
MAD_F_MLA(hi, lo, X[1], (*s)[1]);
MAD_F_MLA(hi, lo, X[2], (*s)[2]);
MAD_F_MLA(hi, lo, X[3], (*s)[3]);
MAD_F_MLA(hi, lo, X[4], (*s)[4]);
MAD_F_MLA(hi, lo, X[5], (*s)[5]);
yptr[ i + 6] = MAD_F_MLZ(hi, lo);
yptr[11 - i] = yptr[i + 6];
++s;
}
yptr += 12;
X += 6;
}
/* windowing, overlapping and concatenation */
yptr = &y[0];
wptr = &window_s[0];
for (i = 0; i < 6; ++i) {
z[i + 0] = 0;
z[i + 6] = mad_f_mul(yptr[ 0 + 0], wptr[0]);
MAD_F_ML0(hi, lo, yptr[ 0 + 6], wptr[6]);
MAD_F_MLA(hi, lo, yptr[12 + 0], wptr[0]);
z[i + 12] = MAD_F_MLZ(hi, lo);
MAD_F_ML0(hi, lo, yptr[12 + 6], wptr[6]);
MAD_F_MLA(hi, lo, yptr[24 + 0], wptr[0]);
z[i + 18] = MAD_F_MLZ(hi, lo);
z[i + 24] = mad_f_mul(yptr[24 + 6], wptr[6]);
z[i + 30] = 0;
++yptr;
++wptr;
}
}
/*
* NAME: III_overlap()
* DESCRIPTION: perform overlap-add of windowed IMDCT outputs
*/
static
void III_overlap(mad_fixed_t const output[36], mad_fixed_t overlap[18],
mad_fixed_t sample[18][32], unsigned int sb)
{
unsigned int i;
# if defined(ASO_INTERLEAVE2)
{
register mad_fixed_t tmp1, tmp2;
tmp1 = overlap[0];
tmp2 = overlap[1];
for (i = 0; i < 16; i += 2) {
sample[i + 0][sb] = output[i + 0] + tmp1;
overlap[i + 0] = output[i + 0 + 18];
tmp1 = overlap[i + 2];
sample[i + 1][sb] = output[i + 1] + tmp2;
overlap[i + 1] = output[i + 1 + 18];
tmp2 = overlap[i + 3];
}
sample[16][sb] = output[16] + tmp1;
overlap[16] = output[16 + 18];
sample[17][sb] = output[17] + tmp2;
overlap[17] = output[17 + 18];
}
# elif 0
for (i = 0; i < 18; i += 2) {
sample[i + 0][sb] = output[i + 0] + overlap[i + 0];
overlap[i + 0] = output[i + 0 + 18];
sample[i + 1][sb] = output[i + 1] + overlap[i + 1];
overlap[i + 1] = output[i + 1 + 18];
}
# else
for (i = 0; i < 18; ++i) {
sample[i][sb] = output[i] + overlap[i];
overlap[i] = output[i + 18];
}
# endif
}
/*
* NAME: III_overlap_z()
* DESCRIPTION: perform "overlap-add" of zero IMDCT outputs
*/
static inline
void III_overlap_z(mad_fixed_t overlap[18],
mad_fixed_t sample[18][32], unsigned int sb)
{
unsigned int i;
# if defined(ASO_INTERLEAVE2)
{
register mad_fixed_t tmp1, tmp2;
tmp1 = overlap[0];
tmp2 = overlap[1];
for (i = 0; i < 16; i += 2) {
sample[i + 0][sb] = tmp1;
overlap[i + 0] = 0;
tmp1 = overlap[i + 2];
sample[i + 1][sb] = tmp2;
overlap[i + 1] = 0;
tmp2 = overlap[i + 3];
}
sample[16][sb] = tmp1;
overlap[16] = 0;
sample[17][sb] = tmp2;
overlap[17] = 0;
}
# else
for (i = 0; i < 18; ++i) {
sample[i][sb] = overlap[i];
overlap[i] = 0;
}
# endif
}
/*
* NAME: III_freqinver()
* DESCRIPTION: perform subband frequency inversion for odd sample lines
*/
static
void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb)
{
unsigned int i;
# if 1 || defined(ASO_INTERLEAVE1) || defined(ASO_INTERLEAVE2)
{
register mad_fixed_t tmp1, tmp2;
tmp1 = sample[1][sb];
tmp2 = sample[3][sb];
for (i = 1; i < 13; i += 4) {
sample[i + 0][sb] = -tmp1;
tmp1 = sample[i + 4][sb];
sample[i + 2][sb] = -tmp2;
tmp2 = sample[i + 6][sb];
}
sample[13][sb] = -tmp1;
tmp1 = sample[17][sb];
sample[15][sb] = -tmp2;
sample[17][sb] = -tmp1;
}
# else
for (i = 1; i < 18; i += 2)
sample[i][sb] = -sample[i][sb];
# endif
}
/*
* NAME: III_decode()
* DESCRIPTION: decode frame main_data
*/
static
enum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame,
struct sideinfo *si, unsigned int nch)
{
struct mad_header *header = &frame->header;
unsigned int sfreqi, ngr, gr;
{
unsigned int sfreq;
sfreq = header->samplerate;
if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
sfreq *= 2;
/* 48000 => 0, 44100 => 1, 32000 => 2,
24000 => 3, 22050 => 4, 16000 => 5 */
sfreqi = ((sfreq >> 7) & 0x000f) +
((sfreq >> 15) & 0x0001) - 8;
if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
sfreqi += 3;
}
/* scalefactors, Huffman decoding, requantization */
ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2;
for (gr = 0; gr < ngr; ++gr) {
struct granule *granule = &si->gr[gr];
unsigned char const *sfbwidth[2];
mad_fixed_t xr[2][576];
unsigned int ch;
enum mad_error error;
for (ch = 0; ch < nch; ++ch) {
struct channel *channel = &granule->ch[ch];
unsigned int part2_length;
sfbwidth[ch] = sfbwidth_table[sfreqi].l;
if (channel->block_type == 2) {
sfbwidth[ch] = (channel->flags & mixed_block_flag) ?
sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s;
}
if (header->flags & MAD_FLAG_LSF_EXT) {
part2_length = III_scalefactors_lsf(ptr, channel,
ch == 0 ? 0 : &si->gr[1].ch[1],
header->mode_extension);
}
else {
part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch],
gr == 0 ? 0 : si->scfsi[ch]);
}
error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length);
if (error)
return error;
}
/* joint stereo processing */
if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) {
error = III_stereo(xr, granule, header, sfbwidth[0]);
if (error)
return error;
}
/* reordering, alias reduction, IMDCT, overlap-add, frequency inversion */
for (ch = 0; ch < nch; ++ch) {
struct channel const *channel = &granule->ch[ch];
mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr];
unsigned int sb, l, i, sblimit;
mad_fixed_t output[36];
if (channel->block_type == 2) {
III_reorder(xr[ch], channel, sfbwidth[ch]);
# if !defined(OPT_STRICT)
/*
* According to ISO/IEC 11172-3, "Alias reduction is not applied for
* granules with block_type == 2 (short block)." However, other
* sources suggest alias reduction should indeed be performed on the
* lower two subbands of mixed blocks. Most other implementations do
* this, so by default we will too.
*/
if (channel->flags & mixed_block_flag)
III_aliasreduce(xr[ch], 36);
# endif
}
else
III_aliasreduce(xr[ch], 576);
l = 0;
/* subbands 0-1 */
if (channel->block_type != 2 || (channel->flags & mixed_block_flag)) {
unsigned int block_type;
block_type = channel->block_type;
if (channel->flags & mixed_block_flag)
block_type = 0;
/* long blocks */
for (sb = 0; sb < 2; ++sb, l += 18) {
III_imdct_l(&xr[ch][l], output, block_type);
III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
}
}
else {
/* short blocks */
for (sb = 0; sb < 2; ++sb, l += 18) {
III_imdct_s(&xr[ch][l], output);
III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
}
}
III_freqinver(sample, 1);
/* (nonzero) subbands 2-31 */
i = 576;
while (i > 36 && xr[ch][i - 1] == 0)
--i;
sblimit = 32 - (576 - i) / 18;
if (channel->block_type != 2) {
/* long blocks */
for (sb = 2; sb < sblimit; ++sb, l += 18) {
III_imdct_l(&xr[ch][l], output, channel->block_type);
III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
if (sb & 1)
III_freqinver(sample, sb);
}
}
else {
/* short blocks */
for (sb = 2; sb < sblimit; ++sb, l += 18) {
III_imdct_s(&xr[ch][l], output);
III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
if (sb & 1)
III_freqinver(sample, sb);
}
}
/* remaining (zero) subbands */
for (sb = sblimit; sb < 32; ++sb) {
III_overlap_z((*frame->overlap)[ch][sb], sample, sb);
if (sb & 1)
III_freqinver(sample, sb);
}
}
}
return MAD_ERROR_NONE;
}
/*
* NAME: layer->III()
* DESCRIPTION: decode a single Layer III frame
*/
int mad_layer_III(struct mad_stream *stream, struct mad_frame *frame)
{
struct mad_header *header = &frame->header;
unsigned int nch, priv_bitlen, next_md_begin = 0;
unsigned int si_len, data_bitlen, md_len;
unsigned int frame_space, frame_used, frame_free;
struct mad_bitptr ptr;
struct sideinfo si;
enum mad_error error;
int result = 0;
/* allocate Layer III dynamic structures */
if (stream->main_data == 0) {
stream->main_data = malloc(MAD_BUFFER_MDLEN);
if (stream->main_data == 0) {
stream->error = MAD_ERROR_NOMEM;
return -1;
}
}
if (frame->overlap == 0) {
frame->overlap = calloc(2 * 32 * 18, sizeof(mad_fixed_t));
if (frame->overlap == 0) {
stream->error = MAD_ERROR_NOMEM;
return -1;
}
}
nch = MAD_NCHANNELS(header);
si_len = (header->flags & MAD_FLAG_LSF_EXT) ?
(nch == 1 ? 9 : 17) : (nch == 1 ? 17 : 32);
/* check frame sanity */
if (stream->next_frame - mad_bit_nextbyte(&stream->ptr) <
(signed int) si_len) {
stream->error = MAD_ERROR_BADFRAMELEN;
stream->md_len = 0;
return -1;
}
/* check CRC word */
if (header->flags & MAD_FLAG_PROTECTION) {
header->crc_check =
mad_bit_crc(stream->ptr, si_len * CHAR_BIT, header->crc_check);
if (header->crc_check != header->crc_target &&
!(frame->options & MAD_OPTION_IGNORECRC)) {
stream->error = MAD_ERROR_BADCRC;
result = -1;
}
}
/* decode frame side information */
error = III_sideinfo(&stream->ptr, nch, header->flags & MAD_FLAG_LSF_EXT,
&si, &data_bitlen, &priv_bitlen);
if (error && result == 0) {
stream->error = error;
result = -1;
}
header->flags |= priv_bitlen;
header->private_bits |= si.private_bits;
/* find main_data of next frame */
{
struct mad_bitptr peek;
unsigned long header;
mad_bit_init(&peek, stream->next_frame);
header = mad_bit_read(&peek, 32);
if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) {
if (!(header & 0x00010000L)) /* protection_bit */
mad_bit_skip(&peek, 16); /* crc_check */
next_md_begin =
mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8);
}
mad_bit_finish(&peek);
}
/* find main_data of this frame */
frame_space = stream->next_frame - mad_bit_nextbyte(&stream->ptr);
if (next_md_begin > si.main_data_begin + frame_space)
next_md_begin = 0;
md_len = si.main_data_begin + frame_space - next_md_begin;
frame_used = 0;
if (si.main_data_begin == 0) {
ptr = stream->ptr;
stream->md_len = 0;
frame_used = md_len;
}
else {
if (si.main_data_begin > stream->md_len) {
if (result == 0) {
stream->error = MAD_ERROR_BADDATAPTR;
result = -1;
}
}
else {
mad_bit_init(&ptr,
*stream->main_data + stream->md_len - si.main_data_begin);
if (md_len > si.main_data_begin) {
assert(stream->md_len + md_len -
si.main_data_begin <= MAD_BUFFER_MDLEN);
memcpy(*stream->main_data + stream->md_len,
mad_bit_nextbyte(&stream->ptr),
frame_used = md_len - si.main_data_begin);
stream->md_len += frame_used;
}
}
}
frame_free = frame_space - frame_used;
/* decode main_data */
if (result == 0) {
error = III_decode(&ptr, frame, &si, nch);
if (error) {
stream->error = error;
result = -1;
}
}
/* designate ancillary bits */
stream->anc_ptr = ptr;
stream->anc_bitlen = md_len * CHAR_BIT - data_bitlen;
# if 0 && defined(DEBUG)
fprintf(stderr,
"main_data_begin:%u, md_len:%u, frame_free:%u, "
"data_bitlen:%u, anc_bitlen: %u\n",
si.main_data_begin, md_len, frame_free,
data_bitlen, stream->anc_bitlen);
# endif
/* preload main_data buffer with up to 511 bytes for next frame(s) */
if (frame_free >= next_md_begin) {
memcpy(*stream->main_data,
stream->next_frame - next_md_begin, next_md_begin);
stream->md_len = next_md_begin;
}
else {
if (md_len < si.main_data_begin) {
unsigned int extra;
extra = si.main_data_begin - md_len;
if (extra + frame_free > next_md_begin)
extra = next_md_begin - frame_free;
if (extra < stream->md_len) {
memmove(*stream->main_data,
*stream->main_data + stream->md_len - extra, extra);
stream->md_len = extra;
}
}
else
stream->md_len = 0;
memcpy(*stream->main_data + stream->md_len,
stream->next_frame - frame_free, frame_free);
stream->md_len += frame_free;
}
return result;
}
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: layer3.h,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifndef LIBMAD_LAYER3_H
# define LIBMAD_LAYER3_H
# include "stream.h"
# include "frame.h"
int mad_layer_III(struct mad_stream *, struct mad_frame *);
# endif
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* If you would like to negotiate alternate licensing terms, you may do
* so by contacting the author: Robert Leslie <rob@mars.org>
*/
# ifdef __cplusplus
extern "C" {
# endif
# define FPM_INTEL
# define SIZEOF_INT 4
# define SIZEOF_LONG 4
# define SIZEOF_LONG_LONG 8
/* Id: version.h,v 1.1 2003/06/18 19:19:19 shank Exp */
# ifndef LIBMAD_VERSION_H
# define LIBMAD_VERSION_H
# define MAD_VERSION_MAJOR 0
# define MAD_VERSION_MINOR 14
# define MAD_VERSION_PATCH 2
# define MAD_VERSION_EXTRA " (beta)"
# define MAD_VERSION_STRINGIZE(str) #str
# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num)
# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \
MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \
MAD_VERSION_STRING(MAD_VERSION_PATCH) \
MAD_VERSION_EXTRA
# define MAD_PUBLISHYEAR "2000-2001"
# define MAD_AUTHOR "Robert Leslie"
# define MAD_EMAIL "rob@mars.org"
extern char const mad_version[];
extern char const mad_copyright[];
extern char const mad_author[];
extern char const mad_build[];
# endif
/* Id: fixed.h,v 1.1 2003/06/18 19:19:19 shank Exp */
# ifndef LIBMAD_FIXED_H
# define LIBMAD_FIXED_H
# if SIZEOF_INT >= 4
typedef signed int mad_fixed_t;
typedef signed int mad_fixed64hi_t;
typedef unsigned int mad_fixed64lo_t;
# else
typedef signed long mad_fixed_t;
typedef signed long mad_fixed64hi_t;
typedef unsigned long mad_fixed64lo_t;
# endif
# if defined(_MSC_VER)
# define mad_fixed64_t signed __int64
# elif 1 || defined(__GNUC__)
# define mad_fixed64_t signed long long
# endif
# if defined(FPM_FLOAT)
typedef double mad_sample_t;
# else
typedef mad_fixed_t mad_sample_t;
# endif
/*
* Fixed-point format: 0xABBBBBBB
* A == whole part (sign + 3 bits)
* B == fractional part (28 bits)
*
* Values are signed two's complement, so the effective range is:
* 0x80000000 to 0x7fffffff
* -8.0 to +7.9999999962747097015380859375
*
* The smallest representable value is:
* 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9)
*
* 28 bits of fractional accuracy represent about
* 8.6 digits of decimal accuracy.
*
* Fixed-point numbers can be added or subtracted as normal
* integers, but multiplication requires shifting the 64-bit result
* from 56 fractional bits back to 28 (and rounding.)
*
* Changing the definition of MAD_F_FRACBITS is only partially
* supported, and must be done with care.
*/
# define MAD_F_FRACBITS 28
# if MAD_F_FRACBITS == 28
# define MAD_F(x) ((mad_fixed_t) (x##L))
# else
# if MAD_F_FRACBITS < 28
# warning "MAD_F_FRACBITS < 28"
# define MAD_F(x) ((mad_fixed_t) \
(((x##L) + \
(1L << (28 - MAD_F_FRACBITS - 1))) >> \
(28 - MAD_F_FRACBITS)))
# elif MAD_F_FRACBITS > 28
# error "MAD_F_FRACBITS > 28 not currently supported"
# define MAD_F(x) ((mad_fixed_t) \
((x##L) << (MAD_F_FRACBITS - 28)))
# endif
# endif
# define MAD_F_MIN ((mad_fixed_t) -0x80000000L)
# define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL)
# define MAD_F_ONE MAD_F(0x10000000)
# define mad_f_tofixed(x) ((mad_fixed_t) \
((x) * (double) (1L << MAD_F_FRACBITS) + 0.5))
# define mad_f_todouble(x) ((double) \
((x) / (double) (1L << MAD_F_FRACBITS)))
# define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS)
# define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1))
/* (x should be positive) */
# define mad_f_fromint(x) ((x) << MAD_F_FRACBITS)
# define mad_f_add(x, y) ((x) + (y))
# define mad_f_sub(x, y) ((x) - (y))
# if defined(FPM_FLOAT)
# error "FPM_FLOAT not yet supported"
# undef MAD_F
# define MAD_F(x) mad_f_todouble(x)
# define mad_f_mul(x, y) ((x) * (y))
# define mad_f_scale64
# undef ASO_ZEROCHECK
# elif defined(FPM_64BIT)
/*
* This version should be the most accurate if 64-bit types are supported by
* the compiler, although it may not be the most efficient.
*/
# if defined(OPT_ACCURACY)
# define mad_f_mul(x, y) \
((mad_fixed_t) \
((((mad_fixed64_t) (x) * (y)) + \
(1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS))
# else
# define mad_f_mul(x, y) \
((mad_fixed_t) (((mad_fixed64_t) (x) * (y)) >> MAD_F_SCALEBITS))
# endif
# define MAD_F_SCALEBITS MAD_F_FRACBITS
/* --- Intel --------------------------------------------------------------- */
# elif defined(FPM_INTEL)
# if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable: 4035) /* no return value */
static __forceinline
mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y)
{
enum {
fracbits = MAD_F_FRACBITS
};
__asm {
mov eax, x
imul y
shrd eax, edx, fracbits
}
/* implicit return of eax */
}
# pragma warning(pop)
# define mad_f_mul mad_f_mul_inline
# define mad_f_scale64
# else
/*
* This Intel version is fast and accurate; the disposition of the least
* significant bit depends on OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
asm ("imull %3" \
: "=a" (lo), "=d" (hi) \
: "%a" (x), "rm" (y) \
: "cc")
# if defined(OPT_ACCURACY)
/*
* This gives best accuracy but is not very fast.
*/
# define MAD_F_MLA(hi, lo, x, y) \
({ mad_fixed64hi_t __hi; \
mad_fixed64lo_t __lo; \
MAD_F_MLX(__hi, __lo, (x), (y)); \
asm ("addl %2,%0\n\t" \
"adcl %3,%1" \
: "=rm" (lo), "=rm" (hi) \
: "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \
: "cc"); \
})
# endif /* OPT_ACCURACY */
# if defined(OPT_ACCURACY)
/*
* Surprisingly, this is faster than SHRD followed by ADC.
*/
# define mad_f_scale64(hi, lo) \
({ mad_fixed64hi_t __hi_; \
mad_fixed64lo_t __lo_; \
mad_fixed_t __result; \
asm ("addl %4,%2\n\t" \
"adcl %5,%3" \
: "=rm" (__lo_), "=rm" (__hi_) \
: "0" (lo), "1" (hi), \
"ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \
: "cc"); \
asm ("shrdl %3,%2,%1" \
: "=rm" (__result) \
: "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# else
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
asm ("shrdl %3,%2,%1" \
: "=rm" (__result) \
: "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# endif /* OPT_ACCURACY */
# define MAD_F_SCALEBITS MAD_F_FRACBITS
# endif
/* --- ARM ----------------------------------------------------------------- */
# elif defined(FPM_ARM)
/*
* This ARM V4 version is as accurate as FPM_64BIT but much faster. The
* least significant bit is properly rounded at no CPU cycle cost!
*/
# if 1
/*
* There's a bug somewhere, possibly in the compiler, that sometimes makes
* this necessary instead of the default implementation via MAD_F_MLX and
* mad_f_scale64. It may be related to the use (or lack) of
* -finline-functions and/or -fstrength-reduce.
*
* This is also apparently faster than MAD_F_MLX/mad_f_scale64.
*/
# define mad_f_mul(x, y) \
({ mad_fixed64hi_t __hi; \
mad_fixed64lo_t __lo; \
mad_fixed_t __result; \
asm ("smull %0, %1, %3, %4\n\t" \
"movs %0, %0, lsr %5\n\t" \
"adc %2, %0, %1, lsl %6" \
: "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
: "%r" (x), "r" (y), \
"M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# endif
# define MAD_F_MLX(hi, lo, x, y) \
asm ("smull %0, %1, %2, %3" \
: "=&r" (lo), "=&r" (hi) \
: "%r" (x), "r" (y))
# define MAD_F_MLA(hi, lo, x, y) \
asm ("smlal %0, %1, %2, %3" \
: "+r" (lo), "+r" (hi) \
: "%r" (x), "r" (y))
# define MAD_F_MLN(hi, lo) \
asm ("rsbs %0, %2, #0\n\t" \
"rsc %1, %3, #0" \
: "=r" (lo), "=r" (hi) \
: "0" (lo), "1" (hi) \
: "cc")
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
asm ("movs %0, %1, lsr %3\n\t" \
"adc %0, %0, %2, lsl %4" \
: "=r" (__result) \
: "r" (lo), "r" (hi), \
"M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
: "cc"); \
__result; \
})
# define MAD_F_SCALEBITS MAD_F_FRACBITS
/* --- MIPS ---------------------------------------------------------------- */
# elif defined(FPM_MIPS)
/*
* This MIPS version is fast and accurate; the disposition of the least
* significant bit depends on OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
asm ("mult %2,%3" \
: "=l" (lo), "=h" (hi) \
: "%r" (x), "r" (y))
# if defined(HAVE_MADD_ASM)
# define MAD_F_MLA(hi, lo, x, y) \
asm ("madd %2,%3" \
: "+l" (lo), "+h" (hi) \
: "%r" (x), "r" (y))
# elif defined(HAVE_MADD16_ASM)
/*
* This loses significant accuracy due to the 16-bit integer limit in the
* multiply/accumulate instruction.
*/
# define MAD_F_ML0(hi, lo, x, y) \
asm ("mult %2,%3" \
: "=l" (lo), "=h" (hi) \
: "%r" ((x) >> 12), "r" ((y) >> 16))
# define MAD_F_MLA(hi, lo, x, y) \
asm ("madd16 %2,%3" \
: "+l" (lo), "+h" (hi) \
: "%r" ((x) >> 12), "r" ((y) >> 16))
# define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo))
# endif
# if defined(OPT_SPEED)
# define mad_f_scale64(hi, lo) \
((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS)))
# define MAD_F_SCALEBITS MAD_F_FRACBITS
# endif
/* --- SPARC --------------------------------------------------------------- */
# elif defined(FPM_SPARC)
/*
* This SPARC V8 version is fast and accurate; the disposition of the least
* significant bit depends on OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
asm ("smul %2, %3, %0\n\t" \
"rd %%y, %1" \
: "=r" (lo), "=r" (hi) \
: "%r" (x), "rI" (y))
/* --- PowerPC ------------------------------------------------------------- */
# elif defined(FPM_PPC)
/*
* This PowerPC version is tuned for the 4xx embedded processors. It is
* effectively a tuned version of FPM_64BIT. It is a little faster and just
* as accurate. The disposition of the least significant bit depends on
* OPT_ACCURACY via mad_f_scale64().
*/
# define MAD_F_MLX(hi, lo, x, y) \
asm ("mulhw %1, %2, %3\n\t" \
"mullw %0, %2, %3" \
: "=&r" (lo), "=&r" (hi) \
: "%r" (x), "r" (y))
# define MAD_F_MLA(hi, lo, x, y) \
({ mad_fixed64hi_t __hi; \
mad_fixed64lo_t __lo; \
MAD_F_MLX(__hi, __lo, (x), (y)); \
asm ("addc %0, %2, %3\n\t" \
"adde %1, %4, %5" \
: "=r" (lo), "=r" (hi) \
: "%r" (__lo), "0" (lo), "%r" (__hi), "1" (hi)); \
})
# if defined(OPT_ACCURACY)
/*
* This is accurate and ~2 - 2.5 times slower than the unrounded version.
*
* The __volatile__ improves the generated code by another 5% (fewer spills
* to memory); eventually they should be removed.
*/
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
mad_fixed64hi_t __hi_; \
mad_fixed64lo_t __lo_; \
asm __volatile__ ("addc %0, %2, %4\n\t" \
"addze %1, %3" \
: "=r" (__lo_), "=r" (__hi_) \
: "r" (lo), "r" (hi), "r" (1 << (MAD_F_SCALEBITS - 1))); \
asm __volatile__ ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \
"rlwimi %0, %1,32-%3,%3,31" \
: "=&r" (__result) \
: "r" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS)); \
__result; \
})
# else
# define mad_f_scale64(hi, lo) \
({ mad_fixed_t __result; \
asm ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \
"rlwimi %0, %1,32-%3,%3,31" \
: "=r" (__result) \
: "r" (lo), "r" (hi), "I" (MAD_F_SCALEBITS)); \
__result; \
})
# endif /* OPT_ACCURACY */
# define MAD_F_SCALEBITS MAD_F_FRACBITS
/* --- Default ------------------------------------------------------------- */
# elif defined(FPM_DEFAULT)
/*
* This version is the most portable but it loses significant accuracy.
* Furthermore, accuracy is biased against the second argument, so care
* should be taken when ordering operands.
*
* The scale factors are constant as this is not used with SSO.
*
* Pre-rounding is required to stay within the limits of compliance.
*/
# if defined(OPT_SPEED)
# define mad_f_mul(x, y) (((x) >> 12) * ((y) >> 16))
# else
# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \
(((y) + (1L << 15)) >> 16))
# endif
/* ------------------------------------------------------------------------- */
# else
# error "no FPM selected"
# endif
/* default implementations */
# if !defined(mad_f_mul)
# define mad_f_mul(x, y) \
({ mad_fixed64hi_t __hi; \
mad_fixed64lo_t __lo; \
MAD_F_MLX(__hi, __lo, (x), (y)); \
mad_f_scale64(__hi, __lo); \
})
# endif
# if !defined(MAD_F_MLA)
# define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y)))
# define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y)))
# define MAD_F_MLN(hi, lo) ((lo) = -(lo))
# define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
# endif
# if !defined(MAD_F_ML0)
# define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y))
# endif
# if !defined(MAD_F_MLN)
# define MAD_F_MLN(hi, lo) ((hi) = ((lo) = -(lo)) ? ~(hi) : -(hi))
# endif
# if !defined(MAD_F_MLZ)
# define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo))
# endif
# if !defined(mad_f_scale64)
# if defined(OPT_ACCURACY)
# define mad_f_scale64(hi, lo) \
((((mad_fixed_t) \
(((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \
((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1)
# else
# define mad_f_scale64(hi, lo) \
((mad_fixed_t) \
(((hi) << (32 - MAD_F_SCALEBITS)) | \
((lo) >> MAD_F_SCALEBITS)))
# endif
# define MAD_F_SCALEBITS MAD_F_FRACBITS
# endif
/* miscellaneous C routines */
mad_fixed_t mad_f_abs(mad_fixed_t);
# endif
/* Id: bit.h,v 1.1 2003/06/18 19:19:19 shank Exp */
# ifndef LIBMAD_BIT_H
# define LIBMAD_BIT_H
struct mad_bitptr {
unsigned char const *byte;
unsigned short cache;
unsigned short left;
};
void mad_bit_init(struct mad_bitptr *, unsigned char const *);
# define mad_bit_finish(bitptr) /* nothing */
unsigned int mad_bit_length(struct mad_bitptr const *,
struct mad_bitptr const *);
# define mad_bit_bitsleft(bitptr) ((bitptr)->left)
unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *);
void mad_bit_skip(struct mad_bitptr *, unsigned int);
unsigned long mad_bit_read(struct mad_bitptr *, unsigned int);
void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long);
unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short);
# endif
/* Id: timer.h,v 1.1 2003/06/18 19:19:19 shank Exp */
# ifndef LIBMAD_TIMER_H
# define LIBMAD_TIMER_H
typedef struct {
signed long seconds; /* whole seconds */
unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */
} mad_timer_t;
extern mad_timer_t const mad_timer_zero;
# define MAD_TIMER_RESOLUTION 352800000UL
enum mad_units {
MAD_UNITS_HOURS = -2,
MAD_UNITS_MINUTES = -1,
MAD_UNITS_SECONDS = 0,
/* metric units */
MAD_UNITS_DECISECONDS = 10,
MAD_UNITS_CENTISECONDS = 100,
MAD_UNITS_MILLISECONDS = 1000,
/* audio sample units */
MAD_UNITS_8000_HZ = 8000,
MAD_UNITS_11025_HZ = 11025,
MAD_UNITS_12000_HZ = 12000,
MAD_UNITS_16000_HZ = 16000,
MAD_UNITS_22050_HZ = 22050,
MAD_UNITS_24000_HZ = 24000,
MAD_UNITS_32000_HZ = 32000,
MAD_UNITS_44100_HZ = 44100,
MAD_UNITS_48000_HZ = 48000,
/* video frame/field units */
MAD_UNITS_24_FPS = 24,
MAD_UNITS_25_FPS = 25,
MAD_UNITS_30_FPS = 30,
MAD_UNITS_48_FPS = 48,
MAD_UNITS_50_FPS = 50,
MAD_UNITS_60_FPS = 60,
/* CD audio frames */
MAD_UNITS_75_FPS = 75,
/* video drop-frame units */
MAD_UNITS_23_976_FPS = -24,
MAD_UNITS_24_975_FPS = -25,
MAD_UNITS_29_97_FPS = -30,
MAD_UNITS_47_952_FPS = -48,
MAD_UNITS_49_95_FPS = -50,
MAD_UNITS_59_94_FPS = -60
};
# define mad_timer_reset(timer) ((void) (*(timer) = mad_timer_zero))
int mad_timer_compare(mad_timer_t, mad_timer_t);
# define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero)
void mad_timer_negate(mad_timer_t *);
mad_timer_t mad_timer_abs(mad_timer_t);
void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long);
void mad_timer_add(mad_timer_t *, mad_timer_t);
void mad_timer_multiply(mad_timer_t *, signed long);
signed long mad_timer_count(mad_timer_t, enum mad_units);
unsigned long mad_timer_fraction(mad_timer_t, unsigned long);
void mad_timer_string(mad_timer_t, char *, char const *,
enum mad_units, enum mad_units, unsigned long);
# endif
/* Id: stream.h,v 1.1 2003/06/18 19:19:19 shank Exp */
# ifndef LIBMAD_STREAM_H
# define LIBMAD_STREAM_H
# define MAD_BUFFER_GUARD 8
# define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD)
enum mad_error {
MAD_ERROR_NONE = 0x0000, /* no error */
MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */
MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */
MAD_ERROR_NOMEM = 0x0031, /* not enough memory */
MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */
MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */
MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */
MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */
MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */
MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */
MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */
MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */
MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */
MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */
MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */
MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */
MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */
MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */
MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */
MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */
MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */
};
# define MAD_RECOVERABLE(error) ((error) & 0xff00)
struct mad_stream {
unsigned char const *buffer; /* input bitstream buffer */
unsigned char const *bufend; /* end of buffer */
unsigned long skiplen; /* bytes to skip before next frame */
int sync; /* stream sync found */
unsigned long freerate; /* free bitrate (fixed) */
unsigned char const *this_frame; /* start of current frame */
unsigned char const *next_frame; /* start of next frame */
struct mad_bitptr ptr; /* current processing bit pointer */
struct mad_bitptr anc_ptr; /* ancillary bits pointer */
unsigned int anc_bitlen; /* number of ancillary bits */
unsigned char (*main_data)[MAD_BUFFER_MDLEN];
/* Layer III main_data() */
unsigned int md_len; /* bytes in main_data */
int options; /* decoding options (see below) */
enum mad_error error; /* error code (see above) */
};
enum {
MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */
MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */
# if 0 /* not yet implemented */
MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */
MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */
MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */
# endif
};
void mad_stream_init(struct mad_stream *);
void mad_stream_finish(struct mad_stream *);
# define mad_stream_options(stream, opts) \
((void) ((stream)->options = (opts)))
void mad_stream_buffer(struct mad_stream *,
unsigned char const *, unsigned long);
void mad_stream_skip(struct mad_stream *, unsigned long);
int mad_stream_sync(struct mad_stream *);
char const *mad_stream_errorstr(struct mad_stream const *);
# endif
/* Id: frame.h,v 1.1 2003/06/18 19:19:19 shank Exp */
# ifndef LIBMAD_FRAME_H
# define LIBMAD_FRAME_H
enum mad_layer {
MAD_LAYER_I = 1, /* Layer I */
MAD_LAYER_II = 2, /* Layer II */
MAD_LAYER_III = 3 /* Layer III */
};
enum mad_mode {
MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */
MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */
MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */
MAD_MODE_STEREO = 3 /* normal LR stereo */
};
enum mad_emphasis {
MAD_EMPHASIS_NONE = 0, /* no emphasis */
MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */
MAD_EMPHASIS_CCITT_J_17 = 3 /* CCITT J.17 emphasis */
};
struct mad_header {
enum mad_layer layer; /* audio layer (1, 2, or 3) */
enum mad_mode mode; /* channel mode (see above) */
int mode_extension; /* additional mode info */
enum mad_emphasis emphasis; /* de-emphasis to use (see above) */
unsigned long bitrate; /* stream bitrate (bps) */
unsigned int samplerate; /* sampling frequency (Hz) */
unsigned short crc_check; /* frame CRC accumulator */
unsigned short crc_target; /* final target CRC checksum */
int flags; /* flags (see below) */
int private_bits; /* private bits (see below) */
mad_timer_t duration; /* audio playing time of frame */
};
struct mad_frame {
struct mad_header header; /* MPEG audio header */
int options; /* decoding options (from stream) */
mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */
mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */
};
# define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1)
# define MAD_NSBSAMPLES(header) \
((header)->layer == MAD_LAYER_I ? 12 : \
(((header)->layer == MAD_LAYER_III && \
((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36))
enum {
MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */
MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */
MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */
MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */
MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */
MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */
MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */
MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */
MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */
MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */
MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */
MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */
};
enum {
MAD_PRIVATE_HEADER = 0x0100, /* header private bit */
MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */
};
void mad_header_init(struct mad_header *);
# define mad_header_finish(header) /* nothing */
int mad_header_decode(struct mad_header *, struct mad_stream *);
void mad_frame_init(struct mad_frame *);
void mad_frame_finish(struct mad_frame *);
int mad_frame_decode(struct mad_frame *, struct mad_stream *);
void mad_frame_mute(struct mad_frame *);
# endif
/* Id: synth.h,v 1.1 2003/06/18 19:19:19 shank Exp */
# ifndef LIBMAD_SYNTH_H
# define LIBMAD_SYNTH_H
struct mad_pcm {
unsigned int samplerate; /* sampling frequency (Hz) */
unsigned short channels; /* number of channels */
unsigned short length; /* number of samples per channel */
mad_fixed_t samples[2][1152]; /* PCM output samples [ch][sample] */
};
struct mad_synth {
mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */
/* [ch][eo][peo][s][v] */
unsigned int phase; /* current processing phase */
struct mad_pcm pcm; /* PCM output */
};
/* single channel PCM selector */
enum {
MAD_PCM_CHANNEL_SINGLE = 0
};
/* dual channel PCM selector */
enum {
MAD_PCM_CHANNEL_DUAL_1 = 0,
MAD_PCM_CHANNEL_DUAL_2 = 1
};
/* stereo PCM selector */
enum {
MAD_PCM_CHANNEL_STEREO_LEFT = 0,
MAD_PCM_CHANNEL_STEREO_RIGHT = 1
};
void mad_synth_init(struct mad_synth *);
# define mad_synth_finish(synth) /* nothing */
void mad_synth_mute(struct mad_synth *);
void mad_synth_frame(struct mad_synth *, struct mad_frame const *);
# endif
/* Id: decoder.h,v 1.1 2003/06/18 19:19:19 shank Exp */
# ifndef LIBMAD_DECODER_H
# define LIBMAD_DECODER_H
enum mad_decoder_mode {
MAD_DECODER_MODE_SYNC = 0,
MAD_DECODER_MODE_ASYNC
};
enum mad_flow {
MAD_FLOW_CONTINUE = 0x0000, /* continue normally */
MAD_FLOW_STOP = 0x0010, /* stop decoding normally */
MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */
MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */
};
struct mad_decoder {
enum mad_decoder_mode mode;
int options;
struct {
long pid;
int in;
int out;
} async;
struct {
struct mad_stream stream;
struct mad_frame frame;
struct mad_synth synth;
} *sync;
void *cb_data;
enum mad_flow (*input_func)(void *, struct mad_stream *);
enum mad_flow (*header_func)(void *, struct mad_header const *);
enum mad_flow (*filter_func)(void *,
struct mad_stream const *, struct mad_frame *);
enum mad_flow (*output_func)(void *,
struct mad_header const *, struct mad_pcm *);
enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
enum mad_flow (*message_func)(void *, void *, unsigned int *);
};
void mad_decoder_init(struct mad_decoder *, void *,
enum mad_flow (*)(void *, struct mad_stream *),
enum mad_flow (*)(void *, struct mad_header const *),
enum mad_flow (*)(void *,
struct mad_stream const *,
struct mad_frame *),
enum mad_flow (*)(void *,
struct mad_header const *,
struct mad_pcm *),
enum mad_flow (*)(void *,
struct mad_stream *,
struct mad_frame *),
enum mad_flow (*)(void *, void *, unsigned int *));
int mad_decoder_finish(struct mad_decoder *);
# define mad_decoder_options(decoder, opts) \
((void) ((decoder)->options = (opts)))
int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode);
int mad_decoder_message(struct mad_decoder *, void *, unsigned int *);
# endif
# ifdef __cplusplus
}
# endif
#
# libmad - MPEG audio decoder library
# Copyright (C) 2000-2001 Robert Leslie
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id: mad.h.sed,v 1.1 2003/06/18 19:19:19 shank Exp $
#
/^\/\*$/{
N
s/ \* libmad - /&/
t copy
b next
: copy
g
n
s|^ \* \$\(Id: .*\) \$$|/* \1 */|p
/^ \*\/$/d
b copy
}
/^# *include "/d
: next
p
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: qc_table.dat,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
/*
* These are the Layer II classes of quantization.
* The table is derived from Table B.4 of ISO/IEC 11172-3.
*/
{ 3, 2, 5,
MAD_F(0x15555555) /* 1.33333333333 => 1.33333333209, e 0.00000000124 */,
MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ },
{ 5, 3, 7,
MAD_F(0x1999999a) /* 1.60000000000 => 1.60000000149, e -0.00000000149 */,
MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ },
{ 7, 0, 3,
MAD_F(0x12492492) /* 1.14285714286 => 1.14285714179, e 0.00000000107 */,
MAD_F(0x04000000) /* 0.25000000000 => 0.25000000000, e 0.00000000000 */ },
{ 9, 4, 10,
MAD_F(0x1c71c71c) /* 1.77777777777 => 1.77777777612, e 0.00000000165 */,
MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ },
{ 15, 0, 4,
MAD_F(0x11111111) /* 1.06666666666 => 1.06666666642, e 0.00000000024 */,
MAD_F(0x02000000) /* 0.12500000000 => 0.12500000000, e 0.00000000000 */ },
{ 31, 0, 5,
MAD_F(0x10842108) /* 1.03225806452 => 1.03225806355, e 0.00000000097 */,
MAD_F(0x01000000) /* 0.06250000000 => 0.06250000000, e 0.00000000000 */ },
{ 63, 0, 6,
MAD_F(0x10410410) /* 1.01587301587 => 1.01587301493, e 0.00000000094 */,
MAD_F(0x00800000) /* 0.03125000000 => 0.03125000000, e 0.00000000000 */ },
{ 127, 0, 7,
MAD_F(0x10204081) /* 1.00787401575 => 1.00787401572, e 0.00000000003 */,
MAD_F(0x00400000) /* 0.01562500000 => 0.01562500000, e 0.00000000000 */ },
{ 255, 0, 8,
MAD_F(0x10101010) /* 1.00392156863 => 1.00392156839, e 0.00000000024 */,
MAD_F(0x00200000) /* 0.00781250000 => 0.00781250000, e 0.00000000000 */ },
{ 511, 0, 9,
MAD_F(0x10080402) /* 1.00195694716 => 1.00195694715, e 0.00000000001 */,
MAD_F(0x00100000) /* 0.00390625000 => 0.00390625000, e 0.00000000000 */ },
{ 1023, 0, 10,
MAD_F(0x10040100) /* 1.00097751711 => 1.00097751617, e 0.00000000094 */,
MAD_F(0x00080000) /* 0.00195312500 => 0.00195312500, e 0.00000000000 */ },
{ 2047, 0, 11,
MAD_F(0x10020040) /* 1.00048851979 => 1.00048851967, e 0.00000000012 */,
MAD_F(0x00040000) /* 0.00097656250 => 0.00097656250, e 0.00000000000 */ },
{ 4095, 0, 12,
MAD_F(0x10010010) /* 1.00024420024 => 1.00024420023, e 0.00000000001 */,
MAD_F(0x00020000) /* 0.00048828125 => 0.00048828125, e 0.00000000000 */ },
{ 8191, 0, 13,
MAD_F(0x10008004) /* 1.00012208522 => 1.00012208521, e 0.00000000001 */,
MAD_F(0x00010000) /* 0.00024414063 => 0.00024414062, e 0.00000000000 */ },
{ 16383, 0, 14,
MAD_F(0x10004001) /* 1.00006103888 => 1.00006103888, e -0.00000000000 */,
MAD_F(0x00008000) /* 0.00012207031 => 0.00012207031, e -0.00000000000 */ },
{ 32767, 0, 15,
MAD_F(0x10002000) /* 1.00003051851 => 1.00003051758, e 0.00000000093 */,
MAD_F(0x00004000) /* 0.00006103516 => 0.00006103516, e 0.00000000000 */ },
{ 65535, 0, 16,
MAD_F(0x10001000) /* 1.00001525902 => 1.00001525879, e 0.00000000023 */,
MAD_F(0x00002000) /* 0.00003051758 => 0.00003051758, e 0.00000000000 */ }
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: sf_table.dat,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
/*
* These are the scalefactor values for Layer I and Layer II.
* The values are from Table B.1 of ISO/IEC 11172-3.
*
* There is some error introduced by the 32-bit fixed-point representation;
* the amount of error is shown. For 16-bit PCM output, this shouldn't be
* too much of a problem.
*/
MAD_F(0x20000000), /* 2.000000000000 => 2.000000000000, e 0.000000000000 */
MAD_F(0x1965fea5), /* 1.587401051968 => 1.587401051074, e 0.000000000894 */
MAD_F(0x1428a2fa), /* 1.259921049895 => 1.259921051562, e -0.000000001667 */
MAD_F(0x10000000), /* 1.000000000000 => 1.000000000000, e 0.000000000000 */
MAD_F(0x0cb2ff53), /* 0.793700525984 => 0.793700527400, e -0.000000001416 */
MAD_F(0x0a14517d), /* 0.629960524947 => 0.629960525781, e -0.000000000833 */
MAD_F(0x08000000), /* 0.500000000000 => 0.500000000000, e 0.000000000000 */
MAD_F(0x06597fa9), /* 0.396850262992 => 0.396850261837, e 0.000000001155 */
MAD_F(0x050a28be), /* 0.314980262474 => 0.314980261028, e 0.000000001446 */
MAD_F(0x04000000), /* 0.250000000000 => 0.250000000000, e 0.000000000000 */
MAD_F(0x032cbfd5), /* 0.198425131496 => 0.198425132781, e -0.000000001285 */
MAD_F(0x0285145f), /* 0.157490131237 => 0.157490130514, e 0.000000000723 */
MAD_F(0x02000000), /* 0.125000000000 => 0.125000000000, e 0.000000000000 */
MAD_F(0x01965fea), /* 0.099212565748 => 0.099212564528, e 0.000000001220 */
MAD_F(0x01428a30), /* 0.078745065618 => 0.078745067120, e -0.000000001501 */
MAD_F(0x01000000), /* 0.062500000000 => 0.062500000000, e 0.000000000000 */
MAD_F(0x00cb2ff5), /* 0.049606282874 => 0.049606282264, e 0.000000000610 */
MAD_F(0x00a14518), /* 0.039372532809 => 0.039372533560, e -0.000000000751 */
MAD_F(0x00800000), /* 0.031250000000 => 0.031250000000, e 0.000000000000 */
MAD_F(0x006597fb), /* 0.024803141437 => 0.024803142995, e -0.000000001558 */
MAD_F(0x0050a28c), /* 0.019686266405 => 0.019686266780, e -0.000000000375 */
MAD_F(0x00400000), /* 0.015625000000 => 0.015625000000, e 0.000000000000 */
MAD_F(0x0032cbfd), /* 0.012401570719 => 0.012401569635, e 0.000000001084 */
MAD_F(0x00285146), /* 0.009843133202 => 0.009843133390, e -0.000000000188 */
MAD_F(0x00200000), /* 0.007812500000 => 0.007812500000, e 0.000000000000 */
MAD_F(0x001965ff), /* 0.006200785359 => 0.006200786680, e -0.000000001321 */
MAD_F(0x001428a3), /* 0.004921566601 => 0.004921566695, e -0.000000000094 */
MAD_F(0x00100000), /* 0.003906250000 => 0.003906250000, e 0.000000000000 */
MAD_F(0x000cb2ff), /* 0.003100392680 => 0.003100391477, e 0.000000001202 */
MAD_F(0x000a1451), /* 0.002460783301 => 0.002460781485, e 0.000000001816 */
MAD_F(0x00080000), /* 0.001953125000 => 0.001953125000, e 0.000000000000 */
MAD_F(0x00065980), /* 0.001550196340 => 0.001550197601, e -0.000000001262 */
MAD_F(0x00050a29), /* 0.001230391650 => 0.001230392605, e -0.000000000955 */
MAD_F(0x00040000), /* 0.000976562500 => 0.000976562500, e 0.000000000000 */
MAD_F(0x00032cc0), /* 0.000775098170 => 0.000775098801, e -0.000000000631 */
MAD_F(0x00028514), /* 0.000615195825 => 0.000615194440, e 0.000000001385 */
MAD_F(0x00020000), /* 0.000488281250 => 0.000488281250, e 0.000000000000 */
MAD_F(0x00019660), /* 0.000387549085 => 0.000387549400, e -0.000000000315 */
MAD_F(0x0001428a), /* 0.000307597913 => 0.000307597220, e 0.000000000693 */
MAD_F(0x00010000), /* 0.000244140625 => 0.000244140625, e 0.000000000000 */
MAD_F(0x0000cb30), /* 0.000193774542 => 0.000193774700, e -0.000000000158 */
MAD_F(0x0000a145), /* 0.000153798956 => 0.000153798610, e 0.000000000346 */
MAD_F(0x00008000), /* 0.000122070313 => 0.000122070313, e 0.000000000000 */
MAD_F(0x00006598), /* 0.000096887271 => 0.000096887350, e -0.000000000079 */
MAD_F(0x000050a3), /* 0.000076899478 => 0.000076901168, e -0.000000001689 */
MAD_F(0x00004000), /* 0.000061035156 => 0.000061035156, e 0.000000000000 */
MAD_F(0x000032cc), /* 0.000048443636 => 0.000048443675, e -0.000000000039 */
MAD_F(0x00002851), /* 0.000038449739 => 0.000038448721, e 0.000000001018 */
MAD_F(0x00002000), /* 0.000030517578 => 0.000030517578, e 0.000000000000 */
MAD_F(0x00001966), /* 0.000024221818 => 0.000024221838, e -0.000000000020 */
MAD_F(0x00001429), /* 0.000019224870 => 0.000019226223, e -0.000000001354 */
MAD_F(0x00001000), /* 0.000015258789 => 0.000015258789, e -0.000000000000 */
MAD_F(0x00000cb3), /* 0.000012110909 => 0.000012110919, e -0.000000000010 */
MAD_F(0x00000a14), /* 0.000009612435 => 0.000009611249, e 0.000000001186 */
MAD_F(0x00000800), /* 0.000007629395 => 0.000007629395, e -0.000000000000 */
MAD_F(0x00000659), /* 0.000006055454 => 0.000006053597, e 0.000000001858 */
MAD_F(0x0000050a), /* 0.000004806217 => 0.000004805624, e 0.000000000593 */
MAD_F(0x00000400), /* 0.000003814697 => 0.000003814697, e 0.000000000000 */
MAD_F(0x0000032d), /* 0.000003027727 => 0.000003028661, e -0.000000000934 */
MAD_F(0x00000285), /* 0.000002403109 => 0.000002402812, e 0.000000000296 */
MAD_F(0x00000200), /* 0.000001907349 => 0.000001907349, e -0.000000000000 */
MAD_F(0x00000196), /* 0.000001513864 => 0.000001512468, e 0.000000001396 */
MAD_F(0x00000143) /* 0.000001201554 => 0.000001203269, e -0.000000001714 */
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: stream.c,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include <stdlib.h>
# include "bit.h"
# include "stream.h"
/*
* NAME: stream->init()
* DESCRIPTION: initialize stream struct
*/
void mad_stream_init(struct mad_stream *stream)
{
stream->buffer = 0;
stream->bufend = 0;
stream->skiplen = 0;
stream->sync = 0;
stream->freerate = 0;
stream->this_frame = 0;
stream->next_frame = 0;
mad_bit_init(&stream->ptr, 0);
mad_bit_init(&stream->anc_ptr, 0);
stream->anc_bitlen = 0;
stream->main_data = 0;
stream->md_len = 0;
stream->options = 0;
stream->error = MAD_ERROR_NONE;
}
/*
* NAME: stream->finish()
* DESCRIPTION: deallocate any dynamic memory associated with stream
*/
void mad_stream_finish(struct mad_stream *stream)
{
if (stream->main_data) {
free(stream->main_data);
stream->main_data = 0;
}
mad_bit_finish(&stream->anc_ptr);
mad_bit_finish(&stream->ptr);
}
/*
* NAME: stream->buffer()
* DESCRIPTION: set stream buffer pointers
*/
void mad_stream_buffer(struct mad_stream *stream,
unsigned char const *buffer, unsigned long length)
{
stream->buffer = buffer;
stream->bufend = buffer + length;
stream->this_frame = buffer;
stream->next_frame = buffer;
stream->sync = 1;
mad_bit_init(&stream->ptr, buffer);
}
/*
* NAME: stream->skip()
* DESCRIPTION: arrange to skip bytes before the next frame
*/
void mad_stream_skip(struct mad_stream *stream, unsigned long length)
{
stream->skiplen += length;
}
/*
* NAME: stream->sync()
* DESCRIPTION: locate the next stream sync word
*/
int mad_stream_sync(struct mad_stream *stream)
{
register unsigned char const *ptr, *end;
ptr = mad_bit_nextbyte(&stream->ptr);
end = stream->bufend;
while (ptr < end - 1 &&
!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0))
++ptr;
if (end - ptr < MAD_BUFFER_GUARD)
return -1;
mad_bit_init(&stream->ptr, ptr);
return 0;
}
/*
* NAME: stream->errorstr()
* DESCRIPTION: return a string description of the current error condition
*/
char const *mad_stream_errorstr(struct mad_stream const *stream)
{
switch (stream->error) {
case MAD_ERROR_NONE: return "no error";
case MAD_ERROR_BUFLEN: return "input buffer too small (or EOF)";
case MAD_ERROR_BUFPTR: return "invalid (null) buffer pointer";
case MAD_ERROR_NOMEM: return "not enough memory";
case MAD_ERROR_LOSTSYNC: return "lost synchronization";
case MAD_ERROR_BADLAYER: return "reserved header layer value";
case MAD_ERROR_BADBITRATE: return "forbidden bitrate value";
case MAD_ERROR_BADSAMPLERATE: return "reserved sample frequency value";
case MAD_ERROR_BADEMPHASIS: return "reserved emphasis value";
case MAD_ERROR_BADCRC: return "CRC check failed";
case MAD_ERROR_BADBITALLOC: return "forbidden bit allocation value";
case MAD_ERROR_BADSCALEFACTOR: return "bad scalefactor index";
case MAD_ERROR_BADFRAMELEN: return "bad frame length";
case MAD_ERROR_BADBIGVALUES: return "bad big_values count";
case MAD_ERROR_BADBLOCKTYPE: return "reserved block_type";
case MAD_ERROR_BADSCFSI: return "bad scalefactor selection info";
case MAD_ERROR_BADDATAPTR: return "bad main_data_begin pointer";
case MAD_ERROR_BADPART3LEN: return "bad audio data length";
case MAD_ERROR_BADHUFFTABLE: return "bad Huffman table select";
case MAD_ERROR_BADHUFFDATA: return "Huffman data overrun";
case MAD_ERROR_BADSTEREO: return "incompatible block_type for JS";
}
return 0;
}
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: stream.h,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifndef LIBMAD_STREAM_H
# define LIBMAD_STREAM_H
# include "bit.h"
# define MAD_BUFFER_GUARD 8
# define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD)
enum mad_error {
MAD_ERROR_NONE = 0x0000, /* no error */
MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */
MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */
MAD_ERROR_NOMEM = 0x0031, /* not enough memory */
MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */
MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */
MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */
MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */
MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */
MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */
MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */
MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */
MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */
MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */
MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */
MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */
MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */
MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */
MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */
MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */
MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */
};
# define MAD_RECOVERABLE(error) ((error) & 0xff00)
struct mad_stream {
unsigned char const *buffer; /* input bitstream buffer */
unsigned char const *bufend; /* end of buffer */
unsigned long skiplen; /* bytes to skip before next frame */
int sync; /* stream sync found */
unsigned long freerate; /* free bitrate (fixed) */
unsigned char const *this_frame; /* start of current frame */
unsigned char const *next_frame; /* start of next frame */
struct mad_bitptr ptr; /* current processing bit pointer */
struct mad_bitptr anc_ptr; /* ancillary bits pointer */
unsigned int anc_bitlen; /* number of ancillary bits */
unsigned char (*main_data)[MAD_BUFFER_MDLEN];
/* Layer III main_data() */
unsigned int md_len; /* bytes in main_data */
int options; /* decoding options (see below) */
enum mad_error error; /* error code (see above) */
};
enum {
MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */
MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */
# if 0 /* not yet implemented */
MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */
MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */
MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */
# endif
};
void mad_stream_init(struct mad_stream *);
void mad_stream_finish(struct mad_stream *);
# define mad_stream_options(stream, opts) \
((void) ((stream)->options = (opts)))
void mad_stream_buffer(struct mad_stream *,
unsigned char const *, unsigned long);
void mad_stream_skip(struct mad_stream *, unsigned long);
int mad_stream_sync(struct mad_stream *);
char const *mad_stream_errorstr(struct mad_stream const *);
# endif
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: synth.c,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include "fixed.h"
# include "frame.h"
# include "synth.h"
/*
* NAME: synth->init()
* DESCRIPTION: initialize synth struct
*/
void mad_synth_init(struct mad_synth *synth)
{
mad_synth_mute(synth);
synth->phase = 0;
synth->pcm.samplerate = 0;
synth->pcm.channels = 0;
synth->pcm.length = 0;
}
/*
* NAME: synth->mute()
* DESCRIPTION: zero all polyphase filterbank values, resetting synthesis
*/
void mad_synth_mute(struct mad_synth *synth)
{
unsigned int ch, s, v;
for (ch = 0; ch < 2; ++ch) {
for (s = 0; s < 16; ++s) {
for (v = 0; v < 8; ++v) {
synth->filter[ch][0][0][s][v] = synth->filter[ch][0][1][s][v] =
synth->filter[ch][1][0][s][v] = synth->filter[ch][1][1][s][v] = 0;
}
}
}
}
/*
* An optional optimization called here the Subband Synthesis Optimization
* (SSO) improves the performance of subband synthesis at the expense of
* accuracy.
*
* The idea is to simplify 32x32->64-bit multiplication to 32x32->32 such
* that extra scaling and rounding are not necessary. This often allows the
* compiler to use faster 32-bit multiply-accumulate instructions instead of
* explicit 64-bit multiply, shift, and add instructions.
*
* SSO works like this: a full 32x32->64-bit multiply of two mad_fixed_t
* values requires the result to be right-shifted 28 bits to be properly
* scaled to the same fixed-point format. Right shifts can be applied at any
* time to either operand or to the result, so the optimization involves
* careful placement of these shifts to minimize the loss of accuracy.
*
* First, a 14-bit shift is applied with rounding at compile-time to the D[]
* table of coefficients for the subband synthesis window. This only loses 2
* bits of accuracy because the lower 12 bits are always zero. A second
* 12-bit shift occurs after the DCT calculation. This loses 12 bits of
* accuracy. Finally, a third 2-bit shift occurs just before the sample is
* saved in the PCM buffer. 14 + 12 + 2 == 28 bits.
*/
/* FPM_DEFAULT without OPT_SSO will actually lose accuracy and performance */
# if defined(FPM_DEFAULT) && !defined(OPT_SSO)
# define OPT_SSO
# endif
/* second SSO shift, with rounding */
# if defined(OPT_SSO)
# define SHIFT(x) (((x) + (1L << 11)) >> 12)
# else
# define SHIFT(x) (x)
# endif
/* possible DCT speed optimization */
# if defined(OPT_SPEED) && defined(MAD_F_MLX)
# define OPT_DCTO
# define MUL(x, y) \
({ mad_fixed64hi_t hi; \
mad_fixed64lo_t lo; \
MAD_F_MLX(hi, lo, (x), (y)); \
hi << (32 - MAD_F_SCALEBITS - 3); \
})
# else
# undef OPT_DCTO
# define MUL(x, y) mad_f_mul((x), (y))
# endif
/*
* NAME: dct32()
* DESCRIPTION: perform fast in[32]->out[32] DCT
*/
static
void dct32(mad_fixed_t const in[32], unsigned int slot,
mad_fixed_t lo[16][8], mad_fixed_t hi[16][8])
{
mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7;
mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15;
mad_fixed_t t16, t17, t18, t19, t20, t21, t22, t23;
mad_fixed_t t24, t25, t26, t27, t28, t29, t30, t31;
mad_fixed_t t32, t33, t34, t35, t36, t37, t38, t39;
mad_fixed_t t40, t41, t42, t43, t44, t45, t46, t47;
mad_fixed_t t48, t49, t50, t51, t52, t53, t54, t55;
mad_fixed_t t56, t57, t58, t59, t60, t61, t62, t63;
mad_fixed_t t64, t65, t66, t67, t68, t69, t70, t71;
mad_fixed_t t72, t73, t74, t75, t76, t77, t78, t79;
mad_fixed_t t80, t81, t82, t83, t84, t85, t86, t87;
mad_fixed_t t88, t89, t90, t91, t92, t93, t94, t95;
mad_fixed_t t96, t97, t98, t99, t100, t101, t102, t103;
mad_fixed_t t104, t105, t106, t107, t108, t109, t110, t111;
mad_fixed_t t112, t113, t114, t115, t116, t117, t118, t119;
mad_fixed_t t120, t121, t122, t123, t124, t125, t126, t127;
mad_fixed_t t128, t129, t130, t131, t132, t133, t134, t135;
mad_fixed_t t136, t137, t138, t139, t140, t141, t142, t143;
mad_fixed_t t144, t145, t146, t147, t148, t149, t150, t151;
mad_fixed_t t152, t153, t154, t155, t156, t157, t158, t159;
mad_fixed_t t160, t161, t162, t163, t164, t165, t166, t167;
mad_fixed_t t168, t169, t170, t171, t172, t173, t174, t175;
mad_fixed_t t176;
/* costab[i] = cos(PI / (2 * 32) * i) */
# if defined(OPT_DCTO)
# define costab1 MAD_F(0x7fd8878e)
# define costab2 MAD_F(0x7f62368f)
# define costab3 MAD_F(0x7e9d55fc)
# define costab4 MAD_F(0x7d8a5f40)
# define costab5 MAD_F(0x7c29fbee)
# define costab6 MAD_F(0x7a7d055b)
# define costab7 MAD_F(0x78848414)
# define costab8 MAD_F(0x7641af3d)
# define costab9 MAD_F(0x73b5ebd1)
# define costab10 MAD_F(0x70e2cbc6)
# define costab11 MAD_F(0x6dca0d14)
# define costab12 MAD_F(0x6a6d98a4)
# define costab13 MAD_F(0x66cf8120)
# define costab14 MAD_F(0x62f201ac)
# define costab15 MAD_F(0x5ed77c8a)
# define costab16 MAD_F(0x5a82799a)
# define costab17 MAD_F(0x55f5a4d2)
# define costab18 MAD_F(0x5133cc94)
# define costab19 MAD_F(0x4c3fdff4)
# define costab20 MAD_F(0x471cece7)
# define costab21 MAD_F(0x41ce1e65)
# define costab22 MAD_F(0x3c56ba70)
# define costab23 MAD_F(0x36ba2014)
# define costab24 MAD_F(0x30fbc54d)
# define costab25 MAD_F(0x2b1f34eb)
# define costab26 MAD_F(0x25280c5e)
# define costab27 MAD_F(0x1f19f97b)
# define costab28 MAD_F(0x18f8b83c)
# define costab29 MAD_F(0x12c8106f)
# define costab30 MAD_F(0x0c8bd35e)
# define costab31 MAD_F(0x0647d97c)
# else
# define costab1 MAD_F(0x0ffb10f2) /* 0.998795456 */
# define costab2 MAD_F(0x0fec46d2) /* 0.995184727 */
# define costab3 MAD_F(0x0fd3aac0) /* 0.989176510 */
# define costab4 MAD_F(0x0fb14be8) /* 0.980785280 */
# define costab5 MAD_F(0x0f853f7e) /* 0.970031253 */
# define costab6 MAD_F(0x0f4fa0ab) /* 0.956940336 */
# define costab7 MAD_F(0x0f109082) /* 0.941544065 */
# define costab8 MAD_F(0x0ec835e8) /* 0.923879533 */
# define costab9 MAD_F(0x0e76bd7a) /* 0.903989293 */
# define costab10 MAD_F(0x0e1c5979) /* 0.881921264 */
# define costab11 MAD_F(0x0db941a3) /* 0.857728610 */
# define costab12 MAD_F(0x0d4db315) /* 0.831469612 */
# define costab13 MAD_F(0x0cd9f024) /* 0.803207531 */
# define costab14 MAD_F(0x0c5e4036) /* 0.773010453 */
# define costab15 MAD_F(0x0bdaef91) /* 0.740951125 */
# define costab16 MAD_F(0x0b504f33) /* 0.707106781 */
# define costab17 MAD_F(0x0abeb49a) /* 0.671558955 */
# define costab18 MAD_F(0x0a267993) /* 0.634393284 */
# define costab19 MAD_F(0x0987fbfe) /* 0.595699304 */
# define costab20 MAD_F(0x08e39d9d) /* 0.555570233 */
# define costab21 MAD_F(0x0839c3cd) /* 0.514102744 */
# define costab22 MAD_F(0x078ad74e) /* 0.471396737 */
# define costab23 MAD_F(0x06d74402) /* 0.427555093 */
# define costab24 MAD_F(0x061f78aa) /* 0.382683432 */
# define costab25 MAD_F(0x0563e69d) /* 0.336889853 */
# define costab26 MAD_F(0x04a5018c) /* 0.290284677 */
# define costab27 MAD_F(0x03e33f2f) /* 0.242980180 */
# define costab28 MAD_F(0x031f1708) /* 0.195090322 */
# define costab29 MAD_F(0x0259020e) /* 0.146730474 */
# define costab30 MAD_F(0x01917a6c) /* 0.098017140 */
# define costab31 MAD_F(0x00c8fb30) /* 0.049067674 */
# endif
t0 = in[0] + in[31]; t16 = MUL(in[0] - in[31], costab1);
t1 = in[15] + in[16]; t17 = MUL(in[15] - in[16], costab31);
t41 = t16 + t17;
t59 = MUL(t16 - t17, costab2);
t33 = t0 + t1;
t50 = MUL(t0 - t1, costab2);
t2 = in[7] + in[24]; t18 = MUL(in[7] - in[24], costab15);
t3 = in[8] + in[23]; t19 = MUL(in[8] - in[23], costab17);
t42 = t18 + t19;
t60 = MUL(t18 - t19, costab30);
t34 = t2 + t3;
t51 = MUL(t2 - t3, costab30);
t4 = in[3] + in[28]; t20 = MUL(in[3] - in[28], costab7);
t5 = in[12] + in[19]; t21 = MUL(in[12] - in[19], costab25);
t43 = t20 + t21;
t61 = MUL(t20 - t21, costab14);
t35 = t4 + t5;
t52 = MUL(t4 - t5, costab14);
t6 = in[4] + in[27]; t22 = MUL(in[4] - in[27], costab9);
t7 = in[11] + in[20]; t23 = MUL(in[11] - in[20], costab23);
t44 = t22 + t23;
t62 = MUL(t22 - t23, costab18);
t36 = t6 + t7;
t53 = MUL(t6 - t7, costab18);
t8 = in[1] + in[30]; t24 = MUL(in[1] - in[30], costab3);
t9 = in[14] + in[17]; t25 = MUL(in[14] - in[17], costab29);
t45 = t24 + t25;
t63 = MUL(t24 - t25, costab6);
t37 = t8 + t9;
t54 = MUL(t8 - t9, costab6);
t10 = in[6] + in[25]; t26 = MUL(in[6] - in[25], costab13);
t11 = in[9] + in[22]; t27 = MUL(in[9] - in[22], costab19);
t46 = t26 + t27;
t64 = MUL(t26 - t27, costab26);
t38 = t10 + t11;
t55 = MUL(t10 - t11, costab26);
t12 = in[2] + in[29]; t28 = MUL(in[2] - in[29], costab5);
t13 = in[13] + in[18]; t29 = MUL(in[13] - in[18], costab27);
t47 = t28 + t29;
t65 = MUL(t28 - t29, costab10);
t39 = t12 + t13;
t56 = MUL(t12 - t13, costab10);
t14 = in[5] + in[26]; t30 = MUL(in[5] - in[26], costab11);
t15 = in[10] + in[21]; t31 = MUL(in[10] - in[21], costab21);
t48 = t30 + t31;
t66 = MUL(t30 - t31, costab22);
t40 = t14 + t15;
t57 = MUL(t14 - t15, costab22);
t69 = t33 + t34; t89 = MUL(t33 - t34, costab4);
t70 = t35 + t36; t90 = MUL(t35 - t36, costab28);
t71 = t37 + t38; t91 = MUL(t37 - t38, costab12);
t72 = t39 + t40; t92 = MUL(t39 - t40, costab20);
t73 = t41 + t42; t94 = MUL(t41 - t42, costab4);
t74 = t43 + t44; t95 = MUL(t43 - t44, costab28);
t75 = t45 + t46; t96 = MUL(t45 - t46, costab12);
t76 = t47 + t48; t97 = MUL(t47 - t48, costab20);
t78 = t50 + t51; t100 = MUL(t50 - t51, costab4);
t79 = t52 + t53; t101 = MUL(t52 - t53, costab28);
t80 = t54 + t55; t102 = MUL(t54 - t55, costab12);
t81 = t56 + t57; t103 = MUL(t56 - t57, costab20);
t83 = t59 + t60; t106 = MUL(t59 - t60, costab4);
t84 = t61 + t62; t107 = MUL(t61 - t62, costab28);
t85 = t63 + t64; t108 = MUL(t63 - t64, costab12);
t86 = t65 + t66; t109 = MUL(t65 - t66, costab20);
t113 = t69 + t70;
t114 = t71 + t72;
/* 0 */ hi[15][slot] = SHIFT(t113 + t114);
/* 16 */ lo[ 0][slot] = SHIFT(MUL(t113 - t114, costab16));
t115 = t73 + t74;
t116 = t75 + t76;
t32 = t115 + t116;
/* 1 */ hi[14][slot] = SHIFT(t32);
t118 = t78 + t79;
t119 = t80 + t81;
t58 = t118 + t119;
/* 2 */ hi[13][slot] = SHIFT(t58);
t121 = t83 + t84;
t122 = t85 + t86;
t67 = t121 + t122;
t49 = (t67 * 2) - t32;
/* 3 */ hi[12][slot] = SHIFT(t49);
t125 = t89 + t90;
t126 = t91 + t92;
t93 = t125 + t126;
/* 4 */ hi[11][slot] = SHIFT(t93);
t128 = t94 + t95;
t129 = t96 + t97;
t98 = t128 + t129;
t68 = (t98 * 2) - t49;
/* 5 */ hi[10][slot] = SHIFT(t68);
t132 = t100 + t101;
t133 = t102 + t103;
t104 = t132 + t133;
t82 = (t104 * 2) - t58;
/* 6 */ hi[ 9][slot] = SHIFT(t82);
t136 = t106 + t107;
t137 = t108 + t109;
t110 = t136 + t137;
t87 = (t110 * 2) - t67;
t77 = (t87 * 2) - t68;
/* 7 */ hi[ 8][slot] = SHIFT(t77);
t141 = MUL(t69 - t70, costab8);
t142 = MUL(t71 - t72, costab24);
t143 = t141 + t142;
/* 8 */ hi[ 7][slot] = SHIFT(t143);
/* 24 */ lo[ 8][slot] =
SHIFT((MUL(t141 - t142, costab16) * 2) - t143);
t144 = MUL(t73 - t74, costab8);
t145 = MUL(t75 - t76, costab24);
t146 = t144 + t145;
t88 = (t146 * 2) - t77;
/* 9 */ hi[ 6][slot] = SHIFT(t88);
t148 = MUL(t78 - t79, costab8);
t149 = MUL(t80 - t81, costab24);
t150 = t148 + t149;
t105 = (t150 * 2) - t82;
/* 10 */ hi[ 5][slot] = SHIFT(t105);
t152 = MUL(t83 - t84, costab8);
t153 = MUL(t85 - t86, costab24);
t154 = t152 + t153;
t111 = (t154 * 2) - t87;
t99 = (t111 * 2) - t88;
/* 11 */ hi[ 4][slot] = SHIFT(t99);
t157 = MUL(t89 - t90, costab8);
t158 = MUL(t91 - t92, costab24);
t159 = t157 + t158;
t127 = (t159 * 2) - t93;
/* 12 */ hi[ 3][slot] = SHIFT(t127);
t160 = (MUL(t125 - t126, costab16) * 2) - t127;
/* 20 */ lo[ 4][slot] = SHIFT(t160);
/* 28 */ lo[12][slot] =
SHIFT((((MUL(t157 - t158, costab16) * 2) - t159) * 2) - t160);
t161 = MUL(t94 - t95, costab8);
t162 = MUL(t96 - t97, costab24);
t163 = t161 + t162;
t130 = (t163 * 2) - t98;
t112 = (t130 * 2) - t99;
/* 13 */ hi[ 2][slot] = SHIFT(t112);
t164 = (MUL(t128 - t129, costab16) * 2) - t130;
t166 = MUL(t100 - t101, costab8);
t167 = MUL(t102 - t103, costab24);
t168 = t166 + t167;
t134 = (t168 * 2) - t104;
t120 = (t134 * 2) - t105;
/* 14 */ hi[ 1][slot] = SHIFT(t120);
t135 = (MUL(t118 - t119, costab16) * 2) - t120;
/* 18 */ lo[ 2][slot] = SHIFT(t135);
t169 = (MUL(t132 - t133, costab16) * 2) - t134;
t151 = (t169 * 2) - t135;
/* 22 */ lo[ 6][slot] = SHIFT(t151);
t170 = (((MUL(t148 - t149, costab16) * 2) - t150) * 2) - t151;
/* 26 */ lo[10][slot] = SHIFT(t170);
/* 30 */ lo[14][slot] =
SHIFT((((((MUL(t166 - t167, costab16) * 2) -
t168) * 2) - t169) * 2) - t170);
t171 = MUL(t106 - t107, costab8);
t172 = MUL(t108 - t109, costab24);
t173 = t171 + t172;
t138 = (t173 * 2) - t110;
t123 = (t138 * 2) - t111;
t139 = (MUL(t121 - t122, costab16) * 2) - t123;
t117 = (t123 * 2) - t112;
/* 15 */ hi[ 0][slot] = SHIFT(t117);
t124 = (MUL(t115 - t116, costab16) * 2) - t117;
/* 17 */ lo[ 1][slot] = SHIFT(t124);
t131 = (t139 * 2) - t124;
/* 19 */ lo[ 3][slot] = SHIFT(t131);
t140 = (t164 * 2) - t131;
/* 21 */ lo[ 5][slot] = SHIFT(t140);
t174 = (MUL(t136 - t137, costab16) * 2) - t138;
t155 = (t174 * 2) - t139;
t147 = (t155 * 2) - t140;
/* 23 */ lo[ 7][slot] = SHIFT(t147);
t156 = (((MUL(t144 - t145, costab16) * 2) - t146) * 2) - t147;
/* 25 */ lo[ 9][slot] = SHIFT(t156);
t175 = (((MUL(t152 - t153, costab16) * 2) - t154) * 2) - t155;
t165 = (t175 * 2) - t156;
/* 27 */ lo[11][slot] = SHIFT(t165);
t176 = (((((MUL(t161 - t162, costab16) * 2) -
t163) * 2) - t164) * 2) - t165;
/* 29 */ lo[13][slot] = SHIFT(t176);
/* 31 */ lo[15][slot] =
SHIFT((((((((MUL(t171 - t172, costab16) * 2) -
t173) * 2) - t174) * 2) - t175) * 2) - t176);
/*
* Totals:
* 80 multiplies
* 80 additions
* 119 subtractions
* 49 shifts (not counting SSO)
*/
}
# undef MUL
# undef SHIFT
/* third SSO shift and/or D[] optimization preshift */
# if defined(OPT_SSO)
# if MAD_F_FRACBITS != 28
# error "MAD_F_FRACBITS must be 28 to use OPT_SSO"
# endif
# define ML0(hi, lo, x, y) ((lo) = (x) * (y))
# define MLA(hi, lo, x, y) ((lo) += (x) * (y))
# define MLN(hi, lo) ((lo) = -(lo))
# define MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
# define SHIFT(x) ((x) >> 2)
# define PRESHIFT(x) ((MAD_F(x) + (1L << 13)) >> 14)
# else
# define ML0(hi, lo, x, y) MAD_F_ML0((hi), (lo), (x), (y))
# define MLA(hi, lo, x, y) MAD_F_MLA((hi), (lo), (x), (y))
# define MLN(hi, lo) MAD_F_MLN((hi), (lo))
# define MLZ(hi, lo) MAD_F_MLZ((hi), (lo))
# define SHIFT(x) (x)
# if defined(MAD_F_SCALEBITS)
# undef MAD_F_SCALEBITS
# define MAD_F_SCALEBITS (MAD_F_FRACBITS - 12)
# define PRESHIFT(x) (MAD_F(x) >> 12)
# else
# define PRESHIFT(x) MAD_F(x)
# endif
# endif
static
mad_fixed_t const D[17][32] = {
# include "D.dat"
};
# if defined(ASO_SYNTH)
void synth_full(struct mad_synth *, struct mad_frame const *,
unsigned int, unsigned int);
# else
/*
* NAME: synth->full()
* DESCRIPTION: perform full frequency PCM synthesis
*/
static
void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
unsigned int nch, unsigned int ns)
{
unsigned int phase, ch, s, sb, pe, po;
mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8];
mad_fixed_t const (*sbsample)[36][32];
register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
register mad_fixed_t const (*Dptr)[32], *ptr;
register mad_fixed64hi_t hi;
register mad_fixed64lo_t lo;
for (ch = 0; ch < nch; ++ch) {
sbsample = &frame->sbsample[ch];
filter = &synth->filter[ch];
phase = synth->phase;
pcm1 = synth->pcm.samples[ch];
for (s = 0; s < ns; ++s) {
dct32((*sbsample)[s], phase >> 1,
(*filter)[0][phase & 1], (*filter)[1][phase & 1]);
pe = phase & ~1;
po = ((phase - 1) & 0xf) | 1;
/* calculate 32 samples */
fe = &(*filter)[0][ phase & 1][0];
fx = &(*filter)[0][~phase & 1][0];
fo = &(*filter)[1][~phase & 1][0];
Dptr = &D[0];
ptr = *Dptr + po;
ML0(hi, lo, (*fx)[0], ptr[ 0]);
MLA(hi, lo, (*fx)[1], ptr[14]);
MLA(hi, lo, (*fx)[2], ptr[12]);
MLA(hi, lo, (*fx)[3], ptr[10]);
MLA(hi, lo, (*fx)[4], ptr[ 8]);
MLA(hi, lo, (*fx)[5], ptr[ 6]);
MLA(hi, lo, (*fx)[6], ptr[ 4]);
MLA(hi, lo, (*fx)[7], ptr[ 2]);
MLN(hi, lo);
ptr = *Dptr + pe;
MLA(hi, lo, (*fe)[0], ptr[ 0]);
MLA(hi, lo, (*fe)[1], ptr[14]);
MLA(hi, lo, (*fe)[2], ptr[12]);
MLA(hi, lo, (*fe)[3], ptr[10]);
MLA(hi, lo, (*fe)[4], ptr[ 8]);
MLA(hi, lo, (*fe)[5], ptr[ 6]);
MLA(hi, lo, (*fe)[6], ptr[ 4]);
MLA(hi, lo, (*fe)[7], ptr[ 2]);
*pcm1++ = SHIFT(MLZ(hi, lo));
pcm2 = pcm1 + 30;
for (sb = 1; sb < 16; ++sb) {
++fe;
++Dptr;
/* D[32 - sb][i] == -D[sb][31 - i] */
ptr = *Dptr + po;
ML0(hi, lo, (*fo)[0], ptr[ 0]);
MLA(hi, lo, (*fo)[1], ptr[14]);
MLA(hi, lo, (*fo)[2], ptr[12]);
MLA(hi, lo, (*fo)[3], ptr[10]);
MLA(hi, lo, (*fo)[4], ptr[ 8]);
MLA(hi, lo, (*fo)[5], ptr[ 6]);
MLA(hi, lo, (*fo)[6], ptr[ 4]);
MLA(hi, lo, (*fo)[7], ptr[ 2]);
MLN(hi, lo);
ptr = *Dptr + pe;
MLA(hi, lo, (*fe)[7], ptr[ 2]);
MLA(hi, lo, (*fe)[6], ptr[ 4]);
MLA(hi, lo, (*fe)[5], ptr[ 6]);
MLA(hi, lo, (*fe)[4], ptr[ 8]);
MLA(hi, lo, (*fe)[3], ptr[10]);
MLA(hi, lo, (*fe)[2], ptr[12]);
MLA(hi, lo, (*fe)[1], ptr[14]);
MLA(hi, lo, (*fe)[0], ptr[ 0]);
*pcm1++ = SHIFT(MLZ(hi, lo));
ptr = *Dptr - pe;
ML0(hi, lo, (*fe)[0], ptr[31 - 16]);
MLA(hi, lo, (*fe)[1], ptr[31 - 14]);
MLA(hi, lo, (*fe)[2], ptr[31 - 12]);
MLA(hi, lo, (*fe)[3], ptr[31 - 10]);
MLA(hi, lo, (*fe)[4], ptr[31 - 8]);
MLA(hi, lo, (*fe)[5], ptr[31 - 6]);
MLA(hi, lo, (*fe)[6], ptr[31 - 4]);
MLA(hi, lo, (*fe)[7], ptr[31 - 2]);
ptr = *Dptr - po;
MLA(hi, lo, (*fo)[7], ptr[31 - 2]);
MLA(hi, lo, (*fo)[6], ptr[31 - 4]);
MLA(hi, lo, (*fo)[5], ptr[31 - 6]);
MLA(hi, lo, (*fo)[4], ptr[31 - 8]);
MLA(hi, lo, (*fo)[3], ptr[31 - 10]);
MLA(hi, lo, (*fo)[2], ptr[31 - 12]);
MLA(hi, lo, (*fo)[1], ptr[31 - 14]);
MLA(hi, lo, (*fo)[0], ptr[31 - 16]);
*pcm2-- = SHIFT(MLZ(hi, lo));
++fo;
}
++Dptr;
ptr = *Dptr + po;
ML0(hi, lo, (*fo)[0], ptr[ 0]);
MLA(hi, lo, (*fo)[1], ptr[14]);
MLA(hi, lo, (*fo)[2], ptr[12]);
MLA(hi, lo, (*fo)[3], ptr[10]);
MLA(hi, lo, (*fo)[4], ptr[ 8]);
MLA(hi, lo, (*fo)[5], ptr[ 6]);
MLA(hi, lo, (*fo)[6], ptr[ 4]);
MLA(hi, lo, (*fo)[7], ptr[ 2]);
*pcm1 = SHIFT(-MLZ(hi, lo));
pcm1 += 16;
phase = (phase + 1) % 16;
}
}
}
# endif
/*
* NAME: synth->half()
* DESCRIPTION: perform half frequency PCM synthesis
*/
static
void synth_half(struct mad_synth *synth, struct mad_frame const *frame,
unsigned int nch, unsigned int ns)
{
unsigned int phase, ch, s, sb, pe, po;
mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8];
mad_fixed_t const (*sbsample)[36][32];
register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
register mad_fixed_t const (*Dptr)[32], *ptr;
register mad_fixed64hi_t hi;
register mad_fixed64lo_t lo;
for (ch = 0; ch < nch; ++ch) {
sbsample = &frame->sbsample[ch];
filter = &synth->filter[ch];
phase = synth->phase;
pcm1 = synth->pcm.samples[ch];
for (s = 0; s < ns; ++s) {
dct32((*sbsample)[s], phase >> 1,
(*filter)[0][phase & 1], (*filter)[1][phase & 1]);
pe = phase & ~1;
po = ((phase - 1) & 0xf) | 1;
/* calculate 16 samples */
fe = &(*filter)[0][ phase & 1][0];
fx = &(*filter)[0][~phase & 1][0];
fo = &(*filter)[1][~phase & 1][0];
Dptr = &D[0];
ptr = *Dptr + po;
ML0(hi, lo, (*fx)[0], ptr[ 0]);
MLA(hi, lo, (*fx)[1], ptr[14]);
MLA(hi, lo, (*fx)[2], ptr[12]);
MLA(hi, lo, (*fx)[3], ptr[10]);
MLA(hi, lo, (*fx)[4], ptr[ 8]);
MLA(hi, lo, (*fx)[5], ptr[ 6]);
MLA(hi, lo, (*fx)[6], ptr[ 4]);
MLA(hi, lo, (*fx)[7], ptr[ 2]);
MLN(hi, lo);
ptr = *Dptr + pe;
MLA(hi, lo, (*fe)[0], ptr[ 0]);
MLA(hi, lo, (*fe)[1], ptr[14]);
MLA(hi, lo, (*fe)[2], ptr[12]);
MLA(hi, lo, (*fe)[3], ptr[10]);
MLA(hi, lo, (*fe)[4], ptr[ 8]);
MLA(hi, lo, (*fe)[5], ptr[ 6]);
MLA(hi, lo, (*fe)[6], ptr[ 4]);
MLA(hi, lo, (*fe)[7], ptr[ 2]);
*pcm1++ = SHIFT(MLZ(hi, lo));
pcm2 = pcm1 + 14;
for (sb = 1; sb < 16; ++sb) {
++fe;
++Dptr;
/* D[32 - sb][i] == -D[sb][31 - i] */
if (!(sb & 1)) {
ptr = *Dptr + po;
ML0(hi, lo, (*fo)[0], ptr[ 0]);
MLA(hi, lo, (*fo)[1], ptr[14]);
MLA(hi, lo, (*fo)[2], ptr[12]);
MLA(hi, lo, (*fo)[3], ptr[10]);
MLA(hi, lo, (*fo)[4], ptr[ 8]);
MLA(hi, lo, (*fo)[5], ptr[ 6]);
MLA(hi, lo, (*fo)[6], ptr[ 4]);
MLA(hi, lo, (*fo)[7], ptr[ 2]);
MLN(hi, lo);
ptr = *Dptr + pe;
MLA(hi, lo, (*fe)[7], ptr[ 2]);
MLA(hi, lo, (*fe)[6], ptr[ 4]);
MLA(hi, lo, (*fe)[5], ptr[ 6]);
MLA(hi, lo, (*fe)[4], ptr[ 8]);
MLA(hi, lo, (*fe)[3], ptr[10]);
MLA(hi, lo, (*fe)[2], ptr[12]);
MLA(hi, lo, (*fe)[1], ptr[14]);
MLA(hi, lo, (*fe)[0], ptr[ 0]);
*pcm1++ = SHIFT(MLZ(hi, lo));
ptr = *Dptr - po;
ML0(hi, lo, (*fo)[7], ptr[31 - 2]);
MLA(hi, lo, (*fo)[6], ptr[31 - 4]);
MLA(hi, lo, (*fo)[5], ptr[31 - 6]);
MLA(hi, lo, (*fo)[4], ptr[31 - 8]);
MLA(hi, lo, (*fo)[3], ptr[31 - 10]);
MLA(hi, lo, (*fo)[2], ptr[31 - 12]);
MLA(hi, lo, (*fo)[1], ptr[31 - 14]);
MLA(hi, lo, (*fo)[0], ptr[31 - 16]);
ptr = *Dptr - pe;
MLA(hi, lo, (*fe)[0], ptr[31 - 16]);
MLA(hi, lo, (*fe)[1], ptr[31 - 14]);
MLA(hi, lo, (*fe)[2], ptr[31 - 12]);
MLA(hi, lo, (*fe)[3], ptr[31 - 10]);
MLA(hi, lo, (*fe)[4], ptr[31 - 8]);
MLA(hi, lo, (*fe)[5], ptr[31 - 6]);
MLA(hi, lo, (*fe)[6], ptr[31 - 4]);
MLA(hi, lo, (*fe)[7], ptr[31 - 2]);
*pcm2-- = SHIFT(MLZ(hi, lo));
}
++fo;
}
++Dptr;
ptr = *Dptr + po;
ML0(hi, lo, (*fo)[0], ptr[ 0]);
MLA(hi, lo, (*fo)[1], ptr[14]);
MLA(hi, lo, (*fo)[2], ptr[12]);
MLA(hi, lo, (*fo)[3], ptr[10]);
MLA(hi, lo, (*fo)[4], ptr[ 8]);
MLA(hi, lo, (*fo)[5], ptr[ 6]);
MLA(hi, lo, (*fo)[6], ptr[ 4]);
MLA(hi, lo, (*fo)[7], ptr[ 2]);
*pcm1 = SHIFT(-MLZ(hi, lo));
pcm1 += 8;
phase = (phase + 1) % 16;
}
}
}
/*
* NAME: synth->frame()
* DESCRIPTION: perform PCM synthesis of frame subband samples
*/
void mad_synth_frame(struct mad_synth *synth, struct mad_frame const *frame)
{
unsigned int nch, ns;
void (*synth_frame)(struct mad_synth *, struct mad_frame const *,
unsigned int, unsigned int);
nch = MAD_NCHANNELS(&frame->header);
ns = MAD_NSBSAMPLES(&frame->header);
synth->pcm.samplerate = frame->header.samplerate;
synth->pcm.channels = nch;
synth->pcm.length = 32 * ns;
synth_frame = synth_full;
if (frame->options & MAD_OPTION_HALFSAMPLERATE) {
synth->pcm.samplerate /= 2;
synth->pcm.length /= 2;
synth_frame = synth_half;
}
synth_frame(synth, frame, nch, ns);
synth->phase = (synth->phase + ns) % 16;
}
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: synth.h,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifndef LIBMAD_SYNTH_H
# define LIBMAD_SYNTH_H
# include "fixed.h"
# include "frame.h"
struct mad_pcm {
unsigned int samplerate; /* sampling frequency (Hz) */
unsigned short channels; /* number of channels */
unsigned short length; /* number of samples per channel */
mad_fixed_t samples[2][1152]; /* PCM output samples [ch][sample] */
};
struct mad_synth {
mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */
/* [ch][eo][peo][s][v] */
unsigned int phase; /* current processing phase */
struct mad_pcm pcm; /* PCM output */
};
/* single channel PCM selector */
enum {
MAD_PCM_CHANNEL_SINGLE = 0
};
/* dual channel PCM selector */
enum {
MAD_PCM_CHANNEL_DUAL_1 = 0,
MAD_PCM_CHANNEL_DUAL_2 = 1
};
/* stereo PCM selector */
enum {
MAD_PCM_CHANNEL_STEREO_LEFT = 0,
MAD_PCM_CHANNEL_STEREO_RIGHT = 1
};
void mad_synth_init(struct mad_synth *);
# define mad_synth_finish(synth) /* nothing */
void mad_synth_mute(struct mad_synth *);
void mad_synth_frame(struct mad_synth *, struct mad_frame const *);
# endif
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: timer.c,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include <stdio.h>
# ifdef HAVE_ASSERT_H
# include <assert.h>
# endif
# include "timer.h"
mad_timer_t const mad_timer_zero = { 0, 0 };
/*
* NAME: timer->compare()
* DESCRIPTION: indicate relative order of two timers
*/
int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2)
{
signed long diff;
diff = timer1.seconds - timer2.seconds;
if (diff < 0)
return -1;
else if (diff > 0)
return +1;
diff = timer1.fraction - timer2.fraction;
if (diff < 0)
return -1;
else if (diff > 0)
return +1;
return 0;
}
/*
* NAME: timer->negate()
* DESCRIPTION: invert the sign of a timer
*/
void mad_timer_negate(mad_timer_t *timer)
{
timer->seconds = -timer->seconds;
if (timer->fraction) {
timer->seconds -= 1;
timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction;
}
}
/*
* NAME: timer->abs()
* DESCRIPTION: return the absolute value of a timer
*/
mad_timer_t mad_timer_abs(mad_timer_t timer)
{
if (mad_timer_sign(timer) < 0)
mad_timer_negate(&timer);
return timer;
}
/*
* NAME: reduce_timer()
* DESCRIPTION: carry timer fraction into seconds
*/
static
void reduce_timer(mad_timer_t *timer)
{
timer->seconds += timer->fraction / MAD_TIMER_RESOLUTION;
timer->fraction %= MAD_TIMER_RESOLUTION;
}
/*
* NAME: gcd()
* DESCRIPTION: compute greatest common denominator
*/
static
unsigned long gcd(unsigned long num1, unsigned long num2)
{
unsigned long tmp;
while (num2) {
tmp = num2;
num2 = num1 % num2;
num1 = tmp;
}
return num1;
}
/*
* NAME: reduce_rational()
* DESCRIPTION: convert rational expression to lowest terms
*/
static
void reduce_rational(unsigned long *numer, unsigned long *denom)
{
unsigned long factor;
factor = gcd(*numer, *denom);
assert(factor != 0);
*numer /= factor;
*denom /= factor;
}
/*
* NAME: scale_rational()
* DESCRIPTION: solve numer/denom == ?/scale avoiding overflowing
*/
static
unsigned long scale_rational(unsigned long numer, unsigned long denom,
unsigned long scale)
{
reduce_rational(&numer, &denom);
reduce_rational(&scale, &denom);
assert(denom != 0);
if (denom < scale)
return numer * (scale / denom) + numer * (scale % denom) / denom;
if (denom < numer)
return scale * (numer / denom) + scale * (numer % denom) / denom;
return numer * scale / denom;
}
/*
* NAME: timer->set()
* DESCRIPTION: set timer to specific (positive) value
*/
void mad_timer_set(mad_timer_t *timer, unsigned long seconds,
unsigned long numer, unsigned long denom)
{
timer->seconds = seconds;
if (numer >= denom && denom > 0) {
timer->seconds += numer / denom;
numer %= denom;
}
switch (denom) {
case 0:
case 1:
timer->fraction = 0;
break;
case MAD_TIMER_RESOLUTION:
timer->fraction = numer;
break;
case 1000:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 1000);
break;
case 8000:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 8000);
break;
case 11025:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025);
break;
case 12000:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000);
break;
case 16000:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000);
break;
case 22050:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050);
break;
case 24000:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000);
break;
case 32000:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000);
break;
case 44100:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100);
break;
case 48000:
timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000);
break;
default:
timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION);
break;
}
if (timer->fraction >= MAD_TIMER_RESOLUTION)
reduce_timer(timer);
}
/*
* NAME: timer->add()
* DESCRIPTION: add one timer to another
*/
void mad_timer_add(mad_timer_t *timer, mad_timer_t incr)
{
timer->seconds += incr.seconds;
timer->fraction += incr.fraction;
if (timer->fraction >= MAD_TIMER_RESOLUTION)
reduce_timer(timer);
}
/*
* NAME: timer->multiply()
* DESCRIPTION: multiply a timer by a scalar value
*/
void mad_timer_multiply(mad_timer_t *timer, signed long scalar)
{
mad_timer_t addend;
unsigned long factor;
factor = scalar;
if (scalar < 0) {
factor = -scalar;
mad_timer_negate(timer);
}
addend = *timer;
*timer = mad_timer_zero;
while (factor) {
if (factor & 1)
mad_timer_add(timer, addend);
mad_timer_add(&addend, addend);
factor >>= 1;
}
}
/*
* NAME: timer->count()
* DESCRIPTION: return timer value in selected units
*/
signed long mad_timer_count(mad_timer_t timer, enum mad_units units)
{
switch (units) {
case MAD_UNITS_HOURS:
return timer.seconds / 60 / 60;
case MAD_UNITS_MINUTES:
return timer.seconds / 60;
case MAD_UNITS_SECONDS:
return timer.seconds;
case MAD_UNITS_DECISECONDS:
case MAD_UNITS_CENTISECONDS:
case MAD_UNITS_MILLISECONDS:
case MAD_UNITS_8000_HZ:
case MAD_UNITS_11025_HZ:
case MAD_UNITS_12000_HZ:
case MAD_UNITS_16000_HZ:
case MAD_UNITS_22050_HZ:
case MAD_UNITS_24000_HZ:
case MAD_UNITS_32000_HZ:
case MAD_UNITS_44100_HZ:
case MAD_UNITS_48000_HZ:
case MAD_UNITS_24_FPS:
case MAD_UNITS_25_FPS:
case MAD_UNITS_30_FPS:
case MAD_UNITS_48_FPS:
case MAD_UNITS_50_FPS:
case MAD_UNITS_60_FPS:
case MAD_UNITS_75_FPS:
return timer.seconds * (signed long) units +
(signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION,
units);
case MAD_UNITS_23_976_FPS:
case MAD_UNITS_24_975_FPS:
case MAD_UNITS_29_97_FPS:
case MAD_UNITS_47_952_FPS:
case MAD_UNITS_49_95_FPS:
case MAD_UNITS_59_94_FPS:
return (mad_timer_count(timer, -units) + 1) * 1000 / 1001;
}
/* unsupported units */
return 0;
}
/*
* NAME: timer->fraction()
* DESCRIPTION: return fractional part of timer in arbitrary terms
*/
unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom)
{
timer = mad_timer_abs(timer);
switch (denom) {
case 0:
return MAD_TIMER_RESOLUTION / timer.fraction;
case MAD_TIMER_RESOLUTION:
return timer.fraction;
default:
return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom);
}
}
/*
* NAME: timer->string()
* DESCRIPTION: write a string representation of a timer using a template
*/
void mad_timer_string(mad_timer_t timer,
char *dest, char const *format, enum mad_units units,
enum mad_units fracunits, unsigned long subparts)
{
unsigned long hours, minutes, seconds, sub;
unsigned int frac;
timer = mad_timer_abs(timer);
seconds = timer.seconds;
frac = sub = 0;
switch (fracunits) {
case MAD_UNITS_HOURS:
case MAD_UNITS_MINUTES:
case MAD_UNITS_SECONDS:
break;
case MAD_UNITS_DECISECONDS:
case MAD_UNITS_CENTISECONDS:
case MAD_UNITS_MILLISECONDS:
case MAD_UNITS_8000_HZ:
case MAD_UNITS_11025_HZ:
case MAD_UNITS_12000_HZ:
case MAD_UNITS_16000_HZ:
case MAD_UNITS_22050_HZ:
case MAD_UNITS_24000_HZ:
case MAD_UNITS_32000_HZ:
case MAD_UNITS_44100_HZ:
case MAD_UNITS_48000_HZ:
case MAD_UNITS_24_FPS:
case MAD_UNITS_25_FPS:
case MAD_UNITS_30_FPS:
case MAD_UNITS_48_FPS:
case MAD_UNITS_50_FPS:
case MAD_UNITS_60_FPS:
case MAD_UNITS_75_FPS:
{
unsigned long denom;
denom = MAD_TIMER_RESOLUTION / fracunits;
frac = timer.fraction / denom;
sub = scale_rational(timer.fraction % denom, denom, subparts);
}
break;
case MAD_UNITS_23_976_FPS:
case MAD_UNITS_24_975_FPS:
case MAD_UNITS_29_97_FPS:
case MAD_UNITS_47_952_FPS:
case MAD_UNITS_49_95_FPS:
case MAD_UNITS_59_94_FPS:
/* drop-frame encoding */
/* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */
{
unsigned long frame, cycle, d, m;
frame = mad_timer_count(timer, fracunits);
cycle = -fracunits * 60 * 10 - (10 - 1) * 2;
d = frame / cycle;
m = frame % cycle;
frame += (10 - 1) * 2 * d;
if (m > 2)
frame += 2 * ((m - 2) / (cycle / 10));
frac = frame % -fracunits;
seconds = frame / -fracunits;
}
break;
}
switch (units) {
case MAD_UNITS_HOURS:
minutes = seconds / 60;
hours = minutes / 60;
sprintf(dest, format,
hours,
(unsigned int) (minutes % 60),
(unsigned int) (seconds % 60),
frac, sub);
break;
case MAD_UNITS_MINUTES:
minutes = seconds / 60;
sprintf(dest, format,
minutes,
(unsigned int) (seconds % 60),
frac, sub);
break;
case MAD_UNITS_SECONDS:
sprintf(dest, format,
seconds,
frac, sub);
break;
case MAD_UNITS_23_976_FPS:
case MAD_UNITS_24_975_FPS:
case MAD_UNITS_29_97_FPS:
case MAD_UNITS_47_952_FPS:
case MAD_UNITS_49_95_FPS:
case MAD_UNITS_59_94_FPS:
if (fracunits < 0) {
/* not yet implemented */
sub = 0;
}
/* fall through */
case MAD_UNITS_DECISECONDS:
case MAD_UNITS_CENTISECONDS:
case MAD_UNITS_MILLISECONDS:
case MAD_UNITS_8000_HZ:
case MAD_UNITS_11025_HZ:
case MAD_UNITS_12000_HZ:
case MAD_UNITS_16000_HZ:
case MAD_UNITS_22050_HZ:
case MAD_UNITS_24000_HZ:
case MAD_UNITS_32000_HZ:
case MAD_UNITS_44100_HZ:
case MAD_UNITS_48000_HZ:
case MAD_UNITS_24_FPS:
case MAD_UNITS_25_FPS:
case MAD_UNITS_30_FPS:
case MAD_UNITS_48_FPS:
case MAD_UNITS_50_FPS:
case MAD_UNITS_60_FPS:
case MAD_UNITS_75_FPS:
sprintf(dest, format, mad_timer_count(timer, units), sub);
break;
}
}
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: timer.h,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifndef LIBMAD_TIMER_H
# define LIBMAD_TIMER_H
typedef struct {
signed long seconds; /* whole seconds */
unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */
} mad_timer_t;
extern mad_timer_t const mad_timer_zero;
# define MAD_TIMER_RESOLUTION 352800000UL
enum mad_units {
MAD_UNITS_HOURS = -2,
MAD_UNITS_MINUTES = -1,
MAD_UNITS_SECONDS = 0,
/* metric units */
MAD_UNITS_DECISECONDS = 10,
MAD_UNITS_CENTISECONDS = 100,
MAD_UNITS_MILLISECONDS = 1000,
/* audio sample units */
MAD_UNITS_8000_HZ = 8000,
MAD_UNITS_11025_HZ = 11025,
MAD_UNITS_12000_HZ = 12000,
MAD_UNITS_16000_HZ = 16000,
MAD_UNITS_22050_HZ = 22050,
MAD_UNITS_24000_HZ = 24000,
MAD_UNITS_32000_HZ = 32000,
MAD_UNITS_44100_HZ = 44100,
MAD_UNITS_48000_HZ = 48000,
/* video frame/field units */
MAD_UNITS_24_FPS = 24,
MAD_UNITS_25_FPS = 25,
MAD_UNITS_30_FPS = 30,
MAD_UNITS_48_FPS = 48,
MAD_UNITS_50_FPS = 50,
MAD_UNITS_60_FPS = 60,
/* CD audio frames */
MAD_UNITS_75_FPS = 75,
/* video drop-frame units */
MAD_UNITS_23_976_FPS = -24,
MAD_UNITS_24_975_FPS = -25,
MAD_UNITS_29_97_FPS = -30,
MAD_UNITS_47_952_FPS = -48,
MAD_UNITS_49_95_FPS = -50,
MAD_UNITS_59_94_FPS = -60
};
# define mad_timer_reset(timer) ((void) (*(timer) = mad_timer_zero))
int mad_timer_compare(mad_timer_t, mad_timer_t);
# define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero)
void mad_timer_negate(mad_timer_t *);
mad_timer_t mad_timer_abs(mad_timer_t);
void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long);
void mad_timer_add(mad_timer_t *, mad_timer_t);
void mad_timer_multiply(mad_timer_t *, signed long);
signed long mad_timer_count(mad_timer_t, enum mad_units);
unsigned long mad_timer_fraction(mad_timer_t, unsigned long);
void mad_timer_string(mad_timer_t, char *, char const *,
enum mad_units, enum mad_units, unsigned long);
# endif
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: version.c,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include "version.h"
char const mad_version[] = "MPEG Audio Decoder " MAD_VERSION;
char const mad_copyright[] = "Copyright (C) " MAD_PUBLISHYEAR " " MAD_AUTHOR;
char const mad_author[] = MAD_AUTHOR " <" MAD_EMAIL ">";
char const mad_build[] = ""
# if defined(FPM_64BIT)
"FPM_64BIT "
# elif defined(FPM_INTEL)
"FPM_INTEL "
# elif defined(FPM_ARM)
"FPM_ARM "
# elif defined(FPM_MIPS)
"FPM_MIPS "
# elif defined(FPM_SPARC)
"FPM_SPARC "
# elif defined(FPM_PPC)
"FPM_PPC "
# elif defined(FPM_DEFAULT)
"FPM_DEFAULT "
# endif
# if defined(ASO_IMDCT)
"ASO_IMDCT "
# endif
# if defined(ASO_INTERLEAVE1)
"ASO_INTERLEAVE1 "
# endif
# if defined(ASO_INTERLEAVE2)
"ASO_INTERLEAVE2 "
# endif
# if defined(ASO_ZEROCHECK)
"ASO_ZEROCHECK "
# endif
# if defined(OPT_SPEED)
"OPT_SPEED "
# elif defined(OPT_ACCURACY)
"OPT_ACCURACY "
# endif
# if defined(OPT_SSO)
"OPT_SSO "
# endif
# if defined(OPT_DCTO) /* never defined here */
"OPT_DCTO "
# endif
# if defined(OPT_STRICT)
"OPT_STRICT "
# endif
# if defined(EXPERIMENTAL)
"EXPERIMENTAL "
# endif
# if defined(DEBUG)
"DEBUG "
# elif defined(NDEBUG)
"NDEBUG "
# endif
;
/*
* libmad - MPEG audio decoder library
* Copyright (C) 2000-2001 Robert Leslie
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: version.h,v 1.1 2003/06/18 19:19:19 shank Exp $
*/
# ifndef LIBMAD_VERSION_H
# define LIBMAD_VERSION_H
# define MAD_VERSION_MAJOR 0
# define MAD_VERSION_MINOR 14
# define MAD_VERSION_PATCH 2
# define MAD_VERSION_EXTRA " (beta)"
# define MAD_VERSION_STRINGIZE(str) #str
# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num)
# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \
MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \
MAD_VERSION_STRING(MAD_VERSION_PATCH) \
MAD_VERSION_EXTRA
# define MAD_PUBLISHYEAR "2000-2001"
# define MAD_AUTHOR "Robert Leslie"
# define MAD_EMAIL "rob@mars.org"
extern char const mad_version[];
extern char const mad_copyright[];
extern char const mad_author[];
extern char const mad_build[];
# endif
......@@ -31,29 +31,21 @@
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <resolv.h>
#define MAXHOSTNAME 1024
int listenSocket;
int establish(unsigned short port) {
char myname[MAXHOSTNAME+1];
int sock;
struct sockaddr_in sockAddr;
struct hostent * he;
memset(&sockAddr, 0, sizeof(struct sockaddr_in));
gethostname(myname,MAXHOSTNAME);
he = gethostbyname(myname);
if(he == NULL) {
fprintf(stderr,"he == NULL\n");
return -1;
}
sockAddr.sin_family = he->h_addrtype;
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(port);
sockAddr.sin_addr.s_addr = INADDR_ANY;
if((sock = socket(AF_INET,SOCK_STREAM,0)) < 0) {
fprintf(stderr,"socket < 0\n");
......
......@@ -19,6 +19,7 @@
#include "ls.h"
#include "command.h"
#include "playlist.h"
#include "path.h"
#include <sys/types.h>
#include <sys/stat.h>
......@@ -40,7 +41,7 @@ int ls(FILE * fp, char * dirname) {
cwd[1] = '\0';
if(dirname==NULL) dirname=cwd;
if((dir = opendir(dirname))==NULL) {
if((dir = opendir(rmp2amp(dirname)))==NULL) {
fprintf(fp,"%s problems opening directory\n",COMMAND_RESPOND_ERROR);
return -1;
}
......@@ -117,7 +118,7 @@ time_t isMusic(char * file) {
time_t isOgg(char * file) {
struct stat st;
if(stat(file,&st)==0) {
if(stat(rmp2amp(file),&st)==0) {
if(S_ISREG(st.st_mode)) {
char * dup;
char * cLast;
......@@ -141,7 +142,7 @@ time_t isOgg(char * file) {
time_t isMp3(char * file) {
struct stat st;
if(stat(file,&st)==0) {
if(stat(rmp2amp(file),&st)==0) {
if(S_ISREG(st.st_mode)) {
char * dup;
char * cLast;
......@@ -165,7 +166,7 @@ time_t isMp3(char * file) {
time_t isDir(char * name) {
struct stat st;
if(stat(name,&st)==0) {
if(stat(rmp2amp(name),&st)==0) {
if(S_ISDIR(st.st_mode)) return st.st_mtime;
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -24,6 +24,7 @@
#include "player.h"
#include "listen.h"
#include "conf.h"
#include "path.h"
#include <unistd.h>
#include <stdio.h>
......@@ -88,15 +89,6 @@ int main(int argc, char * argv[]) {
return -1;
}
if((stat(musicDirArg,&st))<0) {
fprintf(stderr,"problem stat'ing \"%s\"\n",musicDirArg);
return -1;
}
if(!S_ISDIR(st.st_mode)) {
fprintf(stderr,"\"%s\" is not a directory\n",musicDirArg);
return -1;
}
if(playlistDirArg[0]=='/') {
strcpy(playlistDir,playlistDirArg);
}
......@@ -115,7 +107,23 @@ int main(int argc, char * argv[]) {
return -1;
}
chdir(musicDirArg);
if(musicDirArg[0]=='/') {
strcpy(musicDir,musicDirArg);
}
else {
getcwd(musicDir,MAXPATHLEN-strlen(musicDirArg)-1);
strcat(musicDir,"/");
strcat(musicDir,musicDirArg);
}
strcat(musicDir,"/");
if((stat(musicDir,&st))<0) {
fprintf(stderr,"problem stat'ing \"%s\"\n",musicDirArg);
return -1;
}
if(!S_ISDIR(st.st_mode)) {
fprintf(stderr,"\"%s\" is not a directory\n",musicDirArg);
return -1;
}
initTables();
......@@ -138,7 +146,7 @@ int main(int argc, char * argv[]) {
initInterfaces();
initPlaylist();
daemon(1,0);
daemon(0,0);
dup2(fileno(out),STDOUT_FILENO);
dup2(fileno(err),STDERR_FILENO);
......@@ -152,7 +160,7 @@ int main(int argc, char * argv[]) {
}
clearPlaylist(stderr);
closeAllInterfaces();
freeAllInterfaces();
close(listenSocket);
playerStop(stderr);
......
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
case "$1" in
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing - GNU libit 0.0"
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
aclocal)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acinclude.m4' or \`configure.in'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`configure.in'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acconfig.h' or \`configure.in'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
touch $file
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequirements for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $
errstatus=0
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mp3_decode.h"
#include "player.h"
#include "command.h"
#include "utils.h"
#include "libmad/mad.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <signal.h>
#include <ao/ao.h>
#define INPUT_BUFFER_SIZE 80
#define CHUNK_SIZE 256
#define BUFFERED_CHUNKS 8192 /* 2 MB of buffer */
#define PLAY_SIZE 64
#define TIME_TELL_INTERVAL 0.2
#define READ_BUFFER_SIZE 40960
#define DECODE_BREAK -2
#define DECODE_CONT -1
#define DECODE_OK 0
int mp3_decode_pid = 0;
int mp3_decode_done = 0;
/* this is stolen from mpg321! */
struct audio_dither {
mad_fixed_t error[3];
mad_fixed_t random;
};
unsigned long prng(unsigned long state) {
return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
}
signed long audio_linear_dither(unsigned int bits, mad_fixed_t sample, struct audio_dither *dither) {
unsigned int scalebits;
mad_fixed_t output, mask, random;
enum {
MIN = -MAD_F_ONE,
MAX = MAD_F_ONE - 1
};
sample += dither->error[0] - dither->error[1] + dither->error[2];
dither->error[2] = dither->error[1];
dither->error[1] = dither->error[0] / 2;
output = sample + (1L << (MAD_F_FRACBITS + 1 - bits - 1));
scalebits = MAD_F_FRACBITS + 1 - bits;
mask = (1L << scalebits) - 1;
random = prng(dither->random);
output += (random & mask) - (dither->random & mask);
dither->random = random;
if (output > MAX) {
output = MAX;
if (sample > MAX)
sample = MAX;
}
else if (output < MIN) {
output = MIN;
if (sample < MIN)
sample = MIN;
}
output &= ~mask;
dither->error[0] = sample - output;
return output >> scalebits;
}
/* end of stolen stuff from mpg321 */
/* decoder stuff is based on madlld */
typedef struct _mp3DecodeData {
FILE * fp;
struct mad_stream stream;
struct mad_frame frame;
struct mad_synth synth;
mad_timer_t timer;
unsigned char readBuffer[READ_BUFFER_SIZE];
char outputBuffer[CHUNK_SIZE];
char * outputPtr;
char * outputBufferEnd;
unsigned long frameCount;
int status;
float totalTime;
float elapsedTime;
int start;
} mp3DecodeData;
void initMp3DecodeData(mp3DecodeData * data) {
data->outputPtr = data->outputBuffer;
data->outputBufferEnd = data->outputBuffer+CHUNK_SIZE;
data->frameCount = 0;
data->status = 0;
data->start = 0;
mad_stream_init(&data->stream);
mad_frame_init(&data->frame);
mad_synth_init(&data->synth);
mad_timer_reset(&data->timer);
}
int fillMp3InputBuffer(mp3DecodeData * data) {
size_t readSize;
size_t remaining;
unsigned char * readStart;
if((data->stream).next_frame!=NULL) {
remaining = (data->stream).bufend-(data->stream).next_frame;
memmove(data->readBuffer,(data->stream).next_frame,remaining);
readStart = (data->readBuffer)+remaining;
readSize = READ_BUFFER_SIZE-remaining;
}
else {
readSize = READ_BUFFER_SIZE;
readStart = data->readBuffer,
remaining = 0;
}
readSize = fread(readStart,1,readSize,data->fp);
if(readSize<=0) return -1;
mad_stream_buffer(&data->stream,data->readBuffer,readSize+remaining);
(data->stream).error = 0;
return 0;
}
int decodeNextFrame(mp3DecodeData * data) {
if((data->stream).buffer==NULL || (data->stream).error==MAD_ERROR_BUFLEN)
if(fillMp3InputBuffer(data) < 0) return DECODE_BREAK;
if(mad_frame_decode(&data->frame,&data->stream)) {
if(MAD_RECOVERABLE((data->stream).error)) return DECODE_CONT;
else {
if((data->stream).error==MAD_ERROR_BUFLEN) return DECODE_CONT;
else
{
fprintf(stderr,"unrecoverable frame level error (%s).\n",mad_stream_errorstr(&data->stream));
data->status = 1;
return DECODE_BREAK;
}
}
}
data->frameCount++;
return DECODE_OK;
}
int openMp3(char * file, mp3DecodeData * data) {
int ret;
struct stat filestat;
initMp3DecodeData(data);
if((data->fp = fopen(file,"r"))<=0) {
fprintf(stderr,"problems opening \"%s\"\n",file);
return -1;
}
fstat(fileno(data->fp),&filestat);
while((ret=decodeNextFrame(data))==DECODE_CONT);
data->totalTime = (filestat.st_size*8.0)/(data->frame).header.bitrate;
return ret;
}
void mp3ChildSendData(mp3DecodeData * data, int fd_chunks, int fd_times) {
fd_set fds;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(fd_chunks,&fds);
FD_SET(fd_times,&fds);
while(!data->start && 2!=select(FD_SETSIZE,NULL,&fds,NULL,&tv)) {
usleep(100);
FD_ZERO(&fds);
FD_SET(fd_chunks,&fds);
FD_SET(fd_times,&fds);
}
data->start = 0;
if(write(fd_chunks,data->outputBuffer,CHUNK_SIZE)<0) {
fprintf(stderr,"%s mp3_decode child problems writing\n",COMMAND_RESPOND_ERROR);
exit(-1);
}
if(write(fd_times,&(data->elapsedTime),sizeof(float))<0) {
fprintf(stderr,"%s mp3_decode child problems writing\n",COMMAND_RESPOND_ERROR);
exit(-1);
}
}
int mp3Read(mp3DecodeData * data, int fd_chunks, int fd_times) {
static int i;
static int ret;
static struct audio_dither dither;
mad_timer_add(&data->timer,(data->frame).header.duration);
mad_synth_frame(&data->synth,&data->frame);
data->elapsedTime = ((float)mad_timer_count(data->timer,MAD_UNITS_MILLISECONDS))/1000;
for(i=0;i<(data->synth).pcm.length;i++) {
signed int sample;
sample = (signed int) audio_linear_dither(16,(data->synth).pcm.samples[0][i],&dither);
*(data->outputPtr++) = sample&0xff;
*(data->outputPtr++) = sample>>8;
if(MAD_NCHANNELS(&(data->frame).header)==2)
sample = (signed int) audio_linear_dither(16,(data->synth).pcm.samples[1][i],&dither);
*(data->outputPtr++) = sample&0xff;
*(data->outputPtr++) = sample>>8;
if(data->outputPtr==data->outputBufferEnd) {
mp3ChildSendData(data,fd_chunks,fd_times);
data->outputPtr = data->outputBuffer;
}
}
while((ret=decodeNextFrame(data))==DECODE_CONT);
return ret;
}
ao_device * initAoDeviceFromMp3DecodeData(mp3DecodeData * data) {
ao_sample_format format;
ao_device * device;
int default_driver;
format.bits = 16;
format.rate = (data->frame).header.samplerate;
format.byte_format = AO_FMT_LITTLE;
format.channels = MAD_NCHANNELS(&(data->frame).header);
ao_initialize();
default_driver = ao_default_driver_id();
device = ao_open_live(default_driver, &format, NULL);
return device;
}
void mp3DecodeDataFinalize(mp3DecodeData * data) {
mad_synth_finish(&data->synth);
mad_frame_finish(&data->frame);
mad_stream_finish(&data->stream);
fclose(data->fp);
}
void mp3_decode_parentSigHandler(int sig) {
if(sig==SIGCHLD) {
wait3(NULL,WNOHANG,NULL);
mp3_decode_pid = 0;
mp3_decode_done = 1;
}
}
/* mp3_decode w/ buffering
* this will fork another process
* child process does decoding
* parent process does buffering && playing audio
*/
int mp3_decode(char * file, FILE * in, FILE * out) {
ao_device *device;
mp3DecodeData data;
float time_total;
int fd_chunks[2], fd_times[2];
if(openMp3(file,&data) < 0) {
fprintf(out,"%s Input does not appear to be a mp3 bitstream.\n",PLAYER_ERROR);
fflush(out);
return -1;
}
time_total = data.totalTime;
if(socketpair(AF_UNIX,SOCK_STREAM,0,fd_chunks)<0) {
fprintf(stderr,"%s ogg_decode Problems socketpair'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
if(socketpair(AF_UNIX,SOCK_STREAM,0,fd_times)<0) {
fprintf(stderr,"%s ogg_decode Problems socketpair'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
signal(SIGPIPE,SIG_IGN);
signal(SIGCHLD,mp3_decode_parentSigHandler);
fflush(NULL);
mp3_decode_pid = fork();
if(mp3_decode_pid==0) {
float time;
/* CHILD */
fclose(in);
fclose(out);
close(fd_chunks[0]);
close(fd_times[0]);
while(mp3Read(&data,fd_chunks[1],fd_times[1])!=DECODE_BREAK);
time = -1;
if(write(fd_times[1],&(time),sizeof(float))<0) {
fprintf(stderr,"%s ogg_decode child problems writing\n",COMMAND_RESPOND_ERROR);
exit(-1);
}
mp3DecodeDataFinalize(&data);
close(fd_times[1]);
close(fd_chunks[1]);
exit(0);
/* END OF CHILD */
}
else if(mp3_decode_pid<0) {
fprintf(stderr,"%s mp3_decode Problems fork'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
{
/* PARENT */
float elapsed;
float last_tell = 0;
int pause = 0;
char input[INPUT_BUFFER_SIZE+1];
char ** buffer;
float time[BUFFERED_CHUNKS];
int begin = 0;
int end = 0;
int wrap = 0;
int playsPerChunk = CHUNK_SIZE/PLAY_SIZE;
int currentPlayChunk = 0;
int i;
int quit = 0;
fd_set fds;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
close(fd_chunks[1]);
close(fd_times[1]);
device = initAoDeviceFromMp3DecodeData(&data);
mp3DecodeDataFinalize(&data);
if(device == NULL) {
fprintf(out, "%s Error opening device.\n",PLAYER_ERROR);
fflush(out);
close(fd_chunks[0]);
close(fd_times[0]);
kill(mp3_decode_pid,SIGTERM);
wait(NULL);
return -1;
}
buffer = malloc(sizeof(char *)*BUFFERED_CHUNKS);
for(i=0;i<BUFFERED_CHUNKS;i++) {
buffer[i] = malloc(sizeof(char)*CHUNK_SIZE);
}
fprintf(out,"%s\n",PLAYER_START);
fprintf(out,"%s %f %f\n",PLAYER_TIME,last_tell,time_total);
while(!quit) {
if((begin!=end || !wrap) && !mp3_decode_done) {
FD_ZERO(&fds);
FD_SET(fd_times[0],&fds);
if(select(FD_SETSIZE,&fds,NULL,NULL,&tv)) {
read(fd_times[0],&(time[end]),sizeof(float));
if(time[end]<0) mp3_decode_done = 1;
else {
read(fd_chunks[0],buffer[end],CHUNK_SIZE);
}
end++;
if(end>=BUFFERED_CHUNKS) {
end = 0;
wrap = 1;
}
}
}
if(begin==end && !wrap && mp3_decode_done) quit = 1;
if((begin!=end || wrap) && !pause) {
if(currentPlayChunk==0) elapsed = time[begin];
ao_play(device,buffer[begin]+currentPlayChunk*PLAY_SIZE,PLAY_SIZE);
currentPlayChunk++;
if(currentPlayChunk>=playsPerChunk) {
currentPlayChunk=0;
begin++;
if(begin>=BUFFERED_CHUNKS) {
begin = 0;
wrap = 0;
}
}
if(elapsed-last_tell>=TIME_TELL_INTERVAL) {
last_tell = elapsed;
fprintf(out,"%s %f %f\n",PLAYER_TIME,last_tell,time_total);
fflush(out);
}
}
FD_ZERO(&fds);
FD_SET(fileno(in),&fds);
fflush(in);
if(select(fileno(in)+1,&fds,NULL,NULL,&tv)) {
myFgets(input,INPUT_BUFFER_SIZE,in);
if(strcasecmp(PLAYER_STOP,input)==0) {
quit = 1;
}
else if(strcasecmp(PLAYER_PAUSE,input)==0) {
fprintf(out,"%s\n",PLAYER_PAUSE_GOT);
fflush(out);
pause = !pause;
}
}
if(pause) usleep(1000);
}
if(mp3_decode_pid>0) {
kill(mp3_decode_pid,SIGTERM);
wait(NULL);
}
for(i=0;i<BUFFERED_CHUNKS;i++) {
free(buffer[i]);
}
free(buffer);
close(fd_times[0]);
close(fd_chunks[0]);
ao_close(device);
fprintf(out,"%s\n",PLAYER_DONE);
/* END OF PARENT */
}
return 0;
}
......@@ -16,27 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MPG123_H
#define MPG123_H
#ifndef MP3_DECODE_H
#define MP3_DECODE_H
#include <stdio.h>
void mpg123_sigHandler(int signal);
int mpg123play(FILE * fp, char * file);
int mpg123pause(FILE * fp);
int mpg123stop(FILE * fp);
void mpg123kill();
int mpg123processMessages();
int getMpg123totalTime();
int getMpg123elapsedTime();
int getMpg123state();
int mp3_decode(char * file, FILE * in, FILE * out);
#endif
......@@ -3,7 +3,5 @@ music_directory "/home/shank/mp3"
playlist_directory "/home/shank/playlists"
log_file "/home/shank/mpd.log"
error_file "/home/shank/mpd.error"
mpg123_command "mpg123 -b 2048 -R foo"
mpg123_process "mpg123"
mpg123_ignore_junk "yes"
connection_timeout "60"
max_connections "5"
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "mpg123.h"
#include "command.h"
#include "interface.h"
#include "playlist.h"
#include "player.h"
#include "ls.h"
#include "listen.h"
#include "conf.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#define MAX_BUFFER_LENGTH 1024
#define MAX_ARGS 100
int mpg123_pid = 0;
int mpg123_send = 0;
int mpg123_recv = 0;
int mpg123_stderr = 0;
char mpg123_buffer[MAX_BUFFER_LENGTH+1];
int mpg123_bufferLength = 0;
int mpg123_totalTime = 0;
int mpg123_elapsedTime = 0;
int mpg123_reportedElapsedTime = 0;
int mpg123_state = PLAYER_STATE_STOP;
int mpg123_leavePlay = 0;
int mpg123_leavePause = 0;
int mpg123_error = 0;
int mpg123_lastFrame = 0;
int mpg123_done = 0;
char mpg123_currentSong[MAXPATHLEN+1] = "\0";
int mpg123readline();
void mpg123_sigHandler(int signal) {
if(signal==SIGCHLD) {
wait3(NULL,WNOHANG,NULL);
mpg123_pid = 0;
if(mpg123_recv) close(mpg123_recv);
if(mpg123_send) close(mpg123_send);
if(mpg123_stderr) close(mpg123_stderr);
mpg123_send = 0;
mpg123_recv = 0;
mpg123_stderr = 0;
if(mpg123_state==PLAYER_STATE_PLAY) {
mpg123_leavePlay = 1;
fprintf(stderr,"mpg123 died while playing \"%s\"\n",mpg123_currentSong);
}
mpg123_state = PLAYER_STATE_STOP;
mpg123_currentSong[0] = '\0';
}
}
int mpg123init() {
int fd_send[2], fd_recv[2], fd_stderr[2];
mpg123_error = 0;
mpg123_done = 0;
mpg123_currentSong[0] = '\0';
if(socketpair(AF_UNIX,SOCK_STREAM,0,fd_send)<0) {
fprintf(stderr,"%s Problems socketpair'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
if(socketpair(AF_UNIX,SOCK_STREAM,0,fd_recv)<0) {
fprintf(stderr,"%s Problems socketpair()'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
if(socketpair(AF_UNIX,SOCK_STREAM,0,fd_stderr)<0) {
fprintf(stderr,"%s Problems socketpair()'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
signal(SIGPIPE,SIG_IGN);
signal(SIGCHLD,mpg123_sigHandler);
fflush(NULL);
mpg123_pid = fork();
if(mpg123_pid==0) {
char * args[MAX_ARGS+1];
int i;
i = 0;
args[i] = strtok(strdup((getConf())[CONF_MPG123_COMMAND])," ");
while(i<MAX_ARGS && args[i]) {
i++;
args[i] = strtok(NULL," ");
}
close(listenSocket);
closeAllInterfaces();
close(fd_send[0]);
close(fd_recv[0]);
close(fd_stderr[0]);
dup2(fd_send[1],STDIN_FILENO);
close(fd_send[1]);
dup2(fd_recv[1],STDOUT_FILENO);
close(fd_recv[1]);
dup2(fd_stderr[1],STDERR_FILENO);
close(fd_stderr[1]);
if(execvp(args[0],args)) {
fprintf(stderr,"%s Problems spawning mpg123\n",COMMAND_RESPOND_ERROR);
exit(-1);
}
}
else if(mpg123_pid<0) {
fprintf(stderr,"%s Problems fork()'ing\n",COMMAND_RESPOND_ERROR);
mpg123_pid = 0;
close(fd_send[0]);
close(fd_send[1]);
close(fd_recv[0]);
close(fd_recv[1]);
close(fd_stderr[0]);
close(fd_stderr[1]);
return -1;
}
close(fd_send[1]);
close(fd_recv[1]);
close(fd_stderr[1]);
mpg123_send = fd_send[0];
mpg123_recv = fd_recv[0];
mpg123_stderr = fd_stderr[0];
return 0;
}
int mpg123play(FILE * fp, char * file) {
char string[1024];
if(fp==NULL) fp=stderr;
if(!isMp3(file)) {
fprintf(fp,"%s \"%s\" is not a mp3\n",file,COMMAND_RESPOND_ERROR);
return -1;
}
if(mpg123stop(fp)<0) return -1;
if(mpg123init()<0) {
fprintf(fp,"%s problems init'ing mpg123\n",COMMAND_RESPOND_ERROR);
return -1;
}
if(mpg123_pid<=0) {
printf("OOOPS, mpg123_pid = %i\n",mpg123_pid);
}
mpg123_leavePlay = 0;
mpg123_state = PLAYER_STATE_PLAY;
strcpy(mpg123_currentSong,file);
sprintf(string,"LOAD %s\n",file);
if(write(mpg123_send,string,strlen(string))<0) {
fprintf(fp,"%s problems write'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
/*sleep until status is updated*/
while(!mpg123_leavePlay) {
mpg123processMessages();
usleep(1000);
}
if(mpg123_error) {
fprintf(fp,"%s problems playing \"%s\"\n",COMMAND_RESPOND_ERROR,file);
mpg123kill();
return -1;
}
return 0;
}
int mpg123stop(FILE * fp) {
if(mpg123_pid>0) {
int i;
char string[80];
fd_set fdsr;
struct timeval tv;
FD_ZERO(&fdsr);
FD_SET(mpg123_send,&fdsr);
tv.tv_sec = tv.tv_usec = 0;
if(mpg123_state==PLAYER_STATE_PAUSE) {
if(mpg123pause(fp)<0) return -1;
}
mpg123_state = PLAYER_STATE_STOP;
i = 0;
sprintf(string,"QUIT\n");
if(write(mpg123_send,string,strlen(string))<0) {
fprintf(fp,"%s problems write'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
/* wait upto 3 s to get SIGCHLD */
while(i<30 && mpg123_pid>0) {
usleep(100000); /* wait for 10ms for mpg123 to die */
wait3(NULL,WNOHANG|WUNTRACED,NULL);
while(mpg123readline());
i++;
}
if(mpg123_pid>0) {
fprintf(stderr,"mpg123 didn't die!\n");
mpg123kill();
}
}
mpg123_state = PLAYER_STATE_STOP;
return 0;
}
int mpg123pause(FILE * fp) {
char string[1024];
mpg123processMessages();
if(mpg123_pid>0 && !mpg123_done) {
sprintf(string,"PAUSE\n");
if(write(mpg123_send,string,strlen(string))<0) {
fprintf(fp,"%s problems write'ing\n",COMMAND_RESPOND_ERROR);
}
mpg123_leavePause = 0;
while(!mpg123_leavePause) {
mpg123processMessages();
usleep(1000);
}
if(mpg123_state==PLAYER_STATE_PLAY) {
mpg123_state = PLAYER_STATE_PAUSE;
}
else if(mpg123_state==PLAYER_STATE_PAUSE) {
mpg123_state = PLAYER_STATE_PLAY;
}
}
return 0;
}
int mpg123readline() {
int rc;
fd_set fdsr;
struct timeval tv;
FD_ZERO(&fdsr);
FD_SET(mpg123_recv,&fdsr);
tv.tv_sec = tv.tv_usec = 0;
while(select(mpg123_recv+1,&fdsr,NULL,NULL,&tv)==1) {
FD_ZERO(&fdsr);
FD_SET(mpg123_recv,&fdsr);
rc = read(mpg123_recv,mpg123_buffer+mpg123_bufferLength,1);
if(rc<=0) {
/*mpg123_pid = 0;
mpg123_state = PLAYER_STATE_STOP;*/
return 0;
}
if(mpg123_buffer[mpg123_bufferLength]=='\0' || mpg123_buffer[mpg123_bufferLength]=='\n' || mpg123_bufferLength == MAX_BUFFER_LENGTH) {
mpg123_buffer[mpg123_bufferLength] = '\0';
mpg123_bufferLength = 0;
return -1;
}
mpg123_bufferLength++;
}
return 0;
}
int mpg123gotErrors() {
int ret = 0;
fd_set fdsr;
struct timeval tv;
FD_ZERO(&fdsr);
FD_SET(mpg123_stderr,&fdsr);
tv.tv_sec = tv.tv_usec = 0;
if(select(mpg123_stderr+1,&fdsr,NULL,NULL,&tv)==1) {
int rc;
char errorBuffer[MAX_BUFFER_LENGTH];
int errorBufferLength = 0;
while(1) {
rc = read(mpg123_stderr,errorBuffer+errorBufferLength,1);
if(rc<=0) {
return 0;
}
if(errorBuffer[errorBufferLength]=='\0' || errorBuffer[errorBufferLength]=='\n' || errorBufferLength == MAX_BUFFER_LENGTH) {
errorBuffer[errorBufferLength] = '\0';
errorBufferLength = 0;
if(0==strncmp("Junk at the beginning",errorBuffer,strlen("Junk"))) {
if(0!=strcmp("yes",(getConf())[CONF_MPG123_IGNORE_JUNK])) {
fprintf(stderr,"%s file: \"%s\" : %s\n",COMMAND_RESPOND_ERROR,mpg123_currentSong,errorBuffer);
}
return 0;
}
fprintf(stderr,"%s file: \"%s\" : %s\n",COMMAND_RESPOND_ERROR,mpg123_currentSong,errorBuffer);
mpg123kill();
return 1;
}
errorBufferLength++;
}
}
return ret;
}
int mpg123processMessages() {
if(mpg123_pid>0) {
while(mpg123readline()) {
char * c[6];
int i;
c[0] = strtok(mpg123_buffer," \t");
if(c[0]) {
for(i=1;i<6;i++) {
c[i] = c[i-1] ? strtok(NULL," \t") : NULL;
}
if(0==strcmp(c[0],"@F")) {
mpg123_totalTime = atof(c[3])+atof(c[4])+0.5;
mpg123_reportedElapsedTime = atof(c[3])+0.5;
if(atof(c[3])<1) mpg123_leavePlay = 1;
mpg123_lastFrame = time(NULL);
}
else if(0==strcmp(c[0],"@P")) {
if(mpg123_state==PLAYER_STATE_PLAY && atoi(c[1])==PLAYER_STATE_STOP) {
if(!mpg123_leavePlay) {
mpg123_leavePlay=1; mpg123_error=1;
}
mpg123_done = 1;
}
else if(mpg123_state==PLAYER_STATE_PLAY && atoi(c[1])==PLAYER_STATE_PAUSE) {
mpg123_leavePause = 1;
}
else if(mpg123_state==PLAYER_STATE_PAUSE && atoi(c[1])==PLAYER_STATE_PLAY) {
mpg123_leavePause = 1;
}
//mpg123_state = atoi(c[1]);
}
/*else if(0==strcmp(c[0],"@I")) {
mpg123_leavePlay = 1;
}*/
else if(0==strcmp(c[0],"@E")) {
mpg123_error = 1;
}
}
}
if(mpg123gotErrors()) {
mpg123_error = 1;
mpg123_leavePlay = 1;
}
if(mpg123_state==PLAYER_STATE_PAUSE) mpg123_lastFrame = time(NULL);
mpg123_elapsedTime = mpg123_reportedElapsedTime+time(NULL)-mpg123_lastFrame;
if(!mpg123_error && mpg123_leavePlay && mpg123_elapsedTime>=mpg123_totalTime) {
mpg123stop(stderr);
}
}
return 0;
}
void mpg123kill() {
char * string;
string = malloc(strlen("killall -KILL ")+strlen((getConf())[CONF_MPG123_PROCESS])+1);
string[0] = '\0';
strcat(string,"killall -KILL ");
strcat(string,(getConf())[CONF_MPG123_PROCESS]);
if(mpg123_pid>0) system(string);
free(string);
mpg123_state = PLAYER_STATE_STOP;
mpg123_sigHandler(SIGCHLD);
}
int getMpg123elapsedTime() {
return mpg123_elapsedTime;
}
int getMpg123totalTime() {
return mpg123_totalTime;
}
int getMpg123state() {
return mpg123_state;
}
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_OGG
#include "ogg.h"
#include "ogg_decode.h"
#include "command.h"
#include "interface.h"
#include "playlist.h"
#include "ls.h"
#include "utils.h"
#include "player.h"
#include "listen.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <vorbis/vorbisfile.h>
#include <ao/ao.h>
#define MAX_BUFFER_LENGTH 1024
int ogg_pid = 0;
int ogg_state = PLAYER_STATE_STOP;
int ogg_elapsedTime = 0;
int ogg_totalTime = 0;
int ogg_send = -1;
int ogg_recv = -1;
int ogg_leavePlay = 1;
int ogg_leavePause = 1;
char ogg_buffer[MAX_BUFFER_LENGTH+1];
int ogg_bufferLength = 0;
char ogg_currentSong[MAXPATHLEN+1] = "\0";
void ogg_sigHandler(int signal) {
if(signal==SIGCHLD) {
wait3(NULL,WNOHANG,NULL);
ogg_pid = 0;
close(ogg_recv);
close(ogg_send);
ogg_leavePause = 1;
if(ogg_state==PLAYER_STATE_PLAY) {
ogg_leavePlay = 1;
fprintf(stderr,"ogg died while playing \%s\"\n",ogg_currentSong);
}
ogg_state = PLAYER_STATE_STOP;
ogg_currentSong[0] = '\0';
}
}
int oggInit(char * file) {
int fd_send[2], fd_recv[2];
if(socketpair(AF_UNIX,SOCK_STREAM,0,fd_send)<0) {
fprintf(stderr,"%s ogg Problems socketpair'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
if(socketpair(AF_UNIX,SOCK_STREAM,0,fd_recv)<0) {
fprintf(stderr,"%s ogg Problems socketpair()'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
signal(SIGPIPE,SIG_IGN);
signal(SIGCHLD,ogg_sigHandler);
fflush(NULL);
ogg_pid = fork();
if(ogg_pid==0) {
FILE * in;
FILE * out;
close(listenSocket);
closeAllInterfaces();
close(fd_send[0]);
close(fd_recv[0]);
in = fdopen(fd_send[1],"r");
out = fdopen(fd_recv[1],"w");
if(ogg_decode(file,in,out)<0) {
fprintf(stderr,"%s Problems spawning ogg\n",COMMAND_RESPOND_ERROR);
fclose(in);
fclose(out);
exit(-1);
}
fclose(in);
fclose(out);
exit(0);
}
else if(ogg_pid<0) {
fprintf(stderr,"%s ogg Problems fork()'ing\n",COMMAND_RESPOND_ERROR);
ogg_pid = 0;
close(fd_send[0]);
close(fd_send[1]);
close(fd_recv[0]);
close(fd_recv[1]);
return -1;
}
close(fd_send[1]);
close(fd_recv[1]);
ogg_send = fd_send[0];
ogg_recv = fd_recv[0];
return 0;
}
int oggPlay(FILE * fp, char * file) {
if(fp==NULL) fp=stderr;
if(!isOgg(file)) {
fprintf(fp,"%s \"%s\" is not a ogg\n",file,COMMAND_RESPOND_ERROR);
return -1;
}
if(oggStop(fp)<0) return -1;
if(oggInit(file)<0) {
fprintf(fp,"%s problems init'ing ogg\n",COMMAND_RESPOND_ERROR);
return -1;
}
if(ogg_pid<=0) {
printf("OOOPS, ogg_pid = %i\n",ogg_pid);
}
ogg_leavePlay = 0;
ogg_currentSong[0] = '\0';
strcpy(ogg_currentSong,file);
ogg_state = PLAYER_STATE_PLAY;
/*sleep until status is updated*/
while(!ogg_leavePlay) {
oggProcessMessages();
usleep(1000);
}
return 0;
}
int oggStop(FILE * fp) {
if(ogg_pid>0) {
char string[1024];
ogg_state = PLAYER_STATE_STOP;
sprintf(string,"%s\n",OGG_STOP);
if(write(ogg_send,string,strlen(string))<0) {
fprintf(fp,"%s problems write'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
waitpid(ogg_pid,NULL,0);
}
ogg_state = PLAYER_STATE_STOP;
return 0;
}
int oggPause(FILE * fp) {
char string[1024];
if(ogg_pid>0) {
ogg_leavePause = 0;
sprintf(string,"%s\n",OGG_PAUSE);
if(write(ogg_send,string,strlen(string))<0) {
fprintf(fp,"%s problems write'ing\n",COMMAND_RESPOND_ERROR);
}
if(ogg_state==PLAYER_STATE_PLAY) {
ogg_state = PLAYER_STATE_PAUSE;
}
else if(ogg_state==PLAYER_STATE_PAUSE) {
ogg_state = PLAYER_STATE_PLAY;
}
while(!ogg_leavePause) {
oggProcessMessages();
usleep(1000);
}
}
return 0;
}
int oggReadline() {
fd_set fdsr;
struct timeval tv;
FD_ZERO(&fdsr);
FD_SET(ogg_recv,&fdsr);
tv.tv_sec = tv.tv_usec = 0;
if(select(ogg_recv+1,&fdsr,NULL,NULL,&tv)==1) {
int rc;
while(1) {
rc = read(ogg_recv,ogg_buffer+ogg_bufferLength,1);
if(rc<=0) {
return -1;
}
if(ogg_buffer[ogg_bufferLength]=='\0' || ogg_buffer[ogg_bufferLength]=='\n' || ogg_bufferLength == MAX_BUFFER_LENGTH) {
ogg_buffer[ogg_bufferLength] = '\0';
ogg_bufferLength = 0;
return -1;
}
ogg_bufferLength++;
}
}
return 0;
}
int oggProcessMessages() {
if(ogg_pid>0) {
while(oggReadline()) {
char * c[4];
c[0] = strtok(ogg_buffer," ");
if(c[0]) {
if(0==strcmp(c[0],OGG_TIME)) {
c[1] = strtok(NULL," ");
c[2] = strtok(NULL," ");
ogg_totalTime = atof(c[2])+0.5;
ogg_elapsedTime = atof(c[1])+0.5;
}
else if(0==strcmp(c[0],OGG_DONE)) {
wait3(NULL,WNOHANG,NULL);
}
else if(0==strcmp(c[0],OGG_ERROR)) {
fprintf(stderr,"ogg error: file \"%s\" : %s\n",ogg_currentSong,c[1]);
}
else if(0==strcmp(c[0],OGG_START)) {
ogg_leavePlay = 1;
}
else if(0==strcmp(c[0],OGG_PAUSE_GOT)) {
ogg_leavePause = 1;
}
}
}
}
return 0;
}
void oggKill() {
if(ogg_pid>0) {
kill(ogg_pid,SIGKILL);
wait3(NULL,WNOHANG,NULL);
}
}
int getOggElapsedTime() {
return ogg_elapsedTime;
}
int getOggTotalTime() {
return ogg_totalTime;
}
int getOggState() {
return ogg_state;
}
#endif
......@@ -18,6 +18,7 @@
#ifdef HAVE_OGG
#include "ogg_decode.h"
#include "player.h"
#include "command.h"
#include "utils.h"
......@@ -42,14 +43,14 @@
#define INPUT_BUFFER_SIZE 80
int decode_pid = 0;
int decode_done = 0;
int ogg_decode_pid = 0;
int ogg_decode_done = 0;
void ogg_decode_parentSigHandler(int sig) {
if(sig==SIGCHLD) {
wait3(NULL,WNOHANG,NULL);
decode_pid = 0;
decode_done = 1;
ogg_decode_pid = 0;
ogg_decode_done = 1;
}
}
......@@ -68,7 +69,7 @@ int ogg_decode(char * file, FILE * in, FILE * out) {
int fd_chunks[2], fd_times[2];
if(!(oggfp = fopen(file,"r")) || ov_open(oggfp, &vf, NULL, 0) < 0) {
fprintf(out,"%s Input does not appear to be an Ogg bitstream.\n",OGG_ERROR);
fprintf(out,"%s Input does not appear to be an Ogg bitstream.\n",PLAYER_ERROR);
fflush(out);
return -1;
}
......@@ -97,9 +98,9 @@ int ogg_decode(char * file, FILE * in, FILE * out) {
fflush(NULL);
decode_pid = fork();
ogg_decode_pid = fork();
if(decode_pid==0) {
if(ogg_decode_pid==0) {
/* CHILD */
char chunk[CHUNK_SIZE];
float time;
......@@ -157,7 +158,7 @@ int ogg_decode(char * file, FILE * in, FILE * out) {
/* END OF CHILD */
}
else if(decode_pid<0) {
else if(ogg_decode_pid<0) {
fprintf(stderr,"%s ogg_decode Problems fork'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
......@@ -177,6 +178,11 @@ int ogg_decode(char * file, FILE * in, FILE * out) {
int currentPlayChunk = 0;
int i;
int quit = 0;
fd_set fds;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
close(fd_chunks[1]);
close(fd_times[1]);
......@@ -188,11 +194,11 @@ int ogg_decode(char * file, FILE * in, FILE * out) {
device = ao_open_live(default_driver,&format,NULL);
if(device == NULL) {
fprintf(out, "%s Error opening device.\n",OGG_ERROR);
fprintf(out, "%s Error opening device.\n",PLAYER_ERROR);
fflush(out);
close(fd_chunks[0]);
close(fd_times[0]);
kill(decode_pid,SIGTERM);
kill(ogg_decode_pid,SIGTERM);
wait(NULL);
return -1;
}
......@@ -202,19 +208,15 @@ int ogg_decode(char * file, FILE * in, FILE * out) {
buffer[i] = malloc(sizeof(char)*CHUNK_SIZE);
}
fprintf(out,"%s\n",OGG_START);
fprintf(out,"%s %f %f\n",OGG_TIME,last_tell,time_total);
fprintf(out,"%s\n",PLAYER_START);
fprintf(out,"%s %f %f\n",PLAYER_TIME,last_tell,time_total);
while(!quit) {
if((begin!=end || !wrap) && !decode_done) {
static fd_set fds;
static struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
if((begin!=end || !wrap) && !ogg_decode_done) {
FD_ZERO(&fds);
FD_SET(fd_times[0],&fds);
if(select(FD_SETSIZE,&fds,NULL,NULL,&tv)) {
read(fd_times[0],&(time[end]),sizeof(float));
if(time[end]<0) decode_done = 1;
if(time[end]<0) ogg_decode_done = 1;
else {
read(fd_chunks[0],buffer[end],CHUNK_SIZE);
}
......@@ -225,7 +227,7 @@ int ogg_decode(char * file, FILE * in, FILE * out) {
}
}
}
if(begin==end && !wrap && decode_done) quit = 1;
if(begin==end && !wrap && ogg_decode_done) quit = 1;
if((begin!=end || wrap) && !pause) {
if(currentPlayChunk==0) elapsed = time[begin];
ao_play(device,buffer[begin]+currentPlayChunk*PLAY_SIZE,PLAY_SIZE);
......@@ -240,35 +242,29 @@ int ogg_decode(char * file, FILE * in, FILE * out) {
}
if(elapsed-last_tell>=TIME_TELL_INTERVAL) {
last_tell = elapsed;
fprintf(out,"%s %f %f\n",OGG_TIME,last_tell,time_total);
fprintf(out,"%s %f %f\n",PLAYER_TIME,last_tell,time_total);
fflush(out);
}
}
{
static fd_set fds;
static struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(fileno(in),&fds);
fflush(in);
if(select(fileno(in)+1,&fds,NULL,NULL,&tv)) {
myFgets(input,INPUT_BUFFER_SIZE,in);
if(strcasecmp(OGG_STOP,input)==0) {
quit = 1;
}
else if(strcasecmp(OGG_PAUSE,input)==0) {
fprintf(out,"%s\n",OGG_PAUSE_GOT);
fflush(out);
pause = !pause;
}
FD_ZERO(&fds);
FD_SET(fileno(in),&fds);
fflush(in);
if(select(fileno(in)+1,&fds,NULL,NULL,&tv)) {
myFgets(input,INPUT_BUFFER_SIZE,in);
if(strcasecmp(PLAYER_STOP,input)==0) {
quit = 1;
}
else if(strcasecmp(PLAYER_PAUSE,input)==0) {
fprintf(out,"%s\n",PLAYER_PAUSE_GOT);
fflush(out);
pause = !pause;
}
}
if(pause) usleep(1000);
}
if(decode_pid>0) {
kill(decode_pid,SIGTERM);
if(ogg_decode_pid>0) {
kill(ogg_decode_pid,SIGTERM);
wait(NULL);
}
......@@ -279,8 +275,10 @@ int ogg_decode(char * file, FILE * in, FILE * out) {
close(fd_times[0]);
close(fd_chunks[0]);
ao_close(device);
fprintf(out,"%s\n",OGG_DONE);
fprintf(out,"%s\n",PLAYER_DONE);
/* END OF PARENT */
}
......
......@@ -21,15 +21,6 @@
#include <stdio.h>
#define OGG_ERROR "@ERROR"
#define OGG_START "@START"
#define OGG_TIME "@TIME"
#define OGG_DONE "@DONE"
#define OGG_PAUSE_GOT "@PAUSE_GOT"
#define OGG_STOP "stop"
#define OGG_PAUSE "pause"
int ogg_decode(char * file, FILE * in, FILE * out);
#endif
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "path.h"
#include <string.h>
char musicDir[MAXPATHLEN+1];
char playlistDir[MAXPATHLEN+1];
char * rmp2amp(char * relativePath) {
static char absolutePath[MAXPATHLEN+1] = "";
static int musicDirLen;
if(absolutePath[0]=='\0') {
strcpy(absolutePath,musicDir);
musicDirLen = strlen(musicDir);
}
strcpy(&(absolutePath[musicDirLen]),relativePath);
return absolutePath;
}
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PATH_H
#define PATH_H
#include <sys/param.h>
extern char musicDir[MAXPATHLEN+1];
extern char playlistDir[MAXPATHLEN+1];
/* relative music path to absolute music path
* char * passed is a static variable, so don't free it
*/
char * rmp2amp(char * file);
#endif
......@@ -17,15 +17,16 @@
*/
#include "player.h"
#include "mpg123.h"
#include "mp3_decode.h"
#ifdef HAVE_OGG
#include "ogg.h"
#include "ogg_decode.h"
#endif
#include "command.h"
#include "interface.h"
#include "playlist.h"
#include "ls.h"
#include "listen.h"
#include "path.h"
#include <stdio.h>
#include <unistd.h>
......@@ -37,107 +38,253 @@
#include <string.h>
#include <errno.h>
#define PLAYER_NONE 0
#define PLAYER_MPG123 1
#define PLAYER_OGG 2
#define PLAYER_TYPE_MP3 0
#define PLAYER_TYPE_OGG 1
int player_type = PLAYER_NONE;
#define MAX_BUFFER_LENGTH 1024
int playerPlay(FILE * fp, char * file) {
if(playerStop(fp)<0) return -1;
int player_pid = 0;
int player_state = PLAYER_STATE_STOP;
int player_elapsedTime = 0;
int player_totalTime = 0;
int player_send = -1;
int player_recv = -1;
int player_leavePlay = 1;
int player_leavePause = 1;
char player_buffer[MAX_BUFFER_LENGTH+1];
int player_bufferLength = 0;
char player_currentSong[MAXPATHLEN+1] = "\0";
if(isMp3(file)) {
player_type = PLAYER_MPG123;
return mpg123play(fp,file);
}
#ifdef HAVE_OGG
else if(isOgg(file)) {
player_type = PLAYER_OGG;
return oggPlay(fp,file);
void player_sigHandler(int signal) {
if(signal==SIGCHLD) {
wait3(NULL,WNOHANG,NULL);
player_pid = 0;
close(player_recv);
close(player_send);
player_leavePause = 1;
player_leavePlay = 1;
player_state = PLAYER_STATE_STOP;
player_currentSong[0] = '\0';
}
#endif
fprintf(fp,"%s problems with file\n",COMMAND_RESPOND_ERROR);
return -1;
}
int playerStop(FILE * fp) {
if(player_type==PLAYER_MPG123) {
if(mpg123stop(fp)<0) return -1;
int playerInit(char * file, int playerType) {
int fd_send[2], fd_recv[2];
if(socketpair(AF_UNIX,SOCK_STREAM,0,fd_send)<0) {
fprintf(stderr,"%s player Problems socketpair'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
#ifdef HAVE_OGG
else if(player_type==PLAYER_OGG) {
if(oggStop(fp)<0) return -1;
if(socketpair(AF_UNIX,SOCK_STREAM,0,fd_recv)<0) {
fprintf(stderr,"%s player Problems socketpair()'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
#endif
player_type = PLAYER_NONE;
signal(SIGPIPE,SIG_IGN);
signal(SIGCHLD,player_sigHandler);
return 0;
}
fflush(NULL);
int playerPause(FILE * fp) {
if(player_type==PLAYER_MPG123) {
if(mpg123pause(fp)<0) return -1;
}
player_pid = fork();
if(player_pid==0) {
FILE * in;
FILE * out;
close(listenSocket);
freeAllInterfaces();
close(fd_send[0]);
close(fd_recv[0]);
in = fdopen(fd_send[1],"r");
out = fdopen(fd_recv[1],"w");
if(playerType==PLAYER_TYPE_MP3 && mp3_decode(rmp2amp(file),in,out)<0) {
fprintf(stderr,"%s Problems spawning mp3\n",COMMAND_RESPOND_ERROR);
fclose(in);
fclose(out);
exit(-1);
}
#ifdef HAVE_OGG
else if(player_type==PLAYER_OGG) {
if(oggPause(fp)<0) return -1;
}
if(playerType==PLAYER_TYPE_OGG && ogg_decode(rmp2amp(file),in,out)<0) {
fprintf(stderr,"%s Problems spawning ogg\n",COMMAND_RESPOND_ERROR);
fclose(in);
fclose(out);
exit(-1);
}
#endif
fclose(in);
fclose(out);
exit(0);
}
else if(player_pid<0) {
fprintf(stderr,"%s player Problems fork()'ing\n",COMMAND_RESPOND_ERROR);
player_pid = 0;
close(fd_send[0]);
close(fd_send[1]);
close(fd_recv[0]);
close(fd_recv[1]);
return -1;
}
close(fd_send[1]);
close(fd_recv[1]);
player_send = fd_send[0];
player_recv = fd_recv[0];
return 0;
}
void playerKill() {
mpg123kill();
#ifdef HAVE_OGG
oggKill();
#endif
}
int playerPlay(FILE * fp, char * file) {
int playerType;
void playerProcessMessages() {
mpg123processMessages();
#ifdef HAVE_OGG
oggProcessMessages();
if(fp==NULL) fp=stderr;
if(isMp3(file)) playerType = PLAYER_TYPE_MP3;
#ifdef HAVE_OGG
else if(isOgg(file)) playerType = PLAYER_TYPE_OGG;
#endif
}
else {
fprintf(fp,"%s \"%s\" is not a file or unknown file type\n",file,COMMAND_RESPOND_ERROR);
return -1;
}
int getPlayerTotalTime() {
if(player_type==PLAYER_MPG123) {
return getMpg123totalTime();
if(playerStop(fp)<0) return -1;
if(playerInit(file,playerType)<0) {
fprintf(fp,"%s problems init'ing player\n",COMMAND_RESPOND_ERROR);
return -1;
}
#ifdef HAVE_OGG
else if(player_type==PLAYER_OGG) {
return getOggTotalTime();
if(player_pid<=0) {
printf("OOOPS, player_pid = %i\n",player_pid);
}
player_leavePlay = 0;
player_currentSong[0] = '\0';
strcpy(player_currentSong,file);
player_state = PLAYER_STATE_PLAY;
/*sleep until status is updated*/
while(!player_leavePlay) {
playerProcessMessages();
usleep(1000);
}
#endif
return 0;
}
int getPlayerElapsedTime() {
if(player_type==PLAYER_MPG123) {
return getMpg123elapsedTime();
}
#ifdef HAVE_OGG
else if(player_type==PLAYER_OGG) {
return getOggElapsedTime();
int playerStop(FILE * fp) {
if(player_pid>0) {
char string[1024];
player_state = PLAYER_STATE_STOP;
sprintf(string,"%s\n",PLAYER_STOP);
if(write(player_send,string,strlen(string))<0) {
fprintf(fp,"%s problems write'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
waitpid(player_pid,NULL,0);
}
#endif
player_state = PLAYER_STATE_STOP;
return 0;
}
int getPlayerState() {
if(player_type==PLAYER_MPG123) {
return getMpg123state();
int playerPause(FILE * fp) {
char string[1024];
if(player_pid>0) {
player_leavePause = 0;
sprintf(string,"%s\n",PLAYER_PAUSE);
if(write(player_send,string,strlen(string))<0) {
fprintf(fp,"%s problems write'ing\n",COMMAND_RESPOND_ERROR);
}
if(player_state==PLAYER_STATE_PLAY) {
player_state = PLAYER_STATE_PAUSE;
}
else if(player_state==PLAYER_STATE_PAUSE) {
player_state = PLAYER_STATE_PLAY;
}
while(!player_leavePause) {
playerProcessMessages();
usleep(1000);
}
}
#ifdef HAVE_OGG
else if(player_type==PLAYER_OGG) {
return getOggState();
return 0;
}
void playerKill() {
if(player_pid>0) {
kill(player_pid,SIGKILL);
wait3(NULL,WNOHANG,NULL);
}
#endif
}
int playerReadline() {
fd_set fdsr;
struct timeval tv;
FD_ZERO(&fdsr);
FD_SET(player_recv,&fdsr);
tv.tv_sec = tv.tv_usec = 0;
if(select(player_recv+1,&fdsr,NULL,NULL,&tv)==1) {
int rc;
while(1) {
rc = read(player_recv,player_buffer+player_bufferLength,1);
if(rc<=0) return -1;
if(player_buffer[player_bufferLength]=='\0' || player_buffer[player_bufferLength]=='\n' || player_bufferLength == MAX_BUFFER_LENGTH) {
player_buffer[player_bufferLength] = '\0';
player_bufferLength = 0;
return -1;
}
player_bufferLength++;
}
}
return 0;
}
void playerProcessMessages() {
if(player_pid>0) {
while(playerReadline()) {
char * c[4];
c[0] = strtok(player_buffer," ");
if(c[0]) {
if(0==strcmp(c[0],PLAYER_TIME)) {
c[1] = strtok(NULL," ");
c[2] = strtok(NULL," ");
player_totalTime = atof(c[2])+0.5;
player_elapsedTime = atof(c[1])+0.5;
}
else if(0==strcmp(c[0],PLAYER_DONE)) {
wait3(NULL,WNOHANG,NULL);
}
else if(0==strcmp(c[0],PLAYER_ERROR)) {
fprintf(stderr,"player error: file \"%s\" : %s\n",player_currentSong,c[1]);
}
else if(0==strcmp(c[0],PLAYER_START)) {
player_leavePlay = 1;
}
else if(0==strcmp(c[0],PLAYER_PAUSE_GOT)) {
player_leavePause = 1;
}
}
}
}
}
int getPlayerElapsedTime() {
return player_elapsedTime;
}
int getPlayerTotalTime() {
return player_totalTime;
}
int getPlayerState() {
return player_state;
}
......@@ -25,6 +25,15 @@
#define PLAYER_STATE_PAUSE 1
#define PLAYER_STATE_PLAY 2
#define PLAYER_ERROR "@ERROR"
#define PLAYER_START "@START"
#define PLAYER_TIME "@TIME"
#define PLAYER_DONE "@DONE"
#define PLAYER_PAUSE_GOT "@PAUSE_GOT"
#define PLAYER_STOP "stop"
#define PLAYER_PAUSE "pause"
extern int player_totalTime;
extern int player_elapsedTime;
extern int player_state;
......@@ -45,6 +54,4 @@ int getPlayerElapsedTime();
int getPlayerState();
void nextSongInPlaylistIfPlayerStopped();
#endif
......@@ -38,11 +38,11 @@
* */
Playlist playlist;
char playlistDir[MAXPATHLEN+1];
int playlist_state = PLAYLIST_STATE_STOP;
void initPlaylist() {
playlist.length = 0;
playlist.repeat = 0;
memset(playlist.songs,(int)NULL,sizeof(char *)*PLAYLIST_MAX_LENGTH);
}
......@@ -192,11 +192,29 @@ int nextSongInPlaylist(FILE * fp) {
if(playlist.current<playlist.length-1) {
return playPlaylist(fp,playlist.current+1);
}
else if(playlist.repeat) {
return playPlaylist(fp,0);
}
else return stopPlaylist(fp);;
return 0;
}
int getPlaylistRepeatStatus() {
return playlist.repeat;
}
int setPlaylistRepeatStatus(FILE * fp, int status) {
if(status!=0 && status!=1) {
fprintf(fp,"%s \"%i\" is not 0 or 1\n",COMMAND_RESPOND_ERROR,status);
return -1;
}
playlist.repeat = status;
return 0;
}
int previousSongInPlaylist(FILE * fp) {
if(playlist_state!=PLAYLIST_STATE_PLAY) {
fprintf(fp,"%s not currently playing\n",COMMAND_RESPOND_ERROR);
......
......@@ -24,15 +24,14 @@
#include <stdio.h>
#include <sys/param.h>
#define PLAYLIST_FILE_SUFFIX "m3u"
#define PLAYLIST_MAX_LENGTH 1024
extern char playlistDir[MAXPATHLEN+1];
#define PLAYLIST_FILE_SUFFIX "m3u"
#define PLAYLIST_MAX_LENGTH 2048
typedef struct _Playlist {
Song * songs[PLAYLIST_MAX_LENGTH];
int length;
int current;
int repeat;
} Playlist;
void initPlaylist();
......@@ -53,6 +52,8 @@ int playPlaylist(FILE * fp, int song);
int nextSongInPlaylist(FILE * fp);
void nextSongInPlaylistIfPlayerStopped();
int previousSongInPlaylist(FILE * fp);
int shufflePlaylist(FILE * fp);
......@@ -63,4 +64,8 @@ int deletePlaylist(FILE * fp, char * file);
int loadPlaylist(FILE * fp, char * file);
int getPlaylistRepeatStatus();
int setPlaylistRepeatStatus(FILE * fp, int status);
#endif
......@@ -34,6 +34,8 @@
#include <stdlib.h>
#include <string.h>
char musicDir[MAXPATHLEN+1];
Song * newSong(char * file) {
Song * song = malloc(sizeof(Song));
......
......@@ -17,6 +17,7 @@
*/
#include "tag.h"
#include "path.h"
#include <sys/stat.h>
#include <stdlib.h>
......@@ -72,9 +73,9 @@ MpdTag * id3Dup(char * file) {
id3Tag * tag = newId3();
MpdTag * ret;
if(0==get_id3v2_tag(tag,file)) stripSpaces(tag);
else if(0==get_id3v22_tag(tag,file)) stripSpaces(tag);
else if(0==get_id3v1_tag(tag,file)) stripSpaces(tag);
if(0==get_id3v2_tag(tag,rmp2amp(file))) stripSpaces(tag);
else if(0==get_id3v22_tag(tag,rmp2amp(file))) stripSpaces(tag);
else if(0==get_id3v1_tag(tag,rmp2amp(file))) stripSpaces(tag);
else {
free(tag);
return NULL;
......@@ -101,7 +102,7 @@ MpdTag * oggCommentDup(char * file) {
char * s1;
char * s2;
if(!(fp = fopen(file,"r"))) return NULL;
if(!(fp = fopen(rmp2amp(file),"r"))) return NULL;
if(ov_open(fp,&vf,NULL,0)<0) return NULL;
comments = ov_comment(&vf,-1)->user_comments;
......
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "volume.h"
#include "command.h"
#include "conf.h"
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#ifndef NO_LINUX_OSS_MIXER
#include <linux/soundcard.h>
#endif
int getVolumeLevel() {
#ifndef NO_LINUX_OSS_MIXER
char * device = (getConf())[CONF_MIXER_DEVICE];
int fd;
int left, right, level;
if((fd = open(device,O_RDONLY))<0) {
fprintf(stderr, "%s unable to mixer \"%s\"\n",COMMAND_RESPOND_ERROR,device);
return -1;
}
if(ioctl(fd,MIXER_READ(SOUND_MIXER_VOLUME),&level) < 0) {
close(fd);
fprintf(stderr,"%s unable to read volume\n",COMMAND_RESPOND_ERROR);
return -1;
}
close(fd);
left = level & 0xff;
right = (level & 0xff00) >> 8;
if(left!=right) {
fprintf(stderr,"%s volume for left and right is not the same, \"%i\" and \"%i\"\n",COMMAND_RESPOND_ERROR,left,right);
}
return left;
#else
return -1;
#endif
}
int changeVolumeLevel(FILE * fp, int change) {
#ifndef NO_LINUX_OSS_MIXER
int current;
int new;
int level;
int fd;
char * device = (getConf())[CONF_MIXER_DEVICE];
if((current = getVolumeLevel()) < 0) {
fprintf(fp,"%s problem getting current volume\n",COMMAND_RESPOND_ERROR);
return -1;
}
new = current+change;
if(new<0) new = 0;
else if(new>100) new = 100;
level = (new << 8) + new;
if((fd = open(device,O_RDONLY)) < 0) {
fprintf(fp,"%s problems opening mixer device \"%s\"\n",COMMAND_RESPOND_ERROR,device);
return -1;
}
if(ioctl(fd,MIXER_WRITE(SOUND_MIXER_VOLUME),&level) < 0) {
fprintf(fp,"%s problems setting volume\n",COMMAND_RESPOND_ERROR);
close(fd);
return -1;
}
close(fd);
return 0;
#else
fprintf(fp,"%s no volume support!\n",COMMAND_RESPOND_ERROR);
return -1;
#endif
}
......@@ -16,31 +16,13 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef OGG_H
#define OGG_H
#ifndef VOLUME_H
#define VOLUME_H
#include <stdio.h>
#define OGG_STATE_STOP 0
#define OGG_STATE_PAUSE 1
#define OGG_STATE_PLAY 2
int getVolumeLevel();
void ogg_sigHandler(int signal);
int oggPlay(FILE * fp, char * file);
int oggPause(FILE * fp);
int oggStop(FILE * fp);
void oggKill();
int oggProcessMessages();
int getOggTotalTime();
int getOggElapsedTime();
int getOggState();
int changeVolumeLevel(FILE * fp, int change);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment