aboutsummaryrefslogtreecommitdiff
path: root/lib/liblame/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'lib/liblame/frontend')
-rw-r--r--lib/liblame/frontend/Makefile.am81
-rw-r--r--lib/liblame/frontend/Makefile.in641
-rw-r--r--lib/liblame/frontend/amiga_mpega.c139
-rw-r--r--lib/liblame/frontend/brhist.c388
-rw-r--r--lib/liblame/frontend/brhist.h32
-rw-r--r--lib/liblame/frontend/console.c322
-rw-r--r--lib/liblame/frontend/console.h57
-rw-r--r--lib/liblame/frontend/depcomp530
-rw-r--r--lib/liblame/frontend/get_audio.c1806
-rw-r--r--lib/liblame/frontend/get_audio.h108
-rw-r--r--lib/liblame/frontend/gpkplotting.c331
-rw-r--r--lib/liblame/frontend/gpkplotting.h51
-rw-r--r--lib/liblame/frontend/gtkanal.c1639
-rw-r--r--lib/liblame/frontend/gtkanal.h25
-rw-r--r--lib/liblame/frontend/lame_vc6.dsp188
-rw-r--r--lib/liblame/frontend/lame_vc8.vcproj552
-rw-r--r--lib/liblame/frontend/lametime.c169
-rw-r--r--lib/liblame/frontend/lametime.h34
-rw-r--r--lib/liblame/frontend/main.c864
-rw-r--r--lib/liblame/frontend/main.h58
-rw-r--r--lib/liblame/frontend/mp3rtp.c278
-rw-r--r--lib/liblame/frontend/mp3x.c80
-rw-r--r--lib/liblame/frontend/mp3x_vc6.dsp181
-rw-r--r--lib/liblame/frontend/parse.c2341
-rw-r--r--lib/liblame/frontend/parse.h13
-rw-r--r--lib/liblame/frontend/portableio.c490
-rw-r--r--lib/liblame/frontend/portableio.h91
-rw-r--r--lib/liblame/frontend/rtp.c385
-rw-r--r--lib/liblame/frontend/rtp.h38
-rw-r--r--lib/liblame/frontend/timestatus.c348
-rw-r--r--lib/liblame/frontend/timestatus.h34
31 files changed, 12294 insertions, 0 deletions
diff --git a/lib/liblame/frontend/Makefile.am b/lib/liblame/frontend/Makefile.am
new file mode 100644
index 0000000000..0ea2ac7373
--- /dev/null
+++ b/lib/liblame/frontend/Makefile.am
@@ -0,0 +1,81 @@
+## $Id: Makefile.am,v 1.28 2006/09/30 09:17:05 bouvigne Exp $
+
+include $(top_srcdir)/Makefile.am.global
+
+bin_PROGRAMS = @WITH_FRONTEND@ @WITH_MP3RTP@ @WITH_MP3X@
+EXTRA_PROGRAMS = lame$(EXEEXT) mp3rtp$(EXEEXT) mp3x$(EXEEXT)
+
+brhist_sources = brhist.c brhist.h
+
+EXTRA_DIST = \
+ $(brhist_sources) \
+ lame_vc6.dsp \
+ lame_vc8.vcproj \
+ mp3x_vc6.dsp \
+ amiga_mpega.c
+
+DEFS = @DEFS@ @CONFIG_DEFS@
+
+common_sources = \
+ console.c \
+ get_audio.c \
+ lametime.c \
+ parse.c \
+ portableio.c \
+ timestatus.c
+
+noinst_HEADERS = \
+ console.h \
+ get_audio.h \
+ gtkanal.h \
+ gpkplotting.h \
+ lametime.h \
+ main.h \
+ parse.h \
+ portableio.h \
+ timestatus.h
+
+## EXTRA_lame__EXEEXT__SOURCES = $(brhist_sources)
+## EXTRA_mp3rtp__EXEEXT__SOURCES = $(brhist_sources)
+## EXTRA_mp3x__EXEEXT__SOURCES = $(brhist_sources)
+
+if WITH_BRHIST
+lame_SOURCES = main.c $(common_sources) $(brhist_sources)
+mp3rtp_SOURCES = mp3rtp.c rtp.c rtp.h $(common_sources) \
+ $(brhist_sources)
+mp3x_SOURCES = mp3x.c gtkanal.c gpkplotting.c \
+ $(common_sources) $(brhist_sources)
+else
+lame_SOURCES = main.c $(common_sources)
+mp3rtp_SOURCES = mp3rtp.c rtp.c rtp.h $(common_sources)
+mp3x_SOURCES = mp3x.c gtkanal.c gpkplotting.c $(common_sources)
+endif
+
+CFLAGS = @CFLAGS@ @GTK_CFLAGS@ @FRONTEND_CFLAGS@ @SNDFILE_CFLAGS@
+LDFLAGS = @LDFLAGS@ @FRONTEND_LDFLAGS@ @SNDFILE_LIBS@ -static
+
+INCLUDES = -I$(top_srcdir)/libmp3lame -I$(top_srcdir)/include -I$(top_builddir)
+
+LDADD = @LDADD@ \
+ $(top_builddir)/libmp3lame/libmp3lame.la \
+ @FRONTEND_LDADD@
+
+mp3x_LDADD = $(LDADD) @GTK_LIBS@
+
+CLEANFILES = lclint.txt $(EXTRA_PROGRAMS)
+
+LCLINTFLAGS= \
+ +posixlib \
+ +showsummary \
+ +showalluses \
+ +whichlib \
+ +forcehints \
+ -fixedformalarray \
+ +matchanyintegral \
+ -Dlint
+
+lclint.txt: ${lame_SOURCES} ${noinst_HEADERS}
+ @lclint ${LCLINTFLAGS} ${INCLUDES} ${DEFS} ${lame_SOURCES} 2>&1 >lclint.txt || true
+
+lclint: lclint.txt
+ more lclint.txt
diff --git a/lib/liblame/frontend/Makefile.in b/lib/liblame/frontend/Makefile.in
new file mode 100644
index 0000000000..c6bfedc1c9
--- /dev/null
+++ b/lib/liblame/frontend/Makefile.in
@@ -0,0 +1,641 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 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.
+
+@SET_MAKE@
+
+# global section for every Makefile.am
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+ANSI2KNR = $(top_srcdir)/ansi2knr
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(top_srcdir)/Makefile.am.global depcomp
+subdir = frontend
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am__lame_SOURCES_DIST = main.c console.c get_audio.c lametime.c \
+ parse.c portableio.c timestatus.c brhist.c brhist.h
+am__objects_1 = console$U.$(OBJEXT) get_audio$U.$(OBJEXT) \
+ lametime$U.$(OBJEXT) parse$U.$(OBJEXT) portableio$U.$(OBJEXT) \
+ timestatus$U.$(OBJEXT)
+am__objects_2 = brhist$U.$(OBJEXT)
+@WITH_BRHIST_FALSE@am_lame_OBJECTS = main$U.$(OBJEXT) $(am__objects_1)
+@WITH_BRHIST_TRUE@am_lame_OBJECTS = main$U.$(OBJEXT) $(am__objects_1) \
+@WITH_BRHIST_TRUE@ $(am__objects_2)
+lame_OBJECTS = $(am_lame_OBJECTS)
+lame_LDADD = $(LDADD)
+lame_DEPENDENCIES = $(top_builddir)/libmp3lame/libmp3lame.la
+am__mp3rtp_SOURCES_DIST = mp3rtp.c rtp.c rtp.h console.c get_audio.c \
+ lametime.c parse.c portableio.c timestatus.c brhist.c brhist.h
+@WITH_BRHIST_FALSE@am_mp3rtp_OBJECTS = mp3rtp$U.$(OBJEXT) \
+@WITH_BRHIST_FALSE@ rtp$U.$(OBJEXT) $(am__objects_1)
+@WITH_BRHIST_TRUE@am_mp3rtp_OBJECTS = mp3rtp$U.$(OBJEXT) \
+@WITH_BRHIST_TRUE@ rtp$U.$(OBJEXT) $(am__objects_1) \
+@WITH_BRHIST_TRUE@ $(am__objects_2)
+mp3rtp_OBJECTS = $(am_mp3rtp_OBJECTS)
+mp3rtp_LDADD = $(LDADD)
+mp3rtp_DEPENDENCIES = $(top_builddir)/libmp3lame/libmp3lame.la
+am__mp3x_SOURCES_DIST = mp3x.c gtkanal.c gpkplotting.c console.c \
+ get_audio.c lametime.c parse.c portableio.c timestatus.c \
+ brhist.c brhist.h
+@WITH_BRHIST_FALSE@am_mp3x_OBJECTS = mp3x$U.$(OBJEXT) \
+@WITH_BRHIST_FALSE@ gtkanal$U.$(OBJEXT) gpkplotting$U.$(OBJEXT) \
+@WITH_BRHIST_FALSE@ $(am__objects_1)
+@WITH_BRHIST_TRUE@am_mp3x_OBJECTS = mp3x$U.$(OBJEXT) \
+@WITH_BRHIST_TRUE@ gtkanal$U.$(OBJEXT) gpkplotting$U.$(OBJEXT) \
+@WITH_BRHIST_TRUE@ $(am__objects_1) $(am__objects_2)
+mp3x_OBJECTS = $(am_mp3x_OBJECTS)
+am__DEPENDENCIES_1 = $(top_builddir)/libmp3lame/libmp3lame.la
+mp3x_DEPENDENCIES = $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(lame_SOURCES) $(mp3rtp_SOURCES) $(mp3x_SOURCES)
+DIST_SOURCES = $(am__lame_SOURCES_DIST) $(am__mp3rtp_SOURCES_DIST) \
+ $(am__mp3x_SOURCES_DIST)
+HEADERS = $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@ @GTK_CFLAGS@ @FRONTEND_CFLAGS@ @SNDFILE_CFLAGS@
+CONFIG_DEFS = @CONFIG_DEFS@
+CONFIG_MATH_LIB = @CONFIG_MATH_LIB@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPUCCODE = @CPUCCODE@
+CPUTYPE = @CPUTYPE@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@ @CONFIG_DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRONTEND_CFLAGS = @FRONTEND_CFLAGS@
+FRONTEND_LDADD = @FRONTEND_LDADD@
+FRONTEND_LDFLAGS = @FRONTEND_LDFLAGS@
+GREP = @GREP@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_CONFIG = @GTK_CONFIG@
+GTK_LIBS = @GTK_LIBS@
+INCLUDES = -I$(top_srcdir)/libmp3lame -I$(top_srcdir)/include -I$(top_builddir)
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDADD = @LDADD@ \
+ $(top_builddir)/libmp3lame/libmp3lame.la \
+ @FRONTEND_LDADD@
+
+LDFLAGS = @LDFLAGS@ @FRONTEND_LDFLAGS@ @SNDFILE_LIBS@ -static
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+LIB_MAJOR_VERSION = @LIB_MAJOR_VERSION@
+LIB_MINOR_VERSION = @LIB_MINOR_VERSION@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEDEP = @MAKEDEP@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NASM = @NASM@
+NASM_FORMAT = @NASM_FORMAT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+RM_F = @RM_F@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNDFILE_CFLAGS = @SNDFILE_CFLAGS@
+SNDFILE_LIBS = @SNDFILE_LIBS@
+STRIP = @STRIP@
+U = @U@
+VERSION = @VERSION@
+WITH_FRONTEND = @WITH_FRONTEND@
+WITH_MP3RTP = @WITH_MP3RTP@
+WITH_MP3X = @WITH_MP3X@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = 1.9 foreign $(top_srcdir)/ansi2knr
+bin_PROGRAMS = @WITH_FRONTEND@ @WITH_MP3RTP@ @WITH_MP3X@
+EXTRA_PROGRAMS = lame$(EXEEXT) mp3rtp$(EXEEXT) mp3x$(EXEEXT)
+brhist_sources = brhist.c brhist.h
+EXTRA_DIST = \
+ $(brhist_sources) \
+ lame_vc6.dsp \
+ lame_vc8.vcproj \
+ mp3x_vc6.dsp \
+ amiga_mpega.c
+
+common_sources = \
+ console.c \
+ get_audio.c \
+ lametime.c \
+ parse.c \
+ portableio.c \
+ timestatus.c
+
+noinst_HEADERS = \
+ console.h \
+ get_audio.h \
+ gtkanal.h \
+ gpkplotting.h \
+ lametime.h \
+ main.h \
+ parse.h \
+ portableio.h \
+ timestatus.h
+
+@WITH_BRHIST_FALSE@lame_SOURCES = main.c $(common_sources)
+@WITH_BRHIST_TRUE@lame_SOURCES = main.c $(common_sources) $(brhist_sources)
+@WITH_BRHIST_FALSE@mp3rtp_SOURCES = mp3rtp.c rtp.c rtp.h $(common_sources)
+@WITH_BRHIST_TRUE@mp3rtp_SOURCES = mp3rtp.c rtp.c rtp.h $(common_sources) \
+@WITH_BRHIST_TRUE@ $(brhist_sources)
+
+@WITH_BRHIST_FALSE@mp3x_SOURCES = mp3x.c gtkanal.c gpkplotting.c $(common_sources)
+@WITH_BRHIST_TRUE@mp3x_SOURCES = mp3x.c gtkanal.c gpkplotting.c \
+@WITH_BRHIST_TRUE@ $(common_sources) $(brhist_sources)
+
+mp3x_LDADD = $(LDADD) @GTK_LIBS@
+CLEANFILES = lclint.txt $(EXTRA_PROGRAMS)
+LCLINTFLAGS = \
+ +posixlib \
+ +showsummary \
+ +showalluses \
+ +whichlib \
+ +forcehints \
+ -fixedformalarray \
+ +matchanyintegral \
+ -Dlint
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.global $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign frontend/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign frontend/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+lame$(EXEEXT): $(lame_OBJECTS) $(lame_DEPENDENCIES)
+ @rm -f lame$(EXEEXT)
+ $(LINK) $(lame_OBJECTS) $(lame_LDADD) $(LIBS)
+mp3rtp$(EXEEXT): $(mp3rtp_OBJECTS) $(mp3rtp_DEPENDENCIES)
+ @rm -f mp3rtp$(EXEEXT)
+ $(LINK) $(mp3rtp_OBJECTS) $(mp3rtp_LDADD) $(LIBS)
+mp3x$(EXEEXT): $(mp3x_OBJECTS) $(mp3x_DEPENDENCIES)
+ @rm -f mp3x$(EXEEXT)
+ $(LINK) $(mp3x_OBJECTS) $(mp3x_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+$(top_srcdir)/ansi2knr:
+ cd $(top_srcdir) && $(MAKE) $(AM_MAKEFLAGS) ./ansi2knr
+
+mostlyclean-kr:
+ -test "$U" = "" || rm -f *_.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brhist$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/console$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_audio$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpkplotting$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtkanal$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lametime$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mp3rtp$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mp3x$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/portableio$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rtp$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timestatus$U.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+brhist_.c: brhist.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/brhist.c; then echo $(srcdir)/brhist.c; else echo brhist.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+console_.c: console.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/console.c; then echo $(srcdir)/console.c; else echo console.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+get_audio_.c: get_audio.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/get_audio.c; then echo $(srcdir)/get_audio.c; else echo get_audio.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+gpkplotting_.c: gpkplotting.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/gpkplotting.c; then echo $(srcdir)/gpkplotting.c; else echo gpkplotting.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+gtkanal_.c: gtkanal.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/gtkanal.c; then echo $(srcdir)/gtkanal.c; else echo gtkanal.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+lametime_.c: lametime.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/lametime.c; then echo $(srcdir)/lametime.c; else echo lametime.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+main_.c: main.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/main.c; then echo $(srcdir)/main.c; else echo main.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+mp3rtp_.c: mp3rtp.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/mp3rtp.c; then echo $(srcdir)/mp3rtp.c; else echo mp3rtp.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+mp3x_.c: mp3x.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/mp3x.c; then echo $(srcdir)/mp3x.c; else echo mp3x.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+parse_.c: parse.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/parse.c; then echo $(srcdir)/parse.c; else echo parse.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+portableio_.c: portableio.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/portableio.c; then echo $(srcdir)/portableio.c; else echo portableio.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+rtp_.c: rtp.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/rtp.c; then echo $(srcdir)/rtp.c; else echo rtp.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+timestatus_.c: timestatus.c $(ANSI2KNR)
+ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/timestatus.c; then echo $(srcdir)/timestatus.c; else echo timestatus.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+brhist_.$(OBJEXT) brhist_.lo console_.$(OBJEXT) console_.lo \
+get_audio_.$(OBJEXT) get_audio_.lo gpkplotting_.$(OBJEXT) \
+gpkplotting_.lo gtkanal_.$(OBJEXT) gtkanal_.lo lametime_.$(OBJEXT) \
+lametime_.lo main_.$(OBJEXT) main_.lo mp3rtp_.$(OBJEXT) mp3rtp_.lo \
+mp3x_.$(OBJEXT) mp3x_.lo parse_.$(OBJEXT) parse_.lo \
+portableio_.$(OBJEXT) portableio_.lo rtp_.$(OBJEXT) rtp_.lo \
+timestatus_.$(OBJEXT) timestatus_.lo : $(ANSI2KNR)
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic mostlyclean-kr \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libtool ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-kr \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-binPROGRAMS
+
+
+# end global section
+
+lclint.txt: ${lame_SOURCES} ${noinst_HEADERS}
+ @lclint ${LCLINTFLAGS} ${INCLUDES} ${DEFS} ${lame_SOURCES} 2>&1 >lclint.txt || true
+
+lclint: lclint.txt
+ more lclint.txt
+# 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:
diff --git a/lib/liblame/frontend/amiga_mpega.c b/lib/liblame/frontend/amiga_mpega.c
new file mode 100644
index 0000000000..12f144fced
--- /dev/null
+++ b/lib/liblame/frontend/amiga_mpega.c
@@ -0,0 +1,139 @@
+/* MPGLIB replacement using mpega.library (AmigaOS)
+ * Written by Thomas Wenzel and Sigbjrn (CISC) Skj�et.
+ *
+ * Big thanks to St�hane Tavernard for mpega.library.
+ *
+ */
+
+/* $Id: amiga_mpega.c,v 1.3 2005/11/01 13:01:56 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef AMIGA_MPEGA
+
+#define __USE_SYSBASE
+#include "lame.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+/* We need a small workaround here so GCC doesn't fail upon redefinition. :P */
+#define FLOAT _FLOAT
+#include <proto/exec.h>
+#include <proto/mpega.h>
+#undef _FLOAT
+
+#ifndef __GNUC__
+#include <dos.h>
+#endif
+
+struct Library *MPEGABase = NULL;
+MPEGA_STREAM *mstream = NULL;
+MPEGA_CTRL mctrl;
+
+static const int smpls[2][4] = {
+/* Layer x I II III */
+ {0, 384, 1152, 1152}, /* MPEG-1 */
+ {0, 384, 1152, 576} /* MPEG-2(.5) */
+};
+
+
+#ifndef __GNUC__
+static int
+break_cleanup(void)
+{
+ /* Dummy break function to make atexit() work. :P */
+ return 1;
+}
+#endif
+
+static void
+exit_cleanup(void)
+{
+ if (mstream) {
+ MPEGA_close(mstream);
+ mstream = NULL;
+ }
+ if (MPEGABase) {
+ CloseLibrary(MPEGABase);
+ MPEGABase = NULL;
+ }
+}
+
+
+int
+lame_decode_initfile(const char *fullname, mp3data_struct * mp3data)
+{
+ mctrl.bs_access = NULL;
+
+ mctrl.layer_1_2.mono.quality = 2;
+ mctrl.layer_1_2.stereo.quality = 2;
+ mctrl.layer_1_2.mono.freq_div = 1;
+ mctrl.layer_1_2.stereo.freq_div = 1;
+ mctrl.layer_1_2.mono.freq_max = 48000;
+ mctrl.layer_1_2.stereo.freq_max = 48000;
+ mctrl.layer_3.mono.quality = 2;
+ mctrl.layer_3.stereo.quality = 2;
+ mctrl.layer_3.mono.freq_div = 1;
+ mctrl.layer_3.stereo.freq_div = 1;
+ mctrl.layer_3.mono.freq_max = 48000;
+ mctrl.layer_3.stereo.freq_max = 48000;
+ mctrl.layer_1_2.force_mono = 0;
+ mctrl.layer_3.force_mono = 0;
+
+ MPEGABase = OpenLibrary("mpega.library", 2);
+ if (!MPEGABase) {
+ error_printf("Unable to open mpega.library v2\n");
+ exit(1);
+ }
+#ifndef __GNUC__
+ onbreak(break_cleanup);
+#endif
+ atexit(exit_cleanup);
+
+ mp3data->header_parsed = 0;
+ mstream = MPEGA_open((char *) fullname, &mctrl);
+ if (!mstream)
+ return (-1);
+
+ mp3data->header_parsed = 1;
+ mp3data->stereo = mstream->dec_channels;
+ mp3data->samplerate = mstream->dec_frequency;
+ mp3data->bitrate = mstream->bitrate;
+ mp3data->nsamp = (float) mstream->ms_duration / 1000 * mstream->dec_frequency;
+ mp3data->mode = mstream->mode;
+ mp3data->mode_ext = 0; /* mpega.library doesn't supply this info! :( */
+ mp3data->framesize = smpls[mstream->norm - 1][mstream->layer];
+
+ return 0;
+}
+
+int
+lame_decode_fromfile(FILE * fd, short pcm_l[], short pcm_r[], mp3data_struct * mp3data)
+{
+ int outsize = 0;
+ WORD *b[MPEGA_MAX_CHANNELS];
+
+ b[0] = pcm_l;
+ b[1] = pcm_r;
+
+ mp3data->header_parsed = 0;
+ while ((outsize == 0) || (outsize == MPEGA_ERR_BADFRAME)) /* Skip bad frames */
+ outsize = MPEGA_decode_frame(mstream, b);
+
+ if (outsize < 0)
+ return (-1);
+
+ mp3data->header_parsed = 1;
+ mp3data->stereo = mstream->dec_channels;
+ mp3data->samplerate = mstream->dec_frequency;
+ mp3data->bitrate = mstream->bitrate;
+ mp3data->mode = mstream->mode;
+ mp3data->mode_ext = 0; /* mpega.library doesn't supply this info! :( */
+ mp3data->framesize = smpls[mstream->norm - 1][mstream->layer];
+
+ return outsize;
+}
+
+#endif /* AMIGA_MPEGA */
diff --git a/lib/liblame/frontend/brhist.c b/lib/liblame/frontend/brhist.c
new file mode 100644
index 0000000000..664f548df2
--- /dev/null
+++ b/lib/liblame/frontend/brhist.c
@@ -0,0 +1,388 @@
+/*
+ * Bitrate histogram source file
+ *
+ * Copyright (c) 2000 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: brhist.c,v 1.53 2008/04/05 17:38:50 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef BRHIST
+
+/* basic #define's */
+
+#ifndef BRHIST_WIDTH
+# define BRHIST_WIDTH 14
+#endif
+#ifndef BRHIST_RES
+# define BRHIST_RES 14
+#endif
+
+
+/* #includes */
+
+#ifdef STDC_HEADERS
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+#endif
+
+#include "brhist.h"
+#include "console.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+
+/* Structure holding all data related to the Console I/O
+ * may be this should be a more global frontend structure. So it
+ * makes sense to print all files instead with
+ * printf ( "blah\n") with printf ( "blah%s\n", Console_IO.str_clreoln );
+ */
+
+extern Console_IO_t Console_IO;
+
+static struct {
+ int vbr_bitrate_min_index;
+ int vbr_bitrate_max_index;
+ int kbps[BRHIST_WIDTH];
+ int hist_printed_lines;
+ char bar_asterisk[512 + 1]; /* buffer filled up with a lot of '*' to print a bar */
+ char bar_percent[512 + 1]; /* buffer filled up with a lot of '%' to print a bar */
+ char bar_coded[512 + 1]; /* buffer filled up with a lot of ' ' to print a bar */
+ char bar_space[512 + 1]; /* buffer filled up with a lot of ' ' to print a bar */
+} brhist;
+
+static int
+calculate_index(const int *const array, const int len, const int value)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ if (array[i] == value)
+ return i;
+ return -1;
+}
+
+int
+brhist_init(const lame_global_flags * gf, const int bitrate_kbps_min, const int bitrate_kbps_max)
+{
+ brhist.hist_printed_lines = 0;
+
+ /* initialize histogramming data structure */
+ lame_bitrate_kbps(gf, brhist.kbps);
+ brhist.vbr_bitrate_min_index = calculate_index(brhist.kbps, BRHIST_WIDTH, bitrate_kbps_min);
+ brhist.vbr_bitrate_max_index = calculate_index(brhist.kbps, BRHIST_WIDTH, bitrate_kbps_max);
+
+ if (brhist.vbr_bitrate_min_index >= BRHIST_WIDTH ||
+ brhist.vbr_bitrate_max_index >= BRHIST_WIDTH) {
+ error_printf("lame internal error: VBR min %d kbps or VBR max %d kbps not allowed.\n",
+ bitrate_kbps_min, bitrate_kbps_max);
+ return -1;
+ }
+
+ memset(brhist.bar_asterisk, '*', sizeof(brhist.bar_asterisk) - 1);
+ memset(brhist.bar_percent, '%', sizeof(brhist.bar_percent) - 1);
+ memset(brhist.bar_space, '-', sizeof(brhist.bar_space) - 1);
+ memset(brhist.bar_coded, '-', sizeof(brhist.bar_space) - 1);
+
+ return 0;
+}
+
+static int
+digits(unsigned number)
+{
+ int ret = 1;
+
+ if (number >= 100000000) {
+ ret += 8;
+ number /= 100000000;
+ }
+ if (number >= 10000) {
+ ret += 4;
+ number /= 10000;
+ }
+ if (number >= 100) {
+ ret += 2;
+ number /= 100;
+ }
+ if (number >= 10) {
+ ret += 1;
+ }
+
+ return ret;
+}
+
+
+static void
+brhist_disp_line(int i, int br_hist_TOT, int br_hist_LR, int full, int frames)
+{
+ char brppt[14]; /* [%] and max. 10 characters for kbps */
+ int barlen_TOT;
+ int barlen_LR;
+ int ppt = 0;
+ int res = digits(frames) + 3 + 4 + 1;
+
+ if (full != 0) {
+ /* some problems when br_hist_TOT \approx br_hist_LR: You can't see that there are still MS frames */
+ barlen_TOT = (br_hist_TOT * (Console_IO.disp_width - res) + full - 1) / full; /* round up */
+ barlen_LR = (br_hist_LR * (Console_IO.disp_width - res) + full - 1) / full; /* round up */
+ }
+ else {
+ barlen_TOT = barlen_LR = 0;
+ }
+
+ if (frames > 0)
+ ppt = (1000 * br_hist_TOT + frames / 2) / frames; /* round nearest */
+
+ sprintf(brppt, " [%*i]", digits(frames), br_hist_TOT);
+
+ if (Console_IO.str_clreoln[0]) /* ClearEndOfLine available */
+ console_printf("\n%3d%s %.*s%.*s%s",
+ brhist.kbps[i], brppt,
+ barlen_LR, brhist.bar_percent,
+ barlen_TOT - barlen_LR, brhist.bar_asterisk, Console_IO.str_clreoln);
+ else
+ console_printf("\n%3d%s %.*s%.*s%*s",
+ brhist.kbps[i], brppt,
+ barlen_LR, brhist.bar_percent,
+ barlen_TOT - barlen_LR, brhist.bar_asterisk,
+ Console_IO.disp_width - res - barlen_TOT, "");
+
+ brhist.hist_printed_lines++;
+}
+
+
+
+static void
+progress_line(const lame_global_flags * gf, int full, int frames)
+{
+ char rst[20] = "\0";
+ int barlen_TOT = 0, barlen_COD = 0, barlen_RST = 0;
+ int res = 1;
+ float time_in_sec = 0;
+ unsigned int hour, min, sec;
+ int fsize = lame_get_framesize(gf);
+ int srate = lame_get_out_samplerate(gf);
+
+ if (full < frames) {
+ full = frames;
+ }
+ if (srate > 0) {
+ time_in_sec = (float)(full - frames);
+ time_in_sec *= fsize;
+ time_in_sec /= srate;
+ }
+ hour = (unsigned int)(time_in_sec / 3600);
+ time_in_sec -= hour * 3600;
+ min = (unsigned int)(time_in_sec / 60);
+ time_in_sec -= min * 60;
+ sec = (unsigned int)time_in_sec;
+ if (full != 0) {
+ if (hour > 0) {
+ sprintf(rst, "%*d:%02u:%02u", digits(hour), hour, min, sec);
+ res += digits(hour) + 1 + 5;
+ }
+ else {
+ sprintf(rst, "%02u:%02u", min, sec);
+ res += 5;
+ }
+ /* some problems when br_hist_TOT \approx br_hist_LR: You can't see that there are still MS frames */
+ barlen_TOT = (full * (Console_IO.disp_width - res) + full - 1) / full; /* round up */
+ barlen_COD = (frames * (Console_IO.disp_width - res) + full - 1) / full; /* round up */
+ barlen_RST = barlen_TOT - barlen_COD;
+ if (barlen_RST == 0) {
+ sprintf(rst, "%.*s", res - 1, brhist.bar_coded);
+ }
+ }
+ else {
+ barlen_TOT = barlen_COD = barlen_RST = 0;
+ }
+ if (Console_IO.str_clreoln[0]) { /* ClearEndOfLine available */
+ console_printf("\n%.*s%s%.*s%s",
+ barlen_COD, brhist.bar_coded,
+ rst, barlen_RST, brhist.bar_space, Console_IO.str_clreoln);
+ }
+ else {
+ console_printf("\n%.*s%s%.*s%*s",
+ barlen_COD, brhist.bar_coded,
+ rst, barlen_RST, brhist.bar_space, Console_IO.disp_width - res - barlen_TOT,
+ "");
+ }
+ brhist.hist_printed_lines++;
+}
+
+
+static int
+stats_value(double x)
+{
+ if (x > 0.0) {
+ console_printf(" %5.1f", x);
+ return 6;
+ }
+ return 0;
+}
+
+static int
+stats_head(double x, const char *txt)
+{
+ if (x > 0.0) {
+ console_printf(txt);
+ return 6;
+ }
+ return 0;
+}
+
+
+static void
+stats_line(double *stat)
+{
+ int n = 1;
+ console_printf("\n kbps ");
+ n += 12;
+ n += stats_head(stat[1], " mono");
+ n += stats_head(stat[2], " IS ");
+ n += stats_head(stat[3], " LR ");
+ n += stats_head(stat[4], " MS ");
+ console_printf(" %% ");
+ n += 6;
+ n += stats_head(stat[5], " long ");
+ n += stats_head(stat[6], "switch");
+ n += stats_head(stat[7], " short");
+ n += stats_head(stat[8], " mixed");
+ n += console_printf(" %%");
+ if (Console_IO.str_clreoln[0]) { /* ClearEndOfLine available */
+ console_printf("%s", Console_IO.str_clreoln);
+ }
+ else {
+ console_printf("%*s", Console_IO.disp_width - n, "");
+ }
+ brhist.hist_printed_lines++;
+
+ n = 1;
+ console_printf("\n %5.1f ", stat[0]);
+ n += 12;
+ n += stats_value(stat[1]);
+ n += stats_value(stat[2]);
+ n += stats_value(stat[3]);
+ n += stats_value(stat[4]);
+ console_printf(" ");
+ n += 6;
+ n += stats_value(stat[5]);
+ n += stats_value(stat[6]);
+ n += stats_value(stat[7]);
+ n += stats_value(stat[8]);
+ if (Console_IO.str_clreoln[0]) { /* ClearEndOfLine available */
+ console_printf("%s", Console_IO.str_clreoln);
+ }
+ else {
+ console_printf("%*s", Console_IO.disp_width - n, "");
+ }
+ brhist.hist_printed_lines++;
+}
+
+
+/* Yes, not very good */
+#define LR 0
+#define MS 2
+
+void
+brhist_disp(const lame_global_flags * gf)
+{
+ int i, lines_used = 0;
+ int br_hist[BRHIST_WIDTH]; /* how often a frame size was used */
+ int br_sm_hist[BRHIST_WIDTH][4]; /* how often a special frame size/stereo mode commbination was used */
+ int st_mode[4];
+ int bl_type[6];
+ int frames; /* total number of encoded frames */
+ int most_often; /* usage count of the most often used frame size, but not smaller than Console_IO.disp_width-BRHIST_RES (makes this sense?) and 1 */
+ double sum = 0.;
+
+ double stat[9] = { 0 };
+ int st_frames = 0;
+
+
+ brhist.hist_printed_lines = 0; /* printed number of lines for the brhist functionality, used to skip back the right number of lines */
+
+ lame_bitrate_stereo_mode_hist(gf, br_sm_hist);
+ lame_bitrate_hist(gf, br_hist);
+ lame_stereo_mode_hist(gf, st_mode);
+ lame_block_type_hist(gf, bl_type);
+
+ frames = most_often = 0;
+ for (i = 0; i < BRHIST_WIDTH; i++) {
+ frames += br_hist[i];
+ sum += br_hist[i] * brhist.kbps[i];
+ if (most_often < br_hist[i])
+ most_often = br_hist[i];
+ if (br_hist[i])
+ ++lines_used;
+ }
+
+ for (i = 0; i < BRHIST_WIDTH; i++) {
+ int show = br_hist[i];
+ show = show && (lines_used > 1);
+ if (show || (i >= brhist.vbr_bitrate_min_index && i <= brhist.vbr_bitrate_max_index))
+ brhist_disp_line(i, br_hist[i], br_sm_hist[i][LR], most_often, frames);
+ }
+ for (i = 0; i < 4; i++) {
+ st_frames += st_mode[i];
+ }
+ if (frames > 0) {
+ stat[0] = sum / frames;
+ stat[1] = 100. * (frames - st_frames) / frames;
+ }
+ if (st_frames > 0) {
+ stat[2] = 0.0;
+ stat[3] = 100. * st_mode[LR] / st_frames;
+ stat[4] = 100. * st_mode[MS] / st_frames;
+ }
+ if (bl_type[5] > 0) {
+ stat[5] = 100. * bl_type[0] / bl_type[5];
+ stat[6] = 100. * (bl_type[1] + bl_type[3]) / bl_type[5];
+ stat[7] = 100. * bl_type[2] / bl_type[5];
+ stat[8] = 100. * bl_type[4] / bl_type[5];
+ }
+ progress_line(gf, lame_get_totalframes(gf), frames);
+ stats_line(stat);
+}
+
+void
+brhist_jump_back(void)
+{
+ console_up(brhist.hist_printed_lines);
+ brhist.hist_printed_lines = 0;
+}
+
+/*
+ * 1)
+ *
+ * Taken from Termcap_Manual.html:
+ *
+ * With the Unix version of termcap, you must allocate space for the description yourself and pass
+ * the address of the space as the argument buffer. There is no way you can tell how much space is
+ * needed, so the convention is to allocate a buffer 2048 characters long and assume that is
+ * enough. (Formerly the convention was to allocate 1024 characters and assume that was enough.
+ * But one day, for one kind of terminal, that was not enough.)
+ */
+
+#endif /* ifdef BRHIST */
diff --git a/lib/liblame/frontend/brhist.h b/lib/liblame/frontend/brhist.h
new file mode 100644
index 0000000000..480852278d
--- /dev/null
+++ b/lib/liblame/frontend/brhist.h
@@ -0,0 +1,32 @@
+/*
+ * Bitrate histogram include file
+ *
+ * Copyright (c) 2000 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_BRHIST_H
+#define LAME_BRHIST_H
+
+#include "lame.h"
+
+int brhist_init(const lame_global_flags * gf, const int bitrate_kbps_min,
+ const int bitrate_kbps_max);
+void brhist_disp(const lame_global_flags * gf);
+void brhist_jump_back(void);
+
+#endif /* LAME_BRHIST_H */
diff --git a/lib/liblame/frontend/console.c b/lib/liblame/frontend/console.c
new file mode 100644
index 0000000000..97938a3a0f
--- /dev/null
+++ b/lib/liblame/frontend/console.c
@@ -0,0 +1,322 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else
+# ifndef HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+char *strchr(), *strrchr();
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# define memmove(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#if defined(HAVE_NCURSES_TERMCAP_H)
+# include <ncurses/termcap.h>
+#elif defined(HAVE_TERMCAP_H)
+# include <termcap.h>
+#elif defined(HAVE_TERMCAP)
+# include <curses.h>
+# if !defined(__bsdi__)
+# include <term.h>
+# endif
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "console.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+#define CLASS_ID 0x434F4E53
+#define REPORT_BUFF_SIZE 1024
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <windows.h>
+#endif
+
+
+
+static int
+my_console_printing(FILE * fp, const char *format, va_list ap)
+{
+ if (fp != NULL)
+ return vfprintf(fp, format, ap);
+ return 0;
+}
+
+static int
+my_error_printing(FILE * fp, const char *format, va_list ap)
+{
+ if (fp != NULL)
+ return vfprintf(fp, format, ap);
+ return 0;
+}
+
+static int
+my_report_printing(FILE * fp, const char *format, va_list ap)
+{
+ if (fp != NULL)
+ return vfprintf(fp, format, ap);
+ return 0;
+}
+
+
+/*
+ * Taken from Termcap_Manual.html:
+ *
+ * With the Unix version of termcap, you must allocate space for the description yourself and pass
+ * the address of the space as the argument buffer. There is no way you can tell how much space is
+ * needed, so the convention is to allocate a buffer 2048 characters long and assume that is
+ * enough. (Formerly the convention was to allocate 1024 characters and assume that was enough.
+ * But one day, for one kind of terminal, that was not enough.)
+ */
+
+#ifdef HAVE_TERMCAP
+static void
+apply_termcap_settings(Console_IO_t * const mfp)
+{
+ const char *term_name;
+ char term_buff[2048];
+ char *tp;
+ char tc[10];
+ int val;
+
+ /* try to catch additional information about special console sequences */
+
+ if ((term_name = getenv("TERM")) == NULL) {
+ /* rh 061105:
+ silently ignore it and fallback to the behaviour as if
+ TERMCAP wasn't defined at all
+ */
+ return;
+ /*
+ fprintf(mfp->Error_fp, "LAME: Can't get \"TERM\" environment string.\n");
+ return -1;
+ */
+ }
+ if (tgetent(term_buff, term_name) != 1) {
+ /* rh 061105:
+ silently ignore it and fallback to the behaviour as if
+ TERMCAP wasn't defined at all
+ */
+ return;
+ /*
+ fprintf(mfp->Error_fp, "LAME: Can't find termcap entry for terminal \"%s\"\n", term_name);
+ return -1;
+ */
+ }
+
+ val = tgetnum("co");
+ if (val >= 40 && val <= 512)
+ mfp->disp_width = val;
+ val = tgetnum("li");
+ if (val >= 16 && val <= 256)
+ mfp->disp_height = val;
+
+ *(tp = tc) = '\0';
+ tp = tgetstr("up", &tp);
+ if (tp != NULL)
+ strcpy(mfp->str_up, tp);
+
+ *(tp = tc) = '\0';
+ tp = tgetstr("ce", &tp);
+ if (tp != NULL)
+ strcpy(mfp->str_clreoln, tp);
+
+ *(tp = tc) = '\0';
+ tp = tgetstr("md", &tp);
+ if (tp != NULL)
+ strcpy(mfp->str_emph, tp);
+
+ *(tp = tc) = '\0';
+ tp = tgetstr("me", &tp);
+ if (tp != NULL)
+ strcpy(mfp->str_norm, tp);
+}
+#endif /* TERMCAP_AVAILABLE */
+
+static int
+init_console(Console_IO_t * const mfp)
+{
+ /* setup basics of brhist I/O channels */
+ mfp->disp_width = 80;
+ mfp->disp_height = 25;
+ mfp->Console_fp = stderr;
+ mfp->Error_fp = stderr;
+ mfp->Report_fp = NULL;
+
+ /*mfp -> Console_buff = calloc ( 1, REPORT_BUFF_SIZE ); */
+ setvbuf(mfp->Console_fp, mfp->Console_buff, _IOFBF, sizeof(mfp->Console_buff));
+/* setvbuf ( mfp -> Error_fp , NULL , _IONBF, 0 ); */
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ mfp->Console_Handle = GetStdHandle(STD_ERROR_HANDLE);
+#endif
+
+ strcpy(mfp->str_up, "\033[A");
+
+#ifdef HAVE_TERMCAP
+ apply_termcap_settings(mfp);
+#endif /* TERMCAP_AVAILABLE */
+
+ mfp->ClassID = CLASS_ID;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ mfp->Console_file_type = GetFileType(Console_IO.Console_Handle);
+#else
+ mfp->Console_file_type = 0;
+#endif
+ return 0;
+}
+
+static void
+deinit_console(Console_IO_t * const mfp)
+{
+ if (mfp->Report_fp != NULL) {
+ fclose(mfp->Report_fp);
+ mfp->Report_fp = NULL;
+ }
+ fflush(mfp->Console_fp);
+ setvbuf(mfp->Console_fp, NULL, _IONBF, (size_t) 0);
+
+ memset(mfp->Console_buff, 0x55, REPORT_BUFF_SIZE);
+}
+
+
+/* LAME console
+ */
+Console_IO_t Console_IO;
+
+int
+frontend_open_console(void)
+{
+ return init_console(&Console_IO);
+}
+
+void
+frontend_close_console(void)
+{
+ deinit_console(&Console_IO);
+}
+
+void
+frontend_debugf(const char *format, va_list ap)
+{
+ (void) my_report_printing(Console_IO.Report_fp, format, ap);
+}
+
+void
+frontend_msgf(const char *format, va_list ap)
+{
+ (void) my_console_printing(Console_IO.Console_fp, format, ap);
+}
+
+void
+frontend_errorf(const char *format, va_list ap)
+{
+ (void) my_error_printing(Console_IO.Error_fp, format, ap);
+}
+
+int
+console_printf(const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, format);
+ ret = my_console_printing(Console_IO.Console_fp, format, args);
+ va_end(args);
+
+ return ret;
+}
+
+int
+error_printf(const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, format);
+ ret = my_console_printing(Console_IO.Error_fp, format, args);
+ va_end(args);
+
+ return ret;
+}
+
+int
+report_printf(const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, format);
+ ret = my_console_printing(Console_IO.Report_fp, format, args);
+ va_end(args);
+
+ return ret;
+}
+
+void
+console_flush()
+{
+ fflush(Console_IO.Console_fp);
+}
+
+void
+error_flush()
+{
+ fflush(Console_IO.Error_fp);
+}
+
+void
+report_flush()
+{
+ fflush(Console_IO.Report_fp);
+}
+
+void
+console_up(int n_lines)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (Console_IO.Console_file_type != FILE_TYPE_PIPE) {
+ COORD Pos;
+ CONSOLE_SCREEN_BUFFER_INFO CSBI;
+
+ console_flush();
+ GetConsoleScreenBufferInfo(Console_IO.Console_Handle, &CSBI);
+ Pos.Y = CSBI.dwCursorPosition.Y - n_lines;
+ Pos.X = 0;
+ SetConsoleCursorPosition(Console_IO.Console_Handle, Pos);
+ }
+#else
+ while (n_lines-- > 0)
+ fputs(Console_IO.str_up, Console_IO.Console_fp);
+ console_flush();
+#endif
+}
+
+
+void
+set_debug_file(const char *fn)
+{
+ if (Console_IO.Report_fp == NULL) {
+ Console_IO.Report_fp = fopen(fn, "a");
+ if (Console_IO.Report_fp != NULL) {
+ error_printf("writing debug info into: %s\n", fn);
+ }
+ else {
+ error_printf("Error: can't open for debug info: %s\n", fn);
+ }
+ }
+}
+
+/* end of console.c */
diff --git a/lib/liblame/frontend/console.h b/lib/liblame/frontend/console.h
new file mode 100644
index 0000000000..51f8faafaa
--- /dev/null
+++ b/lib/liblame/frontend/console.h
@@ -0,0 +1,57 @@
+/*
+ * frontend/console.h
+ *
+ * This
+ *
+ *
+ */
+
+#ifndef LAME_CONSOLE_H
+#define LAME_CONSOLE_H
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <windows.h>
+#endif
+
+typedef struct {
+ unsigned long ClassID;
+ unsigned long ClassProt;
+ FILE *Console_fp; /* filepointer to stream reporting information */
+ FILE *Error_fp; /* filepointer to stream fatal error reporting information */
+ FILE *Report_fp; /* filepointer to stream reports (normally a text file or /dev/null) */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ HANDLE Console_Handle;
+#endif
+ int disp_width;
+ int disp_height;
+ char str_up[10];
+ char str_clreoln[10];
+ char str_emph[10];
+ char str_norm[10];
+ char Console_buff[2048];
+ int Console_file_type;
+} Console_IO_t;
+
+extern Console_IO_t Console_IO;
+extern int frontend_open_console(void);
+extern void frontend_close_console(void);
+
+extern void frontend_msgf(const char *format, va_list ap);
+extern void frontend_debugf(const char *format, va_list ap);
+extern void frontend_errorf(const char *format, va_list ap);
+
+int console_printf(const char *format, ...);
+int error_printf(const char *format, ...);
+int report_printf(const char *format, ...);
+
+void console_flush(void);
+void error_flush(void);
+void report_flush(void);
+
+void console_up(int n_lines);
+
+void set_debug_file(const char *fn);
+
+#endif /* LAME_CONSOLE_H */
+
+/* end of console.h */
diff --git a/lib/liblame/frontend/depcomp b/lib/liblame/frontend/depcomp
new file mode 100644
index 0000000000..04701da536
--- /dev/null
+++ b/lib/liblame/frontend/depcomp
@@ -0,0 +1,530 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2005-07-09.11
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, 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 Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by `PROGRAMS ARGS'.
+ object Object file output by `PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputing dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+ "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> $depfile
+ echo >> $depfile
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> $depfile
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts `$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+ tmpdepfile="$stripped.u"
+ if test "$libtool" = yes; then
+ "$@" -Wc,-M
+ else
+ "$@" -M
+ fi
+ stat=$?
+
+ if test -f "$tmpdepfile"; then :
+ else
+ stripped=`echo "$stripped" | sed 's,^.*/,,'`
+ tmpdepfile="$stripped.u"
+ fi
+
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile"; then
+ outname="$stripped.o"
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+ sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler understands `-MD -MF file'. However on
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using \ :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+ sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ # With Tru64 cc, shared objects can also be used to make a
+ # static library. This mecanism is used in libtool 1.4 series to
+ # handle both shared and static libraries in a single compilation.
+ # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+ #
+ # With libtool 1.5 this exception was removed, and libtool now
+ # generates 2 separate objects for the 2 libraries. These two
+ # compilations output dependencies in in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
+ tmpdepfile2=$dir$base.o.d # libtool 1.5
+ tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
+ tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.o.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ tmpdepfile4=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for `:'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no
+ for arg in "$@"; do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix="`echo $object | sed 's/^.*\././'`"
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ "$@" || exit $?
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/lib/liblame/frontend/get_audio.c b/lib/liblame/frontend/get_audio.c
new file mode 100644
index 0000000000..04bf3bf744
--- /dev/null
+++ b/lib/liblame/frontend/get_audio.c
@@ -0,0 +1,1806 @@
+/*
+ * Get Audio routines source file
+ *
+ * Copyright (c) 1999 Albert L Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: get_audio.c,v 1.125.2.2 2009/01/18 15:44:28 robert Exp $ */
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else
+# ifndef HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+char *strchr(), *strrchr();
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# define memmove(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+
+#define MAX_U_32_NUM 0xFFFFFFFF
+
+
+#include <math.h>
+#include <sys/stat.h>
+
+#ifdef __sun__
+/* woraround for SunOS 4.x, it has SEEK_* defined here */
+#include <unistd.h>
+#endif
+
+#include "lame.h"
+#include "main.h"
+#include "get_audio.h"
+#include "portableio.h"
+#include "timestatus.h"
+#include "lametime.h"
+#include "console.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+
+/* global data for get_audio.c. */
+typedef struct get_audio_global_data {
+ int count_samples_carefully;
+ int pcmbitwidth;
+ int pcmswapbytes;
+ int pcm_is_unsigned_8bit;
+ unsigned int num_samples_read;
+ FILE *musicin;
+ hip_t hip;
+} get_audio_global_data;
+
+static get_audio_global_data global = { 0, 0, 0, 0, 0, 0, 0 };
+
+
+
+#ifdef AMIGA_MPEGA
+int lame_decode_initfile(const char *fullname, mp3data_struct * const mp3data);
+#else
+int lame_decode_initfile(FILE * fd, mp3data_struct * mp3data, int *enc_delay, int *enc_padding);
+#endif
+
+/* read mp3 file until mpglib returns one frame of PCM data */
+int lame_decode_fromfile(FILE * fd, short int pcm_l[], short int pcm_r[],
+ mp3data_struct * mp3data);
+
+
+static int read_samples_pcm(FILE * musicin, int sample_buffer[2304], int samples_to_read);
+static int read_samples_mp3(lame_global_flags * const gfp, FILE * const musicin,
+ short int mpg123pcm[2][1152]);
+void CloseSndFile(sound_file_format input, FILE * musicin);
+FILE *OpenSndFile(lame_global_flags * gfp, char *, int *enc_delay, int *enc_padding);
+
+
+static size_t
+min_size_t(size_t a, size_t b)
+{
+ if (a < b) {
+ return a;
+ }
+ return b;
+}
+
+enum ByteOrder machine_byte_order(void);
+
+enum ByteOrder
+machine_byte_order(void)
+{
+ long one= 1;
+ return !(*((char *)(&one))) ? ByteOrderBigEndian : ByteOrderLittleEndian;
+}
+
+
+
+/* Replacement for forward fseek(,,SEEK_CUR), because fseek() fails on pipes */
+
+
+static int
+fskip(FILE * fp, long offset, int whence)
+{
+#ifndef PIPE_BUF
+ char buffer[4096];
+#else
+ char buffer[PIPE_BUF];
+#endif
+
+/* S_ISFIFO macro is defined on newer Linuxes */
+#ifndef S_ISFIFO
+# ifdef _S_IFIFO
+ /* _S_IFIFO is defined on Win32 and Cygwin */
+# define S_ISFIFO(m) (((m)&_S_IFIFO) == _S_IFIFO)
+# endif
+#endif
+
+#ifdef S_ISFIFO
+ /* fseek is known to fail on pipes with several C-Library implementations
+ workaround: 1) test for pipe
+ 2) for pipes, only relatvie seeking is possible
+ 3) and only in forward direction!
+ else fallback to old code
+ */
+ {
+ int const fd = fileno(fp);
+ struct stat file_stat;
+
+ if (fstat(fd, &file_stat) == 0) {
+ if (S_ISFIFO(file_stat.st_mode)) {
+ if (whence != SEEK_CUR || offset < 0) {
+ return -1;
+ }
+ while (offset > 0) {
+ size_t const bytes_to_skip = min_size_t(sizeof(buffer), offset);
+ size_t const read = fread(buffer, 1, bytes_to_skip, fp);
+ if (read < 1) {
+ return -1;
+ }
+ offset -= read;
+ }
+ return 0;
+ }
+ }
+ }
+#endif
+ if (0 == fseek(fp, offset, whence)) {
+ return 0;
+ }
+
+ if (whence != SEEK_CUR || offset < 0) {
+ if (silent < 10) {
+ error_printf
+ ("fskip problem: Mostly the return status of functions is not evaluate so it is more secure to polute <stderr>.\n");
+ }
+ return -1;
+ }
+
+ while (offset > 0) {
+ size_t const bytes_to_skip = min_size_t(sizeof(buffer), offset);
+ size_t const read = fread(buffer, 1, bytes_to_skip, fp);
+ if (read < 1) {
+ return -1;
+ }
+ offset -= read;
+ }
+
+ return 0;
+}
+
+
+FILE *
+init_outfile(char *outPath, int decode)
+{
+ FILE *outf;
+#ifdef __riscos__
+ char *p;
+#endif
+
+ /* open the output file */
+ if (0 == strcmp(outPath, "-")) {
+ lame_set_stream_binary_mode(outf = stdout);
+ }
+ else {
+ if ((outf = fopen(outPath, "w+b")) == NULL)
+ return NULL;
+#ifdef __riscos__
+ /* Assign correct file type */
+ for (p = outPath; *p; p++) /* ugly, ugly to modify a string */
+ switch (*p) {
+ case '.':
+ *p = '/';
+ break;
+ case '/':
+ *p = '.';
+ break;
+ }
+ SetFiletype(outPath, decode ? 0xFB1 /*WAV*/ : 0x1AD /*AMPEG*/);
+#else
+ (void) decode;
+#endif
+ }
+ return outf;
+}
+
+
+
+
+
+
+void
+init_infile(lame_global_flags * gfp, char *inPath, int *enc_delay, int *enc_padding)
+{
+ /* open the input file */
+ global. count_samples_carefully = 0;
+ global. num_samples_read = 0;
+ global. pcmbitwidth = in_bitwidth;
+ global. pcmswapbytes = swapbytes;
+ global. pcm_is_unsigned_8bit = in_signed == 1 ? 0 : 1;
+ global. musicin = OpenSndFile(gfp, inPath, enc_delay, enc_padding);
+}
+
+void
+close_infile(void)
+{
+ CloseSndFile(input_format, global.musicin);
+}
+
+
+void
+SwapBytesInWords(short *ptr, int short_words)
+{ /* Some speedy code */
+ unsigned long val;
+ unsigned long *p = (unsigned long *) ptr;
+
+#ifndef lint
+# if defined(CHAR_BIT)
+# if CHAR_BIT != 8
+# error CHAR_BIT != 8
+# endif
+# else
+# error can not determine number of bits in a char
+# endif
+#endif /* lint */
+
+ assert(sizeof(short) == 2);
+
+
+#if defined(SIZEOF_UNSIGNED_LONG) && SIZEOF_UNSIGNED_LONG == 4
+ for (; short_words >= 2; short_words -= 2, p++) {
+ val = *p;
+ *p = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0x00FF00FF);
+ }
+ ptr = (short *) p;
+ for (; short_words >= 1; short_words -= 1, ptr++) {
+ val = *ptr;
+ *ptr = (short) (((val << 8) & 0xFF00) | ((val >> 8) & 0x00FF));
+ }
+#elif defined(SIZEOF_UNSIGNED_LONG) && SIZEOF_UNSIGNED_LONG == 8
+ for (; short_words >= 4; short_words -= 4, p++) {
+ val = *p;
+ *p = ((val << 8) & 0xFF00FF00FF00FF00) | ((val >> 8) & 0x00FF00FF00FF00FF);
+ }
+ ptr = (short *) p;
+ for (; short_words >= 1; short_words -= 1, ptr++) {
+ val = *ptr;
+ *ptr = ((val << 8) & 0xFF00) | ((val >> 8) & 0x00FF);
+ }
+#else
+# ifdef SIZEOF_UNSIGNED_LONG
+# warning Using unoptimized SwapBytesInWords().
+# endif
+ for (; short_words >= 1; short_words -= 1, ptr++) {
+ val = *ptr;
+ *ptr = ((val << 8) & 0xFF00) | ((val >> 8) & 0x00FF);
+ }
+#endif
+
+ assert(short_words == 0);
+}
+
+
+
+static int
+get_audio_common(lame_global_flags * const gfp,
+ int buffer[2][1152], short buffer16[2][1152]);
+
+/************************************************************************
+*
+* get_audio()
+*
+* PURPOSE: reads a frame of audio data from a file to the buffer,
+* aligns the data for future processing, and separates the
+* left and right channels
+*
+************************************************************************/
+int
+get_audio(lame_global_flags * const gfp, int buffer[2][1152])
+{
+ return (get_audio_common(gfp, buffer, NULL));
+}
+
+/*
+ get_audio16 - behave as the original get_audio function, with a limited
+ 16 bit per sample output
+*/
+int
+get_audio16(lame_global_flags * const gfp, short buffer[2][1152])
+{
+ return (get_audio_common(gfp, NULL, buffer));
+}
+
+/************************************************************************
+ get_audio_common - central functionality of get_audio*
+ in: gfp
+ buffer output to the int buffer or 16-bit buffer
+ out: buffer int output (if buffer != NULL)
+ buffer16 16-bit output (if buffer == NULL)
+returns: samples read
+note: either buffer or buffer16 must be allocated upon call
+*/
+static int
+get_audio_common(lame_global_flags * const gfp, int buffer[2][1152], short buffer16[2][1152])
+{
+ int num_channels = lame_get_num_channels(gfp);
+ int insamp[2 * 1152];
+ short buf_tmp16[2][1152];
+ int samples_read;
+ int framesize;
+ int samples_to_read;
+ unsigned int remaining, tmp_num_samples;
+ int i;
+ int *p;
+
+ /*
+ * NOTE: LAME can now handle arbritray size input data packets,
+ * so there is no reason to read the input data in chuncks of
+ * size "framesize". EXCEPT: the LAME graphical frame analyzer
+ * will get out of sync if we read more than framesize worth of data.
+ */
+
+ samples_to_read = framesize = lame_get_framesize(gfp);
+ assert(framesize <= 1152);
+
+ /* get num_samples */
+ tmp_num_samples = lame_get_num_samples(gfp);
+
+ /* if this flag has been set, then we are carefull to read
+ * exactly num_samples and no more. This is useful for .wav and .aiff
+ * files which have id3 or other tags at the end. Note that if you
+ * are using LIBSNDFILE, this is not necessary
+ */
+ if (global.count_samples_carefully) {
+ remaining = tmp_num_samples - Min(tmp_num_samples, global.num_samples_read);
+ if (remaining < (unsigned int) framesize && 0 != tmp_num_samples)
+ /* in case the input is a FIFO (at least it's reproducible with
+ a FIFO) tmp_num_samples may be 0 and therefore remaining
+ would be 0, but we need to read some samples, so don't
+ change samples_to_read to the wrong value in this case */
+ samples_to_read = remaining;
+ }
+
+ if (is_mpeg_file_format(input_format)) {
+ if (buffer != NULL)
+ samples_read = read_samples_mp3(gfp, global.musicin, buf_tmp16);
+ else
+ samples_read = read_samples_mp3(gfp, global.musicin, buffer16);
+ if (samples_read < 0) {
+ return samples_read;
+ }
+ }
+ else {
+ samples_read = read_samples_pcm(global.musicin, insamp, num_channels * samples_to_read);
+ if (samples_read < 0) {
+ return samples_read;
+ }
+ p = insamp + samples_read;
+ samples_read /= num_channels;
+ if (buffer != NULL) { /* output to int buffer */
+ if (num_channels == 2) {
+ for (i = samples_read; --i >= 0;) {
+ buffer[1][i] = *--p;
+ buffer[0][i] = *--p;
+ }
+ }
+ else if (num_channels == 1) {
+ memset(buffer[1], 0, samples_read * sizeof(int));
+ for (i = samples_read; --i >= 0;) {
+ buffer[0][i] = *--p;
+ }
+ }
+ else
+ assert(0);
+ }
+ else { /* convert from int; output to 16-bit buffer */
+ if (num_channels == 2) {
+ for (i = samples_read; --i >= 0;) {
+ buffer16[1][i] = *--p >> (8 * sizeof(int) - 16);
+ buffer16[0][i] = *--p >> (8 * sizeof(int) - 16);
+ }
+ }
+ else if (num_channels == 1) {
+ memset(buffer16[1], 0, samples_read * sizeof(short));
+ for (i = samples_read; --i >= 0;) {
+ buffer16[0][i] = *--p >> (8 * sizeof(int) - 16);
+ }
+ }
+ else
+ assert(0);
+ }
+ }
+
+ /* LAME mp3 output 16bit - convert to int, if necessary */
+ if (is_mpeg_file_format(input_format)) {
+ if (buffer != NULL) {
+ for (i = samples_read; --i >= 0;)
+ buffer[0][i] = buf_tmp16[0][i] << (8 * sizeof(int) - 16);
+ if (num_channels == 2) {
+ for (i = samples_read; --i >= 0;)
+ buffer[1][i] = buf_tmp16[1][i] << (8 * sizeof(int) - 16);
+ }
+ else if (num_channels == 1) {
+ memset(buffer[1], 0, samples_read * sizeof(int));
+ }
+ else
+ assert(0);
+ }
+ }
+
+
+ /* if num_samples = MAX_U_32_NUM, then it is considered infinitely long.
+ Don't count the samples */
+ if (tmp_num_samples != MAX_U_32_NUM)
+ global. num_samples_read += samples_read;
+
+ return samples_read;
+}
+
+
+
+static int
+read_samples_mp3(lame_global_flags * const gfp, FILE * const musicin, short int mpg123pcm[2][1152])
+{
+ int out;
+#if defined(AMIGA_MPEGA) || defined(HAVE_MPGLIB)
+ static const char type_name[] = "MP3 file";
+
+ out = lame_decode_fromfile(musicin, mpg123pcm[0], mpg123pcm[1], &mp3input_data);
+ /*
+ * out < 0: error, probably EOF
+ * out = 0: not possible with lame_decode_fromfile() ???
+ * out > 0: number of output samples
+ */
+ if (out < 0) {
+ memset(mpg123pcm, 0, sizeof(**mpg123pcm) * 2 * 1152);
+ return 0;
+ }
+
+ if (lame_get_num_channels(gfp) != mp3input_data.stereo) {
+ if (silent < 10) {
+ error_printf("Error: number of channels has changed in %s - not supported\n",
+ type_name);
+ }
+ out = -1;
+ }
+ if (lame_get_in_samplerate(gfp) != mp3input_data.samplerate) {
+ if (silent < 10) {
+ error_printf("Error: sample frequency has changed in %s - not supported\n", type_name);
+ }
+ out = -1;
+ }
+#else
+ out = -1;
+#endif
+ return out;
+}
+
+
+int
+WriteWaveHeader(FILE * const fp, const int pcmbytes,
+ const int freq, const int channels, const int bits)
+{
+ int bytes = (bits + 7) / 8;
+
+ /* quick and dirty, but documented */
+ fwrite("RIFF", 1, 4, fp); /* label */
+ Write32BitsLowHigh(fp, pcmbytes + 44 - 8); /* length in bytes without header */
+ fwrite("WAVEfmt ", 2, 4, fp); /* 2 labels */
+ Write32BitsLowHigh(fp, 2 + 2 + 4 + 4 + 2 + 2); /* length of PCM format declaration area */
+ Write16BitsLowHigh(fp, 1); /* is PCM? */
+ Write16BitsLowHigh(fp, channels); /* number of channels */
+ Write32BitsLowHigh(fp, freq); /* sample frequency in [Hz] */
+ Write32BitsLowHigh(fp, freq * channels * bytes); /* bytes per second */
+ Write16BitsLowHigh(fp, channels * bytes); /* bytes per sample time */
+ Write16BitsLowHigh(fp, bits); /* bits per sample */
+ fwrite("data", 1, 4, fp); /* label */
+ Write32BitsLowHigh(fp, pcmbytes); /* length in bytes of raw PCM data */
+
+ return ferror(fp) ? -1 : 0;
+}
+
+
+
+
+#if defined(LIBSNDFILE)
+
+/*
+** Copyright (C) 1999 Albert Faber
+**
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+
+
+
+
+void
+CloseSndFile(sound_file_format input, FILE * musicin)
+{
+ SNDFILE *gs_pSndFileIn = (SNDFILE *) musicin;
+ if (is_mpeg_file_format(input)) {
+#ifndef AMIGA_MPEGA
+ if (fclose(musicin) != 0) {
+ if (silent < 10) {
+ error_printf("Could not close audio input file\n");
+ }
+ exit(2);
+ }
+#endif
+ }
+ else {
+ if (gs_pSndFileIn) {
+ if (sf_close(gs_pSndFileIn) != 0) {
+ if (silent < 10) {
+ error_printf("Could not close sound file \n");
+ }
+ exit(2);
+ }
+ }
+ }
+}
+
+
+
+FILE *
+OpenSndFile(lame_global_flags * gfp, char *inPath, int *enc_delay, int *enc_padding)
+{
+ char *lpszFileName = inPath;
+ FILE *musicin;
+ SNDFILE *gs_pSndFileIn = NULL;
+ SF_INFO gs_wfInfo;
+
+ if (is_mpeg_file_format(input_format)) {
+#ifdef AMIGA_MPEGA
+ if (-1 == lame_decode_initfile(lpszFileName, &mp3input_data)) {
+ if (silent < 10) {
+ error_printf("Error reading headers in mp3 input file %s.\n", lpszFileName);
+ }
+ exit(1);
+ }
+#endif
+#ifdef HAVE_MPGLIB
+ if ((musicin = fopen(lpszFileName, "rb")) == NULL) {
+ if (silent < 10) {
+ error_printf("Could not find \"%s\".\n", lpszFileName);
+ }
+ exit(1);
+ }
+ if (-1 == lame_decode_initfile(musicin, &mp3input_data, enc_delay, enc_padding)) {
+ if (silent < 10) {
+ error_printf("Error reading headers in mp3 input file %s.\n", lpszFileName);
+ }
+ exit(1);
+ }
+#endif
+
+ if (-1 == lame_set_num_channels(gfp, mp3input_data.stereo)) {
+ if (silent < 10) {
+ error_printf("Unsupported number of channels: %ud\n", mp3input_data.stereo);
+ }
+ exit(1);
+ }
+ (void) lame_set_in_samplerate(gfp, mp3input_data.samplerate);
+ (void) lame_set_num_samples(gfp, mp3input_data.nsamp);
+ }
+ else if (input_format == sf_ogg) {
+ if (silent < 10) {
+ error_printf("sorry, vorbis support in LAME is deprecated.\n");
+ }
+ exit(1);
+ }
+ else {
+ /* Try to open the sound file */
+ memset(&gs_wfInfo, 0, sizeof(gs_wfInfo));
+ gs_pSndFileIn = sf_open(lpszFileName, SFM_READ, &gs_wfInfo);
+
+ if (gs_pSndFileIn == NULL) {
+ if (in_signed == 0 && in_bitwidth != 8) {
+ fputs("Unsigned input only supported with bitwidth 8\n", stderr);
+ exit(1);
+ }
+ /* set some defaults incase input is raw PCM */
+ gs_wfInfo.seekable = (input_format != sf_raw); /* if user specified -r, set to not seekable */
+ gs_wfInfo.samplerate = lame_get_in_samplerate(gfp);
+ gs_wfInfo.channels = lame_get_num_channels(gfp);
+ gs_wfInfo.format = SF_FORMAT_RAW;
+ if ((in_endian == ByteOrderLittleEndian) ^ (swapbytes != 0)) {
+ gs_wfInfo.format |= SF_ENDIAN_LITTLE;
+ }
+ else {
+ gs_wfInfo.format |= SF_ENDIAN_BIG;
+ }
+ switch (in_bitwidth) {
+ case 8:
+ gs_wfInfo.format |= in_signed == 0 ? SF_FORMAT_PCM_U8 : SF_FORMAT_PCM_S8;
+ break;
+ case 16:
+ gs_wfInfo.format |= SF_FORMAT_PCM_16;
+ break;
+ case 24:
+ gs_wfInfo.format |= SF_FORMAT_PCM_24;
+ break;
+ case 32:
+ gs_wfInfo.format |= SF_FORMAT_PCM_32;
+ break;
+ default:
+ break;
+ }
+ gs_pSndFileIn = sf_open(lpszFileName, SFM_READ, &gs_wfInfo);
+ }
+
+ musicin = (FILE *) gs_pSndFileIn;
+
+ /* Check result */
+ if (gs_pSndFileIn == NULL) {
+ sf_perror(gs_pSndFileIn);
+ if (silent < 10) {
+ error_printf("Could not open sound file \"%s\".\n", lpszFileName);
+ }
+ exit(1);
+ }
+
+ if ((gs_wfInfo.format & SF_FORMAT_RAW) == SF_FORMAT_RAW) {
+ input_format = sf_raw;
+ }
+
+#ifdef _DEBUG_SND_FILE
+ DEBUGF("\n\nSF_INFO structure\n");
+ DEBUGF("samplerate :%d\n", gs_wfInfo.samplerate);
+ DEBUGF("samples :%d\n", gs_wfInfo.frames);
+ DEBUGF("channels :%d\n", gs_wfInfo.channels);
+ DEBUGF("format :");
+
+ /* new formats from sbellon@sbellon.de 1/2000 */
+
+ switch (gs_wfInfo.format & SF_FORMAT_TYPEMASK) {
+ case SF_FORMAT_WAV:
+ DEBUGF("Microsoft WAV format (big endian). ");
+ break;
+ case SF_FORMAT_AIFF:
+ DEBUGF("Apple/SGI AIFF format (little endian). ");
+ break;
+ case SF_FORMAT_AU:
+ DEBUGF("Sun/NeXT AU format (big endian). ");
+ break;
+ /*
+ case SF_FORMAT_AULE:
+ DEBUGF("DEC AU format (little endian). ");
+ break;
+ */
+ case SF_FORMAT_RAW:
+ DEBUGF("RAW PCM data. ");
+ break;
+ case SF_FORMAT_PAF:
+ DEBUGF("Ensoniq PARIS file format. ");
+ break;
+ case SF_FORMAT_SVX:
+ DEBUGF("Amiga IFF / SVX8 / SV16 format. ");
+ break;
+ case SF_FORMAT_NIST:
+ DEBUGF("Sphere NIST format. ");
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ switch (gs_wfInfo.format & SF_FORMAT_SUBMASK) {
+ /*
+ case SF_FORMAT_PCM:
+ DEBUGF("PCM data in 8, 16, 24 or 32 bits.");
+ break;
+ */
+ case SF_FORMAT_FLOAT:
+ DEBUGF("32 bit Intel x86 floats.");
+ break;
+ case SF_FORMAT_ULAW:
+ DEBUGF("U-Law encoded.");
+ break;
+ case SF_FORMAT_ALAW:
+ DEBUGF("A-Law encoded.");
+ break;
+ case SF_FORMAT_IMA_ADPCM:
+ DEBUGF("IMA ADPCM.");
+ break;
+ case SF_FORMAT_MS_ADPCM:
+ DEBUGF("Microsoft ADPCM.");
+ break;
+ /*
+ case SF_FORMAT_PCM_BE:
+ DEBUGF("Big endian PCM data.");
+ break;
+ case SF_FORMAT_PCM_LE:
+ DEBUGF("Little endian PCM data.");
+ break;
+ */
+ case SF_FORMAT_PCM_S8:
+ DEBUGF("Signed 8 bit PCM.");
+ break;
+ case SF_FORMAT_PCM_U8:
+ DEBUGF("Unsigned 8 bit PCM.");
+ break;
+ case SF_FORMAT_PCM_16:
+ DEBUGF("Signed 16 bit PCM.");
+ break;
+ case SF_FORMAT_PCM_24:
+ DEBUGF("Signed 24 bit PCM.");
+ break;
+ case SF_FORMAT_PCM_32:
+ DEBUGF("Signed 32 bit PCM.");
+ break;
+ /*
+ case SF_FORMAT_SVX_FIB:
+ DEBUGF("SVX Fibonacci Delta encoding.");
+ break;
+ case SF_FORMAT_SVX_EXP:
+ DEBUGF("SVX Exponential Delta encoding.");
+ break;
+ */
+ default:
+ assert(0);
+ break;
+ }
+
+ DEBUGF("\n");
+ DEBUGF("sections :%d\n", gs_wfInfo.sections);
+ DEBUGF("seekable :\n", gs_wfInfo.seekable);
+#endif
+ /* Check result */
+ if (gs_pSndFileIn == NULL) {
+ sf_perror(gs_pSndFileIn);
+ if (silent < 10) {
+ error_printf("Could not open sound file \"%s\".\n", lpszFileName);
+ }
+ exit(1);
+ }
+
+
+ (void) lame_set_num_samples(gfp, gs_wfInfo.frames);
+ if (-1 == lame_set_num_channels(gfp, gs_wfInfo.channels)) {
+ if (silent < 10) {
+ error_printf("Unsupported number of channels: %ud\n", gs_wfInfo.channels);
+ }
+ exit(1);
+ }
+ (void) lame_set_in_samplerate(gfp, gs_wfInfo.samplerate);
+ global. pcmbitwidth = 32;
+ }
+
+ if (lame_get_num_samples(gfp) == MAX_U_32_NUM) {
+ /* try to figure out num_samples */
+ double flen = lame_get_file_size(lpszFileName);
+
+ if (flen >= 0) {
+ /* try file size, assume 2 bytes per sample */
+ if (is_mpeg_file_format(input_format)) {
+ if (mp3input_data.bitrate > 0) {
+ double totalseconds = (flen * 8.0 / (1000.0 * mp3input_data.bitrate));
+ unsigned long tmp_num_samples = totalseconds * lame_get_in_samplerate(gfp);
+
+ (void) lame_set_num_samples(gfp, tmp_num_samples);
+ mp3input_data.nsamp = tmp_num_samples;
+ }
+ }
+ else {
+ lame_set_num_samples(gfp, flen / (2 * lame_get_num_channels(gfp)));
+ }
+ }
+ }
+
+
+ return musicin;
+}
+
+
+/************************************************************************
+*
+* read_samples()
+*
+* PURPOSE: reads the PCM samples from a file to the buffer
+*
+* SEMANTICS:
+* Reads #samples_read# number of shorts from #musicin# filepointer
+* into #sample_buffer[]#. Returns the number of samples read.
+*
+************************************************************************/
+
+static int
+read_samples_pcm(FILE * const musicin, int sample_buffer[2304], int samples_to_read)
+{
+ int samples_read;
+
+ samples_read = sf_read_int((SNDFILE *) musicin, sample_buffer, samples_to_read);
+
+#if 0
+ switch (global.pcmbitwidth) {
+ case 8:
+ for (i = 0; i < samples_read; i++)
+ sample_buffer[i] <<= (8 * sizeof(int) - 8);
+ break;
+ case 16:
+ for (i = 0; i < samples_read; i++)
+ sample_buffer[i] <<= (8 * sizeof(int) - 16);
+ break;
+ case 24:
+ for (i = 0; i < samples_read; i++)
+ sample_buffer[i] <<= (8 * sizeof(int) - 24);
+ break;
+ case 32:
+ break;
+ default:
+ if (silent < 10) {
+ error_printf("Only 8, 16, 24 and 32 bit input files supported \n");
+ }
+ exit(1);
+ }
+#endif
+
+ return samples_read;
+}
+
+
+#else /* defined(LIBSNDFILE) */
+
+/************************************************************************
+ ************************************************************************
+ ************************************************************************
+ ************************************************************************
+ ************************************************************************
+ ************************************************************************
+ *
+ * OLD ISO/LAME routines follow. Used if you dont have LIBSNDFILE
+ * or for stdin/stdout support
+ *
+ ************************************************************************
+ ************************************************************************
+ ************************************************************************
+ ************************************************************************
+ ************************************************************************
+ ************************************************************************/
+
+
+
+/************************************************************************
+unpack_read_samples - read and unpack signed low-to-high byte or unsigned
+ single byte input. (used for read_samples function)
+ Output integers are stored in the native byte order
+ (little or big endian). -jd
+ in: samples_to_read
+ bytes_per_sample
+ swap_order - set for high-to-low byte order input stream
+ i/o: pcm_in
+ out: sample_buffer (must be allocated up to samples_to_read upon call)
+returns: number of samples read
+*/
+static int
+unpack_read_samples(const int samples_to_read, const int bytes_per_sample,
+ const int swap_order, int *sample_buffer, FILE * pcm_in)
+{
+ size_t samples_read;
+ int i;
+ int *op; /* output pointer */
+ unsigned char *ip = (unsigned char *) sample_buffer; /* input pointer */
+ const int b = sizeof(int) * 8;
+
+#define GA_URS_IFLOOP( ga_urs_bps ) \
+ if( bytes_per_sample == ga_urs_bps ) \
+ for( i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >=0;)
+
+ samples_read = fread(sample_buffer, bytes_per_sample, samples_to_read, pcm_in);
+ op = sample_buffer + samples_read;
+
+ if (swap_order == 0) {
+ GA_URS_IFLOOP(1)
+ * --op = ip[i] << (b - 8);
+ GA_URS_IFLOOP(2)
+ * --op = ip[i] << (b - 16) | ip[i + 1] << (b - 8);
+ GA_URS_IFLOOP(3)
+ * --op = ip[i] << (b - 24) | ip[i + 1] << (b - 16) | ip[i + 2] << (b - 8);
+ GA_URS_IFLOOP(4)
+ * --op =
+ ip[i] << (b - 32) | ip[i + 1] << (b - 24) | ip[i + 2] << (b - 16) | ip[i + 3] << (b -
+ 8);
+ }
+ else {
+ GA_URS_IFLOOP(1)
+ * --op = (ip[i] ^ 0x80) << (b - 8) | 0x7f << (b - 16); /* convert from unsigned */
+ GA_URS_IFLOOP(2)
+ * --op = ip[i] << (b - 8) | ip[i + 1] << (b - 16);
+ GA_URS_IFLOOP(3)
+ * --op = ip[i] << (b - 8) | ip[i + 1] << (b - 16) | ip[i + 2] << (b - 24);
+ GA_URS_IFLOOP(4)
+ * --op =
+ ip[i] << (b - 8) | ip[i + 1] << (b - 16) | ip[i + 2] << (b - 24) | ip[i + 3] << (b -
+ 32);
+ }
+#undef GA_URS_IFLOOP
+ return (samples_read);
+}
+
+
+
+/************************************************************************
+*
+* read_samples()
+*
+* PURPOSE: reads the PCM samples from a file to the buffer
+*
+* SEMANTICS:
+* Reads #samples_read# number of shorts from #musicin# filepointer
+* into #sample_buffer[]#. Returns the number of samples read.
+*
+************************************************************************/
+
+static int
+read_samples_pcm(FILE * musicin, int sample_buffer[2304], int samples_to_read)
+{
+ int samples_read;
+ int swap_byte_order; /* byte order of input stream */
+
+ switch (global.pcmbitwidth) {
+ case 32:
+ case 24:
+ case 16:
+ if (in_signed == 0) {
+ error_printf("Unsigned input only supported with bitwidth 8\n");
+ exit(1);
+ }
+ {
+ swap_byte_order = (in_endian != ByteOrderLittleEndian) ? 1 : 0;
+ if (global.pcmswapbytes) {
+ swap_byte_order = !swap_byte_order;
+ }
+ samples_read = unpack_read_samples(samples_to_read, global.pcmbitwidth / 8,
+ swap_byte_order, sample_buffer, musicin);
+
+ }
+ break;
+
+ case 8:
+ {
+ samples_read = unpack_read_samples(samples_to_read, 1, global.pcm_is_unsigned_8bit,
+ sample_buffer, musicin);
+ }
+ break;
+
+ default:
+ {
+ if (silent < 10) {
+ error_printf("Only 8, 16, 24 and 32 bit input files supported \n");
+ }
+ exit(1);
+ }
+ break;
+ }
+ if (ferror(musicin)) {
+ if (silent < 10) {
+ error_printf("Error reading input file\n");
+ }
+ exit(1);
+ }
+
+ return samples_read;
+}
+
+
+
+/* AIFF Definitions */
+
+static int const IFF_ID_FORM = 0x464f524d; /* "FORM" */
+static int const IFF_ID_AIFF = 0x41494646; /* "AIFF" */
+static int const IFF_ID_AIFC = 0x41494643; /* "AIFC" */
+static int const IFF_ID_COMM = 0x434f4d4d; /* "COMM" */
+static int const IFF_ID_SSND = 0x53534e44; /* "SSND" */
+static int const IFF_ID_MPEG = 0x4d504547; /* "MPEG" */
+
+static int const IFF_ID_NONE = 0x4e4f4e45; /* "NONE" */ /* AIFF-C data format */
+static int const IFF_ID_2CBE = 0x74776f73; /* "twos" */ /* AIFF-C data format */
+static int const IFF_ID_2CLE = 0x736f7774; /* "sowt" */ /* AIFF-C data format */
+
+static int const WAV_ID_RIFF = 0x52494646; /* "RIFF" */
+static int const WAV_ID_WAVE = 0x57415645; /* "WAVE" */
+static int const WAV_ID_FMT = 0x666d7420; /* "fmt " */
+static int const WAV_ID_DATA = 0x64617461; /* "data" */
+
+#ifndef WAVE_FORMAT_PCM
+static short const WAVE_FORMAT_PCM = 0x0001;
+#endif
+#ifndef WAVE_FORMAT_EXTENSIBLE
+static short const WAVE_FORMAT_EXTENSIBLE = 0xFFFE;
+#endif
+
+
+/*****************************************************************************
+ *
+ * Read Microsoft Wave headers
+ *
+ * By the time we get here the first 32-bits of the file have already been
+ * read, and we're pretty sure that we're looking at a WAV file.
+ *
+ *****************************************************************************/
+
+static int
+parse_wave_header(lame_global_flags * gfp, FILE * sf)
+{
+ int format_tag = 0;
+ int channels = 0;
+ int block_align = 0;
+ int bits_per_sample = 0;
+ int samples_per_sec = 0;
+ int avg_bytes_per_sec = 0;
+
+
+ int is_wav = 0;
+ long data_length = 0, file_length, subSize = 0;
+ int loop_sanity = 0;
+
+ file_length = Read32BitsHighLow(sf);
+ if (Read32BitsHighLow(sf) != WAV_ID_WAVE)
+ return -1;
+
+ for (loop_sanity = 0; loop_sanity < 20; ++loop_sanity) {
+ int type = Read32BitsHighLow(sf);
+
+ if (type == WAV_ID_FMT) {
+ subSize = Read32BitsLowHigh(sf);
+ if (subSize < 16) {
+ /*DEBUGF(
+ "'fmt' chunk too short (only %ld bytes)!", subSize); */
+ return -1;
+ }
+
+ format_tag = Read16BitsLowHigh(sf);
+ subSize -= 2;
+ channels = Read16BitsLowHigh(sf);
+ subSize -= 2;
+ samples_per_sec = Read32BitsLowHigh(sf);
+ subSize -= 4;
+ avg_bytes_per_sec = Read32BitsLowHigh(sf);
+ subSize -= 4;
+ block_align = Read16BitsLowHigh(sf);
+ subSize -= 2;
+ bits_per_sample = Read16BitsLowHigh(sf);
+ subSize -= 2;
+
+ /* WAVE_FORMAT_EXTENSIBLE support */
+ if ((subSize > 9) && (format_tag == WAVE_FORMAT_EXTENSIBLE)) {
+ Read16BitsLowHigh(sf); /* cbSize */
+ Read16BitsLowHigh(sf); /* ValidBitsPerSample */
+ Read32BitsLowHigh(sf); /* ChannelMask */
+ /* SubType coincident with format_tag for PCM int or float */
+ format_tag = Read16BitsLowHigh(sf);
+ subSize -= 10;
+ }
+
+ /* DEBUGF(" skipping %d bytes\n", subSize); */
+
+ if (subSize > 0) {
+ if (fskip(sf, (long) subSize, SEEK_CUR) != 0)
+ return -1;
+ };
+
+ }
+ else if (type == WAV_ID_DATA) {
+ subSize = Read32BitsLowHigh(sf);
+ data_length = subSize;
+ is_wav = 1;
+ /* We've found the audio data. Read no further! */
+ break;
+
+ }
+ else {
+ subSize = Read32BitsLowHigh(sf);
+ if (fskip(sf, (long) subSize, SEEK_CUR) != 0) {
+ return -1;
+ }
+ }
+ }
+
+ if (is_wav) {
+ if (format_tag != WAVE_FORMAT_PCM) {
+ if (silent < 10) {
+ error_printf("Unsupported data format: 0x%04X\n", format_tag);
+ }
+ return 0; /* oh no! non-supported format */
+ }
+
+
+ /* make sure the header is sane */
+ if (-1 == lame_set_num_channels(gfp, channels)) {
+ if (silent < 10) {
+ error_printf("Unsupported number of channels: %u\n", channels);
+ }
+ return 0;
+ }
+ (void) lame_set_in_samplerate(gfp, samples_per_sec);
+ global. pcmbitwidth = bits_per_sample;
+ global. pcm_is_unsigned_8bit = 1;
+ (void) lame_set_num_samples(gfp, data_length / (channels * ((bits_per_sample + 7) / 8)));
+ return 1;
+ }
+ return -1;
+}
+
+
+
+/************************************************************************
+* aiff_check2
+*
+* PURPOSE: Checks AIFF header information to make sure it is valid.
+* returns 0 on success, 1 on errors
+************************************************************************/
+
+static int
+aiff_check2(IFF_AIFF * const pcm_aiff_data)
+{
+ if (pcm_aiff_data->sampleType != (unsigned long) IFF_ID_SSND) {
+ if (silent < 10) {
+ error_printf("ERROR: input sound data is not PCM\n");
+ }
+ return 1;
+ }
+ switch (pcm_aiff_data->sampleSize) {
+ case 32:
+ case 24:
+ case 16:
+ case 8:
+ break;
+ default:
+ if (silent < 10) {
+ error_printf("ERROR: input sound data is not 8, 16, 24 or 32 bits\n");
+ }
+ return 1;
+ }
+ if (pcm_aiff_data->numChannels != 1 && pcm_aiff_data->numChannels != 2) {
+ if (silent < 10) {
+ error_printf("ERROR: input sound data is not mono or stereo\n");
+ }
+ return 1;
+ }
+ if (pcm_aiff_data->blkAlgn.blockSize != 0) {
+ if (silent < 10) {
+ error_printf("ERROR: block size of input sound data is not 0 bytes\n");
+ }
+ return 1;
+ }
+ /* A bug, since we correctly skip the offset earlier in the code.
+ if (pcm_aiff_data->blkAlgn.offset != 0) {
+ error_printf("Block offset is not 0 bytes in '%s'\n", file_name);
+ return 1;
+ } */
+
+ return 0;
+}
+
+
+static long
+make_even_number_of_bytes_in_length(long x)
+{
+ if ((x & 0x01) != 0) {
+ return x + 1;
+ }
+ return x;
+}
+
+
+/*****************************************************************************
+ *
+ * Read Audio Interchange File Format (AIFF) headers.
+ *
+ * By the time we get here the first 32 bits of the file have already been
+ * read, and we're pretty sure that we're looking at an AIFF file.
+ *
+ *****************************************************************************/
+
+static int
+parse_aiff_header(lame_global_flags * gfp, FILE * sf)
+{
+ long chunkSize = 0, subSize = 0, typeID = 0, dataType = IFF_ID_NONE;
+ IFF_AIFF aiff_info;
+ int seen_comm_chunk = 0, seen_ssnd_chunk = 0;
+ long pcm_data_pos = -1;
+
+ memset(&aiff_info, 0, sizeof(aiff_info));
+ chunkSize = Read32BitsHighLow(sf);
+
+ typeID = Read32BitsHighLow(sf);
+ if ((typeID != IFF_ID_AIFF) && (typeID != IFF_ID_AIFC))
+ return -1;
+
+ while (chunkSize > 0) {
+ long ckSize;
+ int type = Read32BitsHighLow(sf);
+ chunkSize -= 4;
+
+ /* DEBUGF(
+ "found chunk type %08x '%4.4s'\n", type, (char*)&type); */
+
+ /* don't use a switch here to make it easier to use 'break' for SSND */
+ if (type == IFF_ID_COMM) {
+ seen_comm_chunk = seen_ssnd_chunk + 1;
+ subSize = Read32BitsHighLow(sf);
+ ckSize = make_even_number_of_bytes_in_length(subSize);
+ chunkSize -= ckSize;
+
+ aiff_info.numChannels = Read16BitsHighLow(sf);
+ ckSize -= 2;
+ aiff_info.numSampleFrames = Read32BitsHighLow(sf);
+ ckSize -= 4;
+ aiff_info.sampleSize = Read16BitsHighLow(sf);
+ ckSize -= 2;
+ aiff_info.sampleRate = ReadIeeeExtendedHighLow(sf);
+ ckSize -= 10;
+ if (typeID == IFF_ID_AIFC) {
+ dataType = Read32BitsHighLow(sf);
+ ckSize -= 4;
+ }
+ if (fskip(sf, ckSize, SEEK_CUR) != 0)
+ return -1;
+ }
+ else if (type == IFF_ID_SSND) {
+ seen_ssnd_chunk = 1;
+ subSize = Read32BitsHighLow(sf);
+ ckSize = make_even_number_of_bytes_in_length(subSize);
+ chunkSize -= ckSize;
+
+ aiff_info.blkAlgn.offset = Read32BitsHighLow(sf);
+ ckSize -= 4;
+ aiff_info.blkAlgn.blockSize = Read32BitsHighLow(sf);
+ ckSize -= 4;
+
+ aiff_info.sampleType = IFF_ID_SSND;
+
+ if (seen_comm_chunk > 0) {
+ if (fskip(sf, (long) aiff_info.blkAlgn.offset, SEEK_CUR) != 0)
+ return -1;
+ /* We've found the audio data. Read no further! */
+ break;
+ }
+ pcm_data_pos = ftell(sf);
+ if (pcm_data_pos >= 0) {
+ pcm_data_pos += aiff_info.blkAlgn.offset;
+ }
+ if (fskip(sf, ckSize, SEEK_CUR) != 0)
+ return -1;
+ }
+ else {
+ subSize = Read32BitsHighLow(sf);
+ ckSize = make_even_number_of_bytes_in_length(subSize);
+ chunkSize -= ckSize;
+
+ if (fskip(sf, ckSize, SEEK_CUR) != 0)
+ return -1;
+ }
+ }
+ if (dataType == IFF_ID_2CLE) {
+ global. pcmswapbytes = swapbytes;
+ }
+ else if (dataType == IFF_ID_2CBE) {
+ global. pcmswapbytes = !swapbytes;
+ }
+ else if (dataType == IFF_ID_NONE) {
+ global. pcmswapbytes = !swapbytes;
+ }
+ else {
+ return -1;
+ }
+
+ /* DEBUGF("Parsed AIFF %d\n", is_aiff); */
+ if (seen_comm_chunk && (seen_ssnd_chunk > 0 || aiff_info.numSampleFrames == 0)) {
+ /* make sure the header is sane */
+ if (0 != aiff_check2(&aiff_info))
+ return 0;
+ if (-1 == lame_set_num_channels(gfp, aiff_info.numChannels)) {
+ if (silent < 10) {
+ error_printf("Unsupported number of channels: %u\n", aiff_info.numChannels);
+ }
+ return 0;
+ }
+ (void) lame_set_in_samplerate(gfp, (int) aiff_info.sampleRate);
+ (void) lame_set_num_samples(gfp, aiff_info.numSampleFrames);
+ global. pcmbitwidth = aiff_info.sampleSize;
+ global. pcm_is_unsigned_8bit = 0;
+
+ if (pcm_data_pos >= 0) {
+ if (fseek(sf, pcm_data_pos, SEEK_SET) != 0) {
+ if (silent < 10) {
+ error_printf("Can't rewind stream to audio data position\n");
+ }
+ return 0;
+ }
+ }
+
+ return 1;
+ }
+ return -1;
+}
+
+
+
+/************************************************************************
+*
+* parse_file_header
+*
+* PURPOSE: Read the header from a bytestream. Try to determine whether
+* it's a WAV file or AIFF without rewinding, since rewind
+* doesn't work on pipes and there's a good chance we're reading
+* from stdin (otherwise we'd probably be using libsndfile).
+*
+* When this function returns, the file offset will be positioned at the
+* beginning of the sound data.
+*
+************************************************************************/
+
+static int
+parse_file_header(lame_global_flags * gfp, FILE * sf)
+{
+
+ int type = Read32BitsHighLow(sf);
+ /*
+ DEBUGF(
+ "First word of input stream: %08x '%4.4s'\n", type, (char*) &type);
+ */
+ global. count_samples_carefully = 0;
+ global. pcm_is_unsigned_8bit = in_signed == 1 ? 0 : 1;
+ /*input_format = sf_raw; commented out, because it is better to fail
+ here as to encode some hundreds of input files not supported by LAME
+ If you know you have RAW PCM data, use the -r switch
+ */
+
+ if (type == WAV_ID_RIFF) {
+ /* It's probably a WAV file */
+ int const ret = parse_wave_header(gfp, sf);
+ if (ret > 0) {
+ global. count_samples_carefully = 1;
+ return sf_wave;
+ }
+ if (ret < 0) {
+ if (silent < 10) {
+ error_printf("Warning: corrupt or unsupported WAVE format\n");
+ }
+ }
+ }
+ else if (type == IFF_ID_FORM) {
+ /* It's probably an AIFF file */
+ int const ret = parse_aiff_header(gfp, sf);
+ if (ret > 0) {
+ global. count_samples_carefully = 1;
+ return sf_aiff;
+ }
+ if (ret < 0) {
+ if (silent < 10) {
+ error_printf("Warning: corrupt or unsupported AIFF format\n");
+ }
+ }
+ }
+ else {
+ if (silent < 10) {
+ error_printf("Warning: unsupported audio format\n");
+ }
+ }
+ return sf_unknown;
+}
+
+
+
+void
+CloseSndFile(sound_file_format input, FILE * musicin)
+{
+ (void) input;
+ if (fclose(musicin) != 0) {
+ if (silent < 10) {
+ error_printf("Could not close audio input file\n");
+ }
+ exit(2);
+ }
+}
+
+
+
+
+
+FILE *
+OpenSndFile(lame_global_flags * gfp, char *inPath, int *enc_delay, int *enc_padding)
+{
+ FILE *musicin;
+
+ /* set the defaults from info incase we cannot determine them from file */
+ lame_set_num_samples(gfp, MAX_U_32_NUM);
+
+
+ if (!strcmp(inPath, "-")) {
+ lame_set_stream_binary_mode(musicin = stdin); /* Read from standard input. */
+ }
+ else {
+ if ((musicin = fopen(inPath, "rb")) == NULL) {
+ if (silent < 10) {
+ error_printf("Could not find \"%s\".\n", inPath);
+ }
+ exit(1);
+ }
+ }
+
+ if (is_mpeg_file_format(input_format)) {
+#ifdef AMIGA_MPEGA
+ if (-1 == lame_decode_initfile(inPath, &mp3input_data)) {
+ if (silent < 10) {
+ error_printf("Error reading headers in mp3 input file %s.\n", inPath);
+ }
+ exit(1);
+ }
+#endif
+#ifdef HAVE_MPGLIB
+ if (-1 == lame_decode_initfile(musicin, &mp3input_data, enc_delay, enc_padding)) {
+ if (silent < 10) {
+ error_printf("Error reading headers in mp3 input file %s.\n", inPath);
+ }
+ exit(1);
+ }
+#endif
+ if (-1 == lame_set_num_channels(gfp, mp3input_data.stereo)) {
+ if (silent < 10) {
+ error_printf("Unsupported number of channels: %ud\n", mp3input_data.stereo);
+ }
+ exit(1);
+ }
+ (void) lame_set_in_samplerate(gfp, mp3input_data.samplerate);
+ (void) lame_set_num_samples(gfp, mp3input_data.nsamp);
+ }
+ else if (input_format == sf_ogg) {
+ if (silent < 10) {
+ error_printf("sorry, vorbis support in LAME is deprecated.\n");
+ }
+ exit(1);
+ }
+ else if (input_format == sf_raw) {
+ /* assume raw PCM */
+ if (silent < 10) {
+ console_printf("Assuming raw pcm input file");
+ if (swapbytes)
+ console_printf(" : Forcing byte-swapping\n");
+ else
+ console_printf("\n");
+ }
+ global. pcmswapbytes = swapbytes;
+ }
+ else {
+ input_format = parse_file_header(gfp, musicin);
+ }
+ if (input_format == sf_unknown) {
+ exit(1);
+ }
+
+
+ if (lame_get_num_samples(gfp) == MAX_U_32_NUM && musicin != stdin) {
+
+ double flen = lame_get_file_size(inPath); /* try to figure out num_samples */
+ if (flen >= 0) {
+ /* try file size, assume 2 bytes per sample */
+ if (is_mpeg_file_format(input_format)) {
+ if (mp3input_data.bitrate > 0) {
+ double totalseconds = (flen * 8.0 / (1000.0 * mp3input_data.bitrate));
+ unsigned long tmp_num_samples =
+ (unsigned long) (totalseconds * lame_get_in_samplerate(gfp));
+
+ (void) lame_set_num_samples(gfp, tmp_num_samples);
+ mp3input_data.nsamp = tmp_num_samples;
+ }
+ }
+ else {
+ (void) lame_set_num_samples(gfp,
+ (unsigned long) (flen /
+ (2 * lame_get_num_channels(gfp))));
+ }
+ }
+ }
+ return musicin;
+}
+#endif /* defined(LIBSNDFILE) */
+
+
+
+
+
+#if defined(HAVE_MPGLIB)
+static int
+check_aid(const unsigned char *header)
+{
+ return 0 == memcmp(header, "AiD\1", 4);
+}
+
+/*
+ * Please check this and don't kill me if there's a bug
+ * This is a (nearly?) complete header analysis for a MPEG-1/2/2.5 Layer I, II or III
+ * data stream
+ */
+
+static int
+is_syncword_mp123(const void *const headerptr)
+{
+ const unsigned char *const p = headerptr;
+ static const char abl2[16] = { 0, 7, 7, 7, 0, 7, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8 };
+
+ if ((p[0] & 0xFF) != 0xFF)
+ return 0; /* first 8 bits must be '1' */
+ if ((p[1] & 0xE0) != 0xE0)
+ return 0; /* next 3 bits are also */
+ if ((p[1] & 0x18) == 0x08)
+ return 0; /* no MPEG-1, -2 or -2.5 */
+ switch (p[1] & 0x06) {
+ default:
+ case 0x00: /* illegal Layer */
+ return 0;
+
+ case 0x02: /* Layer3 */
+ if (input_format != sf_mp3 && input_format != sf_mp123) {
+ return 0;
+ }
+ input_format = sf_mp3;
+ break;
+
+ case 0x04: /* Layer2 */
+ if (input_format != sf_mp2 && input_format != sf_mp123) {
+ return 0;
+ }
+ input_format = sf_mp2;
+ break;
+
+ case 0x06: /* Layer1 */
+ if (input_format != sf_mp1 && input_format != sf_mp123) {
+ return 0;
+ }
+ input_format = sf_mp1;
+ break;
+ }
+ if ((p[1] & 0x06) == 0x00)
+ return 0; /* no Layer I, II and III */
+ if ((p[2] & 0xF0) == 0xF0)
+ return 0; /* bad bitrate */
+ if ((p[2] & 0x0C) == 0x0C)
+ return 0; /* no sample frequency with (32,44.1,48)/(1,2,4) */
+ if ((p[1] & 0x18) == 0x18 && (p[1] & 0x06) == 0x04 && abl2[p[2] >> 4] & (1 << (p[3] >> 6)))
+ return 0;
+ if ((p[3] & 3) == 2)
+ return 0; /* reserved enphasis mode */
+ return 1;
+}
+
+int
+lame_decode_initfile(FILE * fd, mp3data_struct * mp3data, int *enc_delay, int *enc_padding)
+{
+ /* VBRTAGDATA pTagData; */
+ /* int xing_header,len2,num_frames; */
+ unsigned char buf[100];
+ int ret;
+ size_t len;
+ int aid_header;
+ short int pcm_l[1152], pcm_r[1152];
+ int freeformat = 0;
+
+ memset(mp3data, 0, sizeof(mp3data_struct));
+ if (global.hip) {
+ hip_decode_exit(global.hip);
+ }
+ global.hip = hip_decode_init();
+
+ len = 4;
+ if (fread(buf, 1, len, fd) != len)
+ return -1; /* failed */
+ if (buf[0] == 'I' && buf[1] == 'D' && buf[2] == '3') {
+ if (silent < 10) {
+ console_printf("ID3v2 found. "
+ "Be aware that the ID3 tag is currently lost when transcoding.\n");
+ }
+ len = 6;
+ if (fread(&buf, 1, len, fd) != len)
+ return -1; /* failed */
+ buf[2] &= 127;
+ buf[3] &= 127;
+ buf[4] &= 127;
+ buf[5] &= 127;
+ len = (((((buf[2] << 7) + buf[3]) << 7) + buf[4]) << 7) + buf[5];
+ fskip(fd, len, SEEK_CUR);
+ len = 4;
+ if (fread(&buf, 1, len, fd) != len)
+ return -1; /* failed */
+ }
+ aid_header = check_aid(buf);
+ if (aid_header) {
+ if (fread(&buf, 1, 2, fd) != 2)
+ return -1; /* failed */
+ aid_header = (unsigned char) buf[0] + 256 * (unsigned char) buf[1];
+ if (silent < 10) {
+ console_printf("Album ID found. length=%i \n", aid_header);
+ }
+ /* skip rest of AID, except for 6 bytes we have already read */
+ fskip(fd, aid_header - 6, SEEK_CUR);
+
+ /* read 4 more bytes to set up buffer for MP3 header check */
+ if (fread(&buf, 1, len, fd) != len)
+ return -1; /* failed */
+ }
+ len = 4;
+ while (!is_syncword_mp123(buf)) {
+ unsigned int i;
+ for (i = 0; i < len - 1; i++)
+ buf[i] = buf[i + 1];
+ if (fread(buf + len - 1, 1, 1, fd) != 1)
+ return -1; /* failed */
+ }
+
+ if ((buf[2] & 0xf0) == 0) {
+ if (silent < 10) {
+ console_printf("Input file is freeformat.\n");
+ }
+ freeformat = 1;
+ }
+ /* now parse the current buffer looking for MP3 headers. */
+ /* (as of 11/00: mpglib modified so that for the first frame where */
+ /* headers are parsed, no data will be decoded. */
+ /* However, for freeformat, we need to decode an entire frame, */
+ /* so mp3data->bitrate will be 0 until we have decoded the first */
+ /* frame. Cannot decode first frame here because we are not */
+ /* yet prepared to handle the output. */
+ ret = hip_decode1_headersB(global.hip, buf, len, pcm_l, pcm_r, mp3data, enc_delay, enc_padding);
+ if (-1 == ret)
+ return -1;
+
+ /* repeat until we decode a valid mp3 header. */
+ while (!mp3data->header_parsed) {
+ len = fread(buf, 1, sizeof(buf), fd);
+ if (len != sizeof(buf))
+ return -1;
+ ret = hip_decode1_headersB(global.hip, buf, len, pcm_l, pcm_r, mp3data, enc_delay, enc_padding);
+ if (-1 == ret)
+ return -1;
+ }
+
+ if (mp3data->bitrate == 0 && !freeformat) {
+ if (silent < 10) {
+ error_printf("fail to sync...\n");
+ }
+ return lame_decode_initfile(fd, mp3data, enc_delay, enc_padding);
+ }
+
+ if (mp3data->totalframes > 0) {
+ /* mpglib found a Xing VBR header and computed nsamp & totalframes */
+ }
+ else {
+ /* set as unknown. Later, we will take a guess based on file size
+ * ant bitrate */
+ mp3data->nsamp = MAX_U_32_NUM;
+ }
+
+
+ /*
+ report_printf("ret = %i NEED_MORE=%i \n",ret,MP3_NEED_MORE);
+ report_printf("stereo = %i \n",mp.fr.stereo);
+ report_printf("samp = %i \n",freqs[mp.fr.sampling_frequency]);
+ report_printf("framesize = %i \n",framesize);
+ report_printf("bitrate = %i \n",mp3data->bitrate);
+ report_printf("num frames = %ui \n",num_frames);
+ report_printf("num samp = %ui \n",mp3data->nsamp);
+ report_printf("mode = %i \n",mp.fr.mode);
+ */
+
+ return 0;
+}
+
+/*
+For lame_decode_fromfile: return code
+ -1 error
+ n number of samples output. either 576 or 1152 depending on MP3 file.
+
+
+For lame_decode1_headers(): return code
+ -1 error
+ 0 ok, but need more data before outputing any samples
+ n number of samples output. either 576 or 1152 depending on MP3 file.
+*/
+int
+lame_decode_fromfile(FILE * fd, short pcm_l[], short pcm_r[], mp3data_struct * mp3data)
+{
+ int ret = 0;
+ size_t len = 0;
+ unsigned char buf[1024];
+
+ /* first see if we still have data buffered in the decoder: */
+ ret = hip_decode1_headers(global.hip, buf, len, pcm_l, pcm_r, mp3data);
+ if (ret != 0)
+ return ret;
+
+
+ /* read until we get a valid output frame */
+ while (1) {
+ len = fread(buf, 1, 1024, fd);
+ if (len == 0) {
+ /* we are done reading the file, but check for buffered data */
+ ret = hip_decode1_headers(global.hip, buf, len, pcm_l, pcm_r, mp3data);
+ if (ret <= 0) {
+ hip_decode_exit(global.hip); /* release mp3decoder memory */
+ global.hip = 0;
+ return -1; /* done with file */
+ }
+ break;
+ }
+
+ ret = hip_decode1_headers(global.hip, buf, len, pcm_l, pcm_r, mp3data);
+ if (ret == -1) {
+ hip_decode_exit(global.hip); /* release mp3decoder memory */
+ global.hip = 0;
+ return -1;
+ }
+ if (ret > 0)
+ break;
+ }
+ return ret;
+}
+#endif /* defined(HAVE_MPGLIB) */
+
+
+int
+is_mpeg_file_format(int input_file_format)
+{
+ switch (input_file_format) {
+ case sf_mp1:
+ return 1;
+ case sf_mp2:
+ return 2;
+ case sf_mp3:
+ return 3;
+ case sf_mp123:
+ return -1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+/* end of get_audio.c */
diff --git a/lib/liblame/frontend/get_audio.h b/lib/liblame/frontend/get_audio.h
new file mode 100644
index 0000000000..edc1764f8d
--- /dev/null
+++ b/lib/liblame/frontend/get_audio.h
@@ -0,0 +1,108 @@
+/*
+ * Get Audio routines include file
+ *
+ * Copyright (c) 1999 Albert L Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef LAME_GET_AUDIO_H
+#define LAME_GET_AUDIO_H
+#include "lame.h"
+#include <stdio.h>
+
+typedef enum sound_file_format_e {
+ sf_unknown,
+ sf_raw,
+ sf_wave,
+ sf_aiff,
+ sf_mp1, /* MPEG Layer 1, aka mpg */
+ sf_mp2, /* MPEG Layer 2 */
+ sf_mp3, /* MPEG Layer 3 */
+ sf_mp123, /* MPEG Layer 1,2 or 3; whatever .mp3, .mp2, .mp1 or .mpg contains */
+ sf_ogg
+} sound_file_format;
+
+
+int is_mpeg_file_format( int input_format );
+
+FILE *init_outfile(char *outPath, int decode);
+void init_infile(lame_global_flags *, char *inPath, int *enc_delay, int *enc_padding);
+void close_infile(void);
+int get_audio(lame_global_flags * const gfp, int buffer[2][1152]);
+int get_audio16(lame_global_flags * const gfp, short buffer[2][1152]);
+int WriteWaveHeader(FILE * const fp, const int pcmbytes,
+ const int freq, const int channels, const int bits);
+
+
+
+/* the simple lame decoder */
+/* After calling lame_init(), lame_init_params() and
+ * init_infile(), call this routine to read the input MP3 file
+ * and output .wav data to the specified file pointer
+ * lame_decoder will ignore the first 528 samples, since these samples
+ * represent the mpglib decoding delay (and are all 0).
+ *skip = number of additional
+ * samples to skip, to (for example) compensate for the encoder delay,
+ * only used when decoding mp3
+*/
+int lame_decoder(lame_global_flags * gfp, FILE * outf, int skip, char *inPath, char *outPath,
+ int *enc_delay, int *enc_padding);
+
+
+
+void SwapBytesInWords(short *loc, int words);
+
+
+
+#ifdef LIBSNDFILE
+
+#include "sndfile.h"
+
+
+#else
+/*****************************************************************
+ * LAME/ISO built in audio file I/O routines
+ *******************************************************************/
+#include "portableio.h"
+
+
+typedef struct blockAlign_struct {
+ unsigned long offset;
+ unsigned long blockSize;
+} blockAlign;
+
+typedef struct IFF_AIFF_struct {
+ short numChannels;
+ unsigned long numSampleFrames;
+ short sampleSize;
+ double sampleRate;
+ unsigned long sampleType;
+ blockAlign blkAlgn;
+} IFF_AIFF;
+
+extern int aiff_read_headers(FILE *, IFF_AIFF *);
+extern int aiff_seek_to_sound_data(FILE *);
+extern int aiff_write_headers(FILE *, IFF_AIFF *);
+extern int parse_wavheader(void);
+extern int parse_aiff(const char fn[]);
+extern void aiff_check(const char *, IFF_AIFF *, int *);
+
+
+
+#endif /* ifdef LIBSNDFILE */
+#endif /* ifndef LAME_GET_AUDIO_H */
diff --git a/lib/liblame/frontend/gpkplotting.c b/lib/liblame/frontend/gpkplotting.c
new file mode 100644
index 0000000000..034d0a090e
--- /dev/null
+++ b/lib/liblame/frontend/gpkplotting.c
@@ -0,0 +1,331 @@
+/*
+ * GTK plotting routines source file
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: gpkplotting.c,v 1.11 2007/07/24 17:46:08 bouvigne Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "gpkplotting.h"
+
+#ifdef STDC_HEADERS
+# include <string.h>
+#else
+# ifndef HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+char *strchr(), *strrchr();
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# define memmove(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+static gint num_plotwindows = 0;
+static gint max_plotwindows = 10;
+static GdkPixmap *pixmaps[10];
+static GtkWidget *pixmapboxes[10];
+
+
+
+
+/* compute a gdkcolor */
+void
+setcolor(GtkWidget * widget, GdkColor * color, gint red, gint green, gint blue)
+{
+
+ /* colors in GdkColor are taken from 0 to 65535, not 0 to 255. */
+ color->red = red * (65535 / 255);
+ color->green = green * (65535 / 255);
+ color->blue = blue * (65535 / 255);
+ color->pixel = (gulong) (color->red * 65536 + color->green * 256 + color->blue);
+ /* find closest in colormap, if needed */
+ gdk_color_alloc(gtk_widget_get_colormap(widget), color);
+}
+
+
+void
+gpk_redraw(GdkPixmap * pixmap, GtkWidget * pixmapbox)
+{
+ /* redraw the entire pixmap */
+ gdk_draw_pixmap(pixmapbox->window,
+ pixmapbox->style->fg_gc[GTK_WIDGET_STATE(pixmapbox)],
+ pixmap, 0, 0, 0, 0, pixmapbox->allocation.width, pixmapbox->allocation.height);
+}
+
+
+static GdkPixmap **
+findpixmap(GtkWidget * widget)
+{
+ int i;
+ for (i = 0; i < num_plotwindows && widget != pixmapboxes[i]; i++);
+ if (i >= num_plotwindows) {
+ g_print("findpixmap(): bad argument widget \n");
+ return NULL;
+ }
+ return &pixmaps[i];
+}
+
+void
+gpk_graph_draw(GtkWidget * widget, /* plot on this widged */
+ int n, /* number of data points */
+ gdouble * xcord, gdouble * ycord, /* data */
+ gdouble xmn, gdouble ymn, /* coordinates of corners */
+ gdouble xmx, gdouble ymx, int clear, /* clear old plot first */
+ char *title, /* add a title (only if clear=1) */
+ GdkColor * color)
+{
+ GdkPixmap **ppixmap;
+ GdkPoint *points;
+ int i;
+ gint16 width, height;
+ GdkFont *fixed_font;
+ GdkGC *gc;
+
+ gc = gdk_gc_new(widget->window);
+ gdk_gc_set_foreground(gc, color);
+
+
+
+ if ((ppixmap = findpixmap(widget))) {
+ width = widget->allocation.width;
+ height = widget->allocation.height;
+
+
+ if (clear) {
+ /* white background */
+ gdk_draw_rectangle(*ppixmap, widget->style->white_gc, TRUE, 0, 0, width, height);
+ /* title */
+#ifdef _WIN32
+ fixed_font = gdk_font_load("-misc-fixed-large-r-*-*-*-100-*-*-*-*-*-*");
+#else
+ fixed_font = gdk_font_load("-misc-fixed-medium-r-*-*-*-100-*-*-*-*-iso8859-1");
+#endif
+
+ gdk_draw_text(*ppixmap, fixed_font,
+ widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ 0, 10, title, strlen(title));
+ }
+
+
+ points = g_malloc(n * sizeof(GdkPoint));
+ for (i = 0; i < n; i++) {
+ points[i].x = .5 + ((xcord[i] - xmn) * (width - 1) / (xmx - xmn));
+ points[i].y = .5 + ((ycord[i] - ymx) * (height - 1) / (ymn - ymx));
+ }
+ gdk_draw_lines(*ppixmap, gc, points, n);
+ g_free(points);
+ gpk_redraw(*ppixmap, widget);
+ }
+ gdk_gc_destroy(gc);
+}
+
+
+
+void
+gpk_rectangle_draw(GtkWidget * widget, /* plot on this widged */
+ gdouble * xcord, gdouble * ycord, /* corners */
+ gdouble xmn, gdouble ymn, /* coordinates of corners */
+ gdouble xmx, gdouble ymx, GdkColor * color)
+{
+ GdkPixmap **ppixmap;
+ GdkPoint points[2];
+ int i;
+ gint16 width, height;
+ GdkGC *gc;
+
+
+ gc = gdk_gc_new(widget->window);
+ gdk_gc_set_foreground(gc, color);
+
+
+ if ((ppixmap = findpixmap(widget))) {
+ width = widget->allocation.width;
+ height = widget->allocation.height;
+
+
+ for (i = 0; i < 2; i++) {
+ points[i].x = .5 + ((xcord[i] - xmn) * (width - 1) / (xmx - xmn));
+ points[i].y = .5 + ((ycord[i] - ymx) * (height - 1) / (ymn - ymx));
+ }
+ width = points[1].x - points[0].x + 1;
+ height = points[1].y - points[0].y + 1;
+ gdk_draw_rectangle(*ppixmap, gc, TRUE, points[0].x, points[0].y, width, height);
+ gpk_redraw(*ppixmap, widget);
+ }
+ gdk_gc_destroy(gc);
+}
+
+
+
+void
+gpk_bargraph_draw(GtkWidget * widget, /* plot on this widged */
+ int n, /* number of data points */
+ gdouble * xcord, gdouble * ycord, /* data */
+ gdouble xmn, gdouble ymn, /* coordinates of corners */
+ gdouble xmx, gdouble ymx, int clear, /* clear old plot first */
+ char *title, /* add a title (only if clear=1) */
+ int barwidth, /* bar width. 0=compute based on window size */
+ GdkColor * color)
+{
+ GdkPixmap **ppixmap;
+ GdkPoint points[2];
+ int i;
+ gint16 width, height, x, y, barheight;
+ GdkFont *fixed_font;
+ GdkGC *gc;
+ int titleSplit;
+
+
+ gc = gdk_gc_new(widget->window);
+ gdk_gc_set_foreground(gc, color);
+
+
+ if ((ppixmap = findpixmap(widget))) {
+ width = widget->allocation.width;
+ height = widget->allocation.height;
+
+
+ if (clear) {
+ /* white background */
+ gdk_draw_rectangle(*ppixmap, widget->style->white_gc, TRUE, 0, 0, width, height);
+ /* title */
+#ifdef _WIN32
+ fixed_font = gdk_font_load("-misc-fixed-large-r-*-*-*-100-*-*-*-*-*-*");
+#else
+ fixed_font = gdk_font_load("-misc-fixed-medium-r-*-*-*-100-*-*-*-*-iso8859-1");
+#endif
+
+ titleSplit = strcspn(title, "\n");
+
+ if (titleSplit && (titleSplit != strlen(title))) {
+ gdk_draw_text(*ppixmap, fixed_font,
+ widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ 0, 10, title, titleSplit);
+
+ gdk_draw_text(*ppixmap, fixed_font,
+ widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ 0, 22, title + titleSplit + 1, (strlen(title) - titleSplit) - 1);
+
+
+ }
+ else {
+ gdk_draw_text(*ppixmap, fixed_font,
+ widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ 0, 10, title, strlen(title));
+ }
+ }
+
+
+ for (i = 0; i < n; i++) {
+ points[1].x = .5 + ((xcord[i] - xmn) * (width - 1) / (xmx - xmn));
+ points[1].y = .5 + ((ycord[i] - ymx) * (height - 1) / (ymn - ymx));
+ points[0].x = points[1].x;
+ points[0].y = height - 1;
+
+ x = .5 + ((xcord[i] - xmn) * (width - 1) / (xmx - xmn));
+ y = .5 + ((ycord[i] - ymx) * (height - 1) / (ymn - ymx));
+ if (!barwidth)
+ barwidth = (width / (n + 1)) - 1;
+ barwidth = barwidth > 5 ? 5 : barwidth;
+ barwidth = barwidth < 1 ? 1 : barwidth;
+ barheight = height - 1 - y;
+ /* gdk_draw_lines(*ppixmap,gc,points,2); */
+ gdk_draw_rectangle(*ppixmap, gc, TRUE, x, y, barwidth, barheight);
+
+ }
+ gpk_redraw(*ppixmap, widget);
+ }
+ gdk_gc_destroy(gc);
+}
+
+
+
+
+
+/* Create a new backing pixmap of the appropriate size */
+static gint
+configure_event(GtkWidget * widget, GdkEventConfigure * event, gpointer data)
+{
+ GdkPixmap **ppixmap;
+ if ((ppixmap = findpixmap(widget))) {
+ if (*ppixmap)
+ gdk_pixmap_unref(*ppixmap);
+ *ppixmap = gdk_pixmap_new(widget->window,
+ widget->allocation.width, widget->allocation.height, -1);
+ gdk_draw_rectangle(*ppixmap,
+ widget->style->white_gc,
+ TRUE, 0, 0, widget->allocation.width, widget->allocation.height);
+ }
+ return TRUE;
+}
+
+
+
+/* Redraw the screen from the backing pixmap */
+static gint
+expose_event(GtkWidget * widget, GdkEventExpose * event, gpointer data)
+{
+ GdkPixmap **ppixmap;
+ if ((ppixmap = findpixmap(widget))) {
+ gdk_draw_pixmap(widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ *ppixmap,
+ event->area.x, event->area.y,
+ event->area.x, event->area.y, event->area.width, event->area.height);
+ }
+
+ return FALSE;
+}
+
+
+
+
+
+GtkWidget *
+gpk_plot_new(int width, int height)
+{
+ GtkWidget *pixmapbox;
+
+ pixmapbox = gtk_drawing_area_new();
+ gtk_drawing_area_size(GTK_DRAWING_AREA(pixmapbox), width, height);
+ gtk_signal_connect(GTK_OBJECT(pixmapbox), "expose_event", (GtkSignalFunc) expose_event, NULL);
+ gtk_signal_connect(GTK_OBJECT(pixmapbox), "configure_event",
+ (GtkSignalFunc) configure_event, NULL);
+ gtk_widget_set_events(pixmapbox, GDK_EXPOSURE_MASK);
+
+ if (num_plotwindows < max_plotwindows) {
+ pixmapboxes[num_plotwindows] = pixmapbox;
+ pixmaps[num_plotwindows] = NULL;
+ num_plotwindows++;
+ }
+ else {
+ g_print("gtk_plotarea_new(): exceeded maximum of 10 plotarea windows\n");
+ }
+
+ return pixmapbox;
+}
diff --git a/lib/liblame/frontend/gpkplotting.h b/lib/liblame/frontend/gpkplotting.h
new file mode 100644
index 0000000000..2c69c8c65d
--- /dev/null
+++ b/lib/liblame/frontend/gpkplotting.h
@@ -0,0 +1,51 @@
+/*
+ * GTK plotting routines include file
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_GPKPLOTTING_H
+#define LAME_GPKPLOTTING_H
+
+#include <gtk/gtk.h>
+
+/* allocate a graphing widget */
+GtkWidget *gpk_plot_new(int width, int height);
+
+/* graph a function in the graphing widged */
+void gpk_graph_draw(GtkWidget * widget,
+ int n, gdouble * xcord, gdouble * ycord,
+ gdouble xmn, gdouble ymn, gdouble xmx, gdouble ymx,
+ int clear, char *title, GdkColor * color);
+
+/* draw a rectangle in the graphing widget */
+void gpk_rectangle_draw(GtkWidget * widget, /* plot on this widged */
+ gdouble xcord[2], gdouble ycord[2], /* corners */
+ gdouble xmn, gdouble ymn, /* coordinates of corners */
+ gdouble xmx, gdouble ymx, GdkColor * color); /* color to use */
+
+/* make a bar graph in the graphing widged */
+void gpk_bargraph_draw(GtkWidget * widget,
+ int n, gdouble * xcord, gdouble * ycord,
+ gdouble xmn, gdouble ymn, gdouble xmx, gdouble ymx,
+ int clear, char *title, int bwidth, GdkColor * color);
+
+/* set forground color */
+void setcolor(GtkWidget * widget, GdkColor * color, int red, int green, int blue);
+
+#endif
diff --git a/lib/liblame/frontend/gtkanal.c b/lib/liblame/frontend/gtkanal.c
new file mode 100644
index 0000000000..02f3bbe3bb
--- /dev/null
+++ b/lib/liblame/frontend/gtkanal.c
@@ -0,0 +1,1639 @@
+/*
+ * GTK plotting routines source file
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: gtkanal.c,v 1.41.8.3 2009/01/18 15:44:28 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include "main.h"
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "lame-analysis.h"
+#include "get_audio.h"
+#include "gtkanal.h"
+#include "gpkplotting.h"
+#include "lame_global_flags.h"
+
+/* this file should be removed. The few data items accessed in 'gfc'
+ should be made accessable by writing a lame_set_variable() function */
+#include "util.h"
+
+#include "console.h"
+
+
+#ifdef _WIN32
+# include <windows.h>
+# define msleep(t) Sleep(t)
+#else
+# include <unistd.h>
+# define msleep(t) usleep((t) * 1000)
+#endif
+
+
+
+
+/*! Stringify \a x. */
+#define STR(x) #x
+/*! Stringify \a x, perform macro expansion. */
+#define XSTR(x) STR(x)
+
+#define MP3X_MAJOR_VERSION 0 /* Major version number */
+#define MP3X_MINOR_VERSION 82 /* Minor version number */
+#define MP3X_ALPHA_VERSION 0 /* Set number if this is an alpha version, otherwise zero */
+#define MP3X_BETA_VERSION 0 /* Set number if this is a beta version, otherwise zero */
+
+
+plotting_data *pinfo;
+plotting_data *pplot;
+plotting_data Pinfo[NUMPINFO];
+
+
+/* global variables for the state of the system */
+static gint idle_keepgoing; /* processing of frames is ON */
+static gint idle_count_max; /* number of frames to process before plotting */
+static gint idle_count; /* pause & plot when idle_count=idel_count_max */
+static gint idle_end = 0; /* process all frames, stop at last frame */
+static gint idle_back = 0; /* set when we are displaying the old data */
+static int mp3done = 0; /* last frame has been read */
+static GtkWidget *frameprogress; /* progress bar */
+static GtkWidget *framecounter; /* progress counter */
+
+static int subblock_draw[3] = { 1, 1, 1 };
+
+/* main window */
+GtkWidget *window;
+/* Backing pixmap for drawing areas */
+GtkWidget *pcmbox; /* PCM data plotted here */
+GtkWidget *winbox; /* mpg123 synthesis data plotted here */
+GtkWidget *enerbox[2]; /* spectrum, gr=0,1 plotted here */
+GtkWidget *mdctbox[2]; /* mdct coefficients gr=0,1 plotted here */
+GtkWidget *sfbbox[2]; /* scalefactors gr=0,1 plotted here */
+GtkWidget *headerbox; /* mpg123 header info shown here */
+
+
+struct gtkinfostruct {
+ int filetype; /* input file type 0=WAV, 1=MP3 */
+ int msflag; /* toggle between L&R vs M&S PCM data display */
+ int chflag; /* toggle between L & R channels */
+ int kbflag; /* toggle between wave # and barks */
+ int flag123; /* show mpg123 frame info, OR ISO encoder frame info */
+ double avebits; /* running average bits per frame */
+ int approxbits; /* (approx) bits per frame */
+ int maxbits; /* max bits per frame used so far */
+ int totemph; /* total of frames with de-emphasis */
+ int totms; /* total frames with ms_stereo */
+ int totis; /* total frames with i_stereo */
+ int totshort; /* total granules with short blocks */
+ int totmix; /* total granules with mixed blocks */
+ int totpreflag; /* total granules with preflag */
+ int pupdate; /* plot while processing, or only when needed */
+ int sfblines; /* plot scalefactor bands in MDCT plot */
+ int difference; /* plot original - decoded instead of orig vs. decoded */
+ int totalframes;
+} gtkinfo;
+
+
+static lame_global_flags *gfp;
+lame_internal_flags *gfc;
+hip_t hip;
+
+/**********************************************************************
+ * read one frame and encode it
+ **********************************************************************/
+int
+gtkmakeframe(void)
+{
+ int iread = 0;
+ static int init = 0;
+ static int mpglag;
+ static short int Buffer[2][1152];
+ short int mpg123pcm[2][1152];
+ int ch, j;
+ int mp3count = 0;
+ int mp3out = 0;
+ int channels_out;
+ unsigned char mp3buffer[LAME_MAXMP3BUFFER];
+ static int frameNum = 0;
+ int framesize = lame_get_framesize(gfp);
+
+ channels_out = (lame_get_mode(gfp) == MONO) ? 1 : 2;
+
+ pinfo->frameNum = frameNum;
+ pinfo->sampfreq = lame_get_out_samplerate(gfp);
+ pinfo->framesize = framesize;
+ pinfo->stereo = channels_out;
+
+ /* If the analsys code is enabled, lame will writes data into gfc->pinfo,
+ * and mpg123 will write data into pinfo. Set these so
+ * the libraries put this data in the right place: */
+ gfc->pinfo = pinfo;
+ hip_set_pinfo(hip, pinfo);
+
+ if (is_mpeg_file_format(input_format)) {
+ iread = get_audio16(gfp, Buffer);
+
+
+ /* add a delay of framesize-DECDELAY, which will make the total delay
+ * exactly one frame, so we can sync MP3 output with WAV input */
+ for (ch = 0; ch < channels_out; ch++) {
+ for (j = 0; j < framesize - DECDELAY; j++)
+ pinfo->pcmdata2[ch][j] = pinfo->pcmdata2[ch][j + framesize];
+ for (j = 0; j < framesize; j++) /*rescale from int to short int */
+ pinfo->pcmdata2[ch][j + framesize - DECDELAY] = Buffer[ch][j];
+ }
+
+ pinfo->frameNum123 = frameNum - 1;
+ ++frameNum;
+
+ }
+ else {
+
+ /* feed data to encoder until encoder produces some output */
+ while (lame_get_frameNum(gfp) == pinfo->frameNum) {
+
+ if (!init) {
+ init = 1;
+ mpglag = 1;
+ if (hip) {
+ hip_decode_exit(hip);
+ }
+ hip = hip_decode_init();
+ hip_set_pinfo(hip, pinfo);
+ }
+
+ iread = get_audio16(gfp, Buffer);
+ if (iread > framesize) {
+ /* NOTE: frame analyzer requires that we encode one frame
+ * for each pass through this loop. If lame_encode_buffer()
+ * is feed data too quickly, it will sometimes encode multiple frames
+ * breaking this loop.
+ */
+ error_printf("Warning: get_audio is returning too much data.\n");
+ }
+ if (iread <= 0)
+ break; /* eof */
+
+ mp3count = lame_encode_buffer(gfp, Buffer[0], Buffer[1], iread,
+ mp3buffer, sizeof(mp3buffer));
+
+ assert(!(mp3count > 0 && lame_get_frameNum(gfp) == pinfo->frameNum));
+ /* not possible to produce mp3 data without encoding at least
+ * one frame of data which would increment frameNum */
+ }
+ frameNum = lame_get_frameNum(gfp); /* use the internal MP3 frame counter */
+
+
+ /* decode one frame of output */
+ mp3out = hip_decode1(hip, mp3buffer, mp3count, mpg123pcm[0], mpg123pcm[1]); /* re-synthesis to pcm */
+ /* mp3out = 0: need more data to decode */
+ /* mp3out = -1: error. Lets assume 0 pcm output */
+ /* mp3out = number of samples output */
+ if (mp3out > 0)
+ assert(mp3out == pinfo->framesize);
+ if (mp3out != 0) {
+ /* decoded output is for frame pinfo->frameNum123
+ * add a delay of framesize-DECDELAY, which will make the total delay
+ * exactly one frame */
+ pinfo->frameNum123 = pinfo->frameNum - mpglag;
+ for (ch = 0; ch < pinfo->stereo; ch++) {
+ for (j = 0; j < pinfo->framesize - DECDELAY; j++)
+ pinfo->pcmdata2[ch][j] = pinfo->pcmdata2[ch][j + pinfo->framesize];
+ for (j = 0; j < pinfo->framesize; j++) {
+ pinfo->pcmdata2[ch][j + pinfo->framesize - DECDELAY] =
+ (mp3out == -1) ? 0 : mpg123pcm[ch][j];
+ }
+ }
+ }
+ else {
+ if (mpglag == MAXMPGLAG) {
+ error_printf("READ_AHEAD set too low - not enough frame buffering.\n"
+ "MP3x display of input and output PCM data out of sync.\n");
+ error_flush();
+ }
+ else
+ mpglag++;
+ pinfo->frameNum123 = -1; /* no frame output */
+ }
+ }
+ return iread;
+}
+
+
+void
+plot_frame(void)
+{
+ int i, j, n, ch, gr;
+ gdouble *xcord, *ycord;
+ gdouble xmx, xmn, ymx, ymn;
+ double *data, *data2, *data3;
+ char title2[80];
+ char label[80], label2[80];
+ char *title;
+ plotting_data *pplot1;
+ plotting_data *pplot2 = NULL;
+
+ double en, samp;
+ int sampindex, version = 0;
+ int barthick;
+ static int firstcall = 1;
+ static GdkColor *barcolor, *color, *grcolor[2];
+ static GdkColor yellow, gray, cyan, magenta, orange, pink, red, green, blue, black, oncolor,
+ offcolor;
+ int blocktype[2][2];
+ int headbits;
+ int mode_gr = 2;
+
+ /* find the frame where mpg123 produced output coming from input frame
+ * pinfo. i.e.: out_frame + out_frame_lag = input_frame */
+ for (i = 1; i <= MAXMPGLAG; i++) {
+ if ((pplot - i)->frameNum123 == pplot->frameNum) {
+ pplot2 = pplot - i;
+ break;
+ }
+ }
+ if (i > MAXMPGLAG) {
+ error_printf("input/output pcm syncing problem. should not happen!\n");
+ pplot2 = pplot - 1;
+ }
+
+
+ /* however, the PCM data is delayed by 528 samples in the encoder filterbanks.
+ * We added another 1152-528 delay to this so the PCM data is *exactly* one
+ * frame behind the header & MDCT information */
+ pplot1 = pplot2 + 1; /* back one frame for header info, MDCT */
+
+ /* allocate these GC's only once */
+ if (firstcall) {
+ firstcall = 0;
+ /* grcolor[0] = &magenta; */
+ grcolor[0] = &blue;
+ grcolor[1] = &green;
+ barcolor = &gray;
+
+ setcolor(headerbox, &oncolor, 255, 0, 0);
+ setcolor(headerbox, &offcolor, 175, 175, 175);
+ setcolor(pcmbox, &red, 255, 0, 0);
+ setcolor(pcmbox, &pink, 255, 0, 255);
+ setcolor(pcmbox, &magenta, 255, 0, 100);
+ setcolor(pcmbox, &orange, 255, 127, 0);
+ setcolor(pcmbox, &cyan, 0, 255, 255);
+ setcolor(pcmbox, &green, 0, 255, 0);
+ setcolor(pcmbox, &blue, 0, 0, 255);
+ setcolor(pcmbox, &black, 0, 0, 0);
+ setcolor(pcmbox, &gray, 100, 100, 100);
+ setcolor(pcmbox, &yellow, 255, 255, 0);
+
+ }
+
+ /*******************************************************************
+ * frame header info
+ *******************************************************************/
+ if (pplot1->sampfreq)
+ samp = pplot1->sampfreq;
+ else
+ samp = 1;
+ sampindex = SmpFrqIndex((long) samp, &version);
+
+ ch = gtkinfo.chflag;
+
+ headbits = 32 + ((pplot1->stereo == 2) ? 256 : 136);
+ gtkinfo.approxbits = (pplot1->bitrate * 1000 * 1152.0 / samp) - headbits;
+ sprintf(title2, "%3.1fkHz %ikbs ", samp / 1000, pplot1->bitrate);
+ gtk_text_freeze(GTK_TEXT(headerbox));
+ gtk_text_backward_delete(GTK_TEXT(headerbox), gtk_text_get_length(GTK_TEXT(headerbox)));
+ gtk_text_set_point(GTK_TEXT(headerbox), 0);
+ gtk_text_insert(GTK_TEXT(headerbox), NULL, &oncolor, NULL, title2, -1);
+ title = " mono ";
+ if (2 == pplot1->stereo)
+ title = pplot1->js ? " js " : " s ";
+ gtk_text_insert(GTK_TEXT(headerbox), NULL, &oncolor, NULL, title, -1);
+ color = pplot1->ms_stereo ? &oncolor : &offcolor;
+ gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "ms ", -1);
+ color = pplot1->i_stereo ? &oncolor : &offcolor;
+ gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "is ", -1);
+
+ color = pplot1->crc ? &oncolor : &offcolor;
+ gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "crc ", -1);
+ color = pplot1->padding ? &oncolor : &offcolor;
+ gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "pad ", -1);
+
+ color = pplot1->emph ? &oncolor : &offcolor;
+ gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "em ", -1);
+
+ sprintf(title2, "bv=%i,%i ", pplot1->big_values[0][ch], pplot1->big_values[1][ch]);
+ gtk_text_insert(GTK_TEXT(headerbox), NULL, &black, NULL, title2, -1);
+
+ color = pplot1->scfsi[ch] ? &oncolor : &offcolor;
+ sprintf(title2, "scfsi=%i ", pplot1->scfsi[ch]);
+ gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, title2, -1);
+ if (gtkinfo.filetype)
+ sprintf(title2, " mdb=%i %i/NA", pplot1->maindata, pplot1->totbits);
+ else
+ sprintf(title2, " mdb=%i %i/%i",
+ pplot1->maindata, pplot1->totbits, pplot1->totbits + pplot->resvsize);
+ gtk_text_insert(GTK_TEXT(headerbox), NULL, &oncolor, NULL, title2, -1);
+ gtk_text_thaw(GTK_TEXT(headerbox));
+
+
+
+ /*******************************************************************
+ * block type
+ *******************************************************************/
+ for (gr = 0; gr < mode_gr; gr++)
+ if (gtkinfo.flag123)
+ blocktype[gr][ch] = pplot1->mpg123blocktype[gr][ch];
+ else
+ blocktype[gr][ch] = pplot->blocktype[gr][ch];
+
+
+ /*******************************************************************
+ * draw the PCM data *
+ *******************************************************************/
+ n = 1600; /* PCM frame + FFT window: 224 + 1152 + 224 */
+ xcord = g_malloc(n * sizeof(gdouble));
+ ycord = g_malloc(n * sizeof(gdouble));
+
+
+ if (gtkinfo.msflag)
+ title = ch ? "Side Channel" : "Mid Channel";
+ else
+ title = ch ? "Right Channel" : "Left Channel";
+
+ sprintf(title2, "%s mask_ratio=%3.2f %3.2f ener_ratio=%3.2f %3.2f",
+ title,
+ pplot->ms_ratio[0], pplot->ms_ratio[1],
+ pplot->ms_ener_ratio[0], pplot->ms_ener_ratio[1]);
+
+
+ ymn = -32767;
+ ymx = 32767;
+ xmn = 0;
+ xmx = 1600 - 1;
+
+ /* 0 ... 224 draw in black, connecting to 224 pixel
+ * 1375 .. 1599 draw in black connecting to 1375 pixel
+ * 224 ... 1375 MP3 frame. draw in blue
+ */
+
+ /* draw the title */
+ gpk_graph_draw(pcmbox, 0, xcord, ycord, xmn, ymn, xmx, ymx, 1, title2, &black);
+
+
+ /* draw some hash marks dividing the frames */
+ ycord[0] = ymx * .8;
+ ycord[1] = ymn * .8;
+ for (gr = 0; gr <= 2; gr++) {
+ xcord[0] = 223.5 + gr * 576;
+ xcord[1] = 223.5 + gr * 576;
+ gpk_rectangle_draw(pcmbox, xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
+ }
+ for (gr = 0; gr < mode_gr; gr++) {
+ if (blocktype[gr][ch] == 2)
+ for (i = 1; i <= 2; i++) {
+ xcord[0] = 223.5 + gr * 576 + i * 192;
+ xcord[1] = 223.5 + gr * 576 + i * 192;
+ gpk_rectangle_draw(pcmbox, xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
+ }
+ }
+ /* bars representing FFT windows */
+ xcord[0] = 0;
+ ycord[0] = ymn + 3000;
+ xcord[1] = 1024 - 1;
+ ycord[1] = ymn + 1000;
+ gpk_rectangle_draw(pcmbox, xcord, ycord, xmn, ymn, xmx, ymx, grcolor[0]);
+ xcord[0] = 576;
+ ycord[0] = ymn + 2000;
+ xcord[1] = 576 + 1024 - 1;
+ ycord[1] = ymn;
+ gpk_rectangle_draw(pcmbox, xcord, ycord, xmn, ymn, xmx, ymx, grcolor[1]);
+
+
+ /* plot PCM data */
+ for (i = 0; i < n; i++) {
+ xcord[i] = i;
+ if (gtkinfo.msflag)
+ ycord[i] = ch ? .5 * (pplot->pcmdata[0][i] - pplot->pcmdata[1][i]) :
+ .5 * (pplot->pcmdata[0][i] + pplot->pcmdata[1][i]);
+ else
+ ycord[i] = pplot->pcmdata[ch][i];
+ }
+
+ /* skip plot if we are doing an mp3 file */
+ if (!gtkinfo.filetype) {
+ gpk_graph_draw(pcmbox, n, xcord, ycord, xmn, ymn, xmx, ymx, 0, title2, &black);
+ }
+
+
+ /*******************************************************************/
+ /* draw the PCM re-synthesis data */
+ /*******************************************************************/
+ n = 1152;
+ /*
+ sprintf(title2,"Re-synthesis mask_ratio=%3.2f %3.2f ener_ratio=%3.2f %3.2f",
+ pplot->ms_ratio[0],pplot->ms_ratio[1],
+ pplot->ms_ener_ratio[0],pplot->ms_ener_ratio[1]);
+ */
+ title = "Re-synthesis";
+ if (gtkinfo.difference)
+ title = "Re-synthesis difference (amplified 20db)";
+
+
+ ymn = -32767;
+ ymx = 32767;
+ xmn = 0;
+ xmx = 1600 - 1;
+ gpk_graph_draw(winbox, 0, xcord, ycord, xmn, ymn, xmx, ymx, 1, title, &black);
+ /* draw some hash marks dividing the frames */
+ ycord[0] = ymx * .8;
+ ycord[1] = ymn * .8;
+ for (gr = 0; gr <= 2; gr++) {
+ xcord[0] = 223.5 + gr * 576;
+ xcord[1] = 223.5 + gr * 576;
+ gpk_rectangle_draw(winbox, xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
+ }
+ for (gr = 0; gr < 2; gr++) {
+ if (blocktype[gr][ch] == 2)
+ for (i = 1; i <= 2; i++) {
+ xcord[0] = 223.5 + gr * 576 + i * 192;
+ xcord[1] = 223.5 + gr * 576 + i * 192;
+ gpk_rectangle_draw(winbox, xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
+ }
+ }
+
+ /* this piece of PCM data from previous frame */
+ n = 224;
+ for (j = 1152 - n, i = 0; i < n; i++, j++) {
+ xcord[i] = i;
+ if (gtkinfo.msflag)
+ ycord[i] = ch ? .5 * (pplot1->pcmdata2[0][j] -
+ pplot1->pcmdata2[1][j]) :
+ .5 * (pplot1->pcmdata2[0][j] + pplot1->pcmdata2[1][j]);
+ else
+ ycord[i] = pplot1->pcmdata2[ch][j];
+ }
+
+ /* this piece of PCM data from current frame */
+ n = 1152;
+ for (i = 0; i < n; i++) {
+ xcord[i + 224] = i + 224;
+ if (gtkinfo.msflag)
+ ycord[i + 224] = ch ? .5 * (pplot2->pcmdata2[0][i] - pplot2->pcmdata2[1][i]) :
+ .5 * (pplot2->pcmdata2[0][i] + pplot2->pcmdata2[1][i]);
+ else
+ ycord[i + 224] = pplot2->pcmdata2[ch][i];
+ }
+
+ n = 1152 + 224;
+ if (gtkinfo.difference) {
+ for (i = 0; i < n; i++) {
+ if (gtkinfo.msflag)
+ ycord[i] -= ch ? .5 * (pplot->pcmdata[0][i] - pplot->pcmdata[1][i]) :
+ .5 * (pplot->pcmdata[0][i] + pplot->pcmdata[1][i]);
+ else
+ ycord[i] -= pplot->pcmdata[ch][i];
+ }
+ ycord[i] *= 100;
+ }
+
+
+ gpk_graph_draw(winbox, n, xcord, ycord, xmn, ymn, xmx, ymx, 0, title, &black);
+
+
+
+
+
+ /*******************************************************************/
+ /* draw the MDCT energy spectrum */
+ /*******************************************************************/
+ for (gr = 0; gr < mode_gr; gr++) {
+ int bits, bits2;
+ char *blockname = "";
+ switch (blocktype[gr][ch]) {
+ case 0:
+ blockname = "normal";
+ break;
+ case 1:
+ blockname = "start";
+ break;
+ case 2:
+ blockname = "short";
+ break;
+ case 3:
+ blockname = "end";
+ break;
+ }
+ strcpy(label, blockname);
+ if (pplot1->mixed[gr][ch])
+ strcat(label, "(mixed)");
+
+
+
+
+ n = 576;
+ if (gtkinfo.flag123) {
+ data = pplot1->mpg123xr[gr][0];
+ data2 = pplot1->mpg123xr[gr][1];
+ }
+ else {
+ data = pplot->xr[gr][0];
+ data2 = pplot->xr[gr][1];
+ }
+
+
+ xmn = 0;
+ xmx = n - 1;
+ ymn = 0;
+ ymx = 11;
+
+ /* draw title, erase old plot */
+ if (gtkinfo.flag123) {
+ bits = pplot1->mainbits[gr][ch];
+ bits2 = pplot1->sfbits[gr][ch];
+ }
+ else {
+ bits = pplot->LAMEmainbits[gr][ch];
+ bits2 = pplot->LAMEsfbits[gr][ch];
+ }
+ sprintf(title2, "MDCT%1i(%s) bits=%i/%i ", gr, label, bits, bits2);
+ gpk_bargraph_draw(mdctbox[gr], 0, xcord, ycord, xmn, ymn, xmx, ymx, 1, title2, 0, barcolor);
+
+ /* draw some hash marks showing scalefactor bands */
+ if (gtkinfo.sfblines) {
+ int fac, nsfb, *scalefac;
+ if (blocktype[gr][ch] == SHORT_TYPE) {
+ nsfb = SBMAX_s;
+ i = nsfb - 7;
+ fac = 3;
+ scalefac = gfc->scalefac_band.s;
+ }
+ else {
+ nsfb = SBMAX_l;
+ i = nsfb - 10;
+ fac = 1;
+ scalefac = gfc->scalefac_band.l;
+ }
+ for (; i < nsfb; i++) {
+ ycord[0] = .8 * ymx;
+ ycord[1] = ymn;
+ xcord[0] = fac * scalefac[i];
+ xcord[1] = xcord[0];
+ gpk_rectangle_draw(mdctbox[gr], xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
+ }
+ }
+
+
+
+ ymn = 9e20;
+ ymx = -9e20;
+ for (i = 0; i < n; i++) {
+ double coeff;
+ xcord[i] = i;
+ if (gtkinfo.msflag) {
+ coeff = ch ? .5 * (data[i] - data2[i]) : .5 * (data[i] + data2[i]);
+ }
+ else {
+ coeff = ch ? data2[i] : data[i];
+ }
+ if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
+ coeff = 0;
+ ycord[i] = coeff * coeff * 1e10;
+ ycord[i] = log10(MAX(ycord[i], (double) 1));
+
+#if 0
+ if (ch == 0)
+ if (i == 26)
+ if (data[i] != 0)
+ console_printf("%i %i i=%i mdct: (db) %f %f \n", pplot->frameNum, gr, i,
+ 10 * log10(data[i] * data[i]),
+ 10 * log10(.33 *
+ (data[i - 1] * data[i - 1] + data[i] * data[i] +
+ data[i + 1] * data[i + 1]))
+ );
+#endif
+
+ ymx = (ycord[i] > ymx) ? ycord[i] : ymx;
+ ymn = (ycord[i] < ymn) ? ycord[i] : ymn;
+ }
+ /* print the min/max
+ sprintf(title2,"MDCT%1i %5.2f %5.2f bits=%i",gr,ymn,ymx,
+ pplot1->mainbits[gr][ch]);
+ */
+ if (gtkinfo.flag123)
+ bits = pplot1->mainbits[gr][ch];
+ else
+ bits = pplot->LAMEmainbits[gr][ch];
+
+
+ sprintf(title2, "MDCT%1i(%s) bits=%i ", gr, label, bits);
+
+ xmn = 0;
+ xmx = n - 1;
+ ymn = 0;
+ ymx = 11;
+ gpk_bargraph_draw(mdctbox[gr], n, xcord, ycord, xmn, ymn, xmx, ymx, 0, title2, 0, barcolor);
+ }
+
+
+
+
+ /*******************************************************************
+ * draw the psy model energy spectrum (k space)
+ * l3psy.c computes pe, en, thm for THIS granule.
+ *******************************************************************/
+ if (gtkinfo.kbflag) {
+ for (gr = 0; gr < mode_gr; gr++) {
+ n = HBLKSIZE; /* only show half the spectrum */
+
+ data = &pplot->energy[gr][ch][0];
+
+ ymn = 9e20;
+ ymx = -9e20;
+ for (i = 0; i < n; i++) {
+ xcord[i] = i + 1;
+ if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
+ ycord[i] = 0;
+ else
+ ycord[i] = log10(MAX(data[i], (double) 1));
+ ymx = (ycord[i] > ymx) ? ycord[i] : ymx;
+ ymn = (ycord[i] < ymn) ? ycord[i] : ymn;
+ }
+ for (en = 0, j = 0; j < BLKSIZE; j++)
+ en += pplot->energy[gr][ch][j];
+
+ sprintf(title2, "FFT%1i pe=%5.2fK en=%5.2e ", gr, pplot->pe[gr][ch] / 1000, en);
+
+ ymn = 3;
+ ymx = 15;
+ xmn = 1;
+ xmx = n;
+ gpk_bargraph_draw(enerbox[gr], n, xcord, ycord,
+ xmn, ymn, xmx, ymx, 1, title2, 0, barcolor);
+
+ }
+ }
+ else {
+ /*******************************************************************
+ * draw the psy model energy spectrum (scalefactor bands)
+ *******************************************************************/
+ for (gr = 0; gr < mode_gr; gr++) {
+
+ if (blocktype[gr][ch] == 2) {
+ n = 3 * SBMAX_s;
+ data = &pplot->en_s[gr][ch][0];
+ data2 = &pplot->thr_s[gr][ch][0];
+ data3 = &pplot->xfsf_s[gr][ch][0];
+ }
+ else {
+ n = SBMAX_l;
+ data = &pplot->en[gr][ch][0];
+ data2 = &pplot->thr[gr][ch][0];
+ data3 = &pplot->xfsf[gr][ch][0];
+ }
+ ymn = 9e20;
+ ymx = -9e20;
+ for (i = 0; i < n; i++) {
+ xcord[i] = i + 1;
+ if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
+ ycord[i] = 0;
+ else
+ ycord[i] = log10(MAX(data[i], (double) 1));
+ /*
+ ymx=(ycord[i] > ymx) ? ycord[i] : ymx;
+ ymn=(ycord[i] < ymn) ? ycord[i] : ymn;
+ */
+ }
+
+
+
+ /* en = max energy difference amoung the 3 short FFTs for this granule */
+ en = pplot->ers[gr][ch];
+ if (en > 999)
+ en = 999;
+ sprintf(title2,
+ "FFT%1i pe=%5.2fK/%3.1f \nnoise ovr_b:%i/max:%3.1f/ovr:%3.1f/tot:%3.1f/ssd:%i",
+ gr, pplot->pe[gr][ch] / 1000, en, pplot->over[gr][ch], pplot->max_noise[gr][ch],
+ pplot->over_noise[gr][ch], pplot->tot_noise[gr][ch], pplot->over_SSD[gr][ch]);
+
+ barthick = 3;
+ if (blocktype[gr][ch] == SHORT_TYPE)
+ barthick = 2;
+ if (!(subblock_draw[0] && subblock_draw[1] && subblock_draw[2]))
+ barthick = 3;
+
+ ymn = 3;
+ ymx = 15;
+ xmn = 1;
+ xmx = n + 1; /* a little extra because of the bar thickness */
+ gpk_bargraph_draw(enerbox[gr], n, xcord, ycord,
+ xmn, ymn, xmx, ymx, 1, title2, barthick, barcolor);
+
+ for (i = 0; i < n; i++) {
+ xcord[i] = i + 1 + .20;
+ if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
+ ycord[i] = 0;
+ else
+ ycord[i] = log10(MAX(data2[i], (double) 1));
+ }
+
+ gpk_bargraph_draw(enerbox[gr], n, xcord, ycord,
+ xmn, ymn, xmx, ymx, 0, title2, barthick, grcolor[gr]);
+
+ for (i = 0; i < n; i++) {
+ xcord[i] = i + 1 + .40;
+ if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
+ ycord[i] = 0;
+ else
+ ycord[i] = log10(MAX(data3[i], (double) 1));
+ }
+ gpk_bargraph_draw(enerbox[gr], n, xcord, ycord,
+ xmn, ymn, xmx, ymx, 0, title2, barthick, &red);
+
+ }
+ }
+
+ /*******************************************************************
+ * draw scalefactors
+ *******************************************************************/
+ for (gr = 0; gr < mode_gr; gr++) {
+ int ggain;
+ if (blocktype[gr][ch] == 2) {
+ n = 3 * SBMAX_s;
+ if (gtkinfo.flag123)
+ data = pplot1->sfb_s[gr][ch];
+ else
+ data = pplot->LAMEsfb_s[gr][ch];
+ }
+ else {
+ n = SBMAX_l;
+ if (gtkinfo.flag123)
+ data = pplot1->sfb[gr][ch];
+ else
+ data = pplot->LAMEsfb[gr][ch];
+ }
+
+ ymn = -1;
+ ymx = 10;
+ for (i = 0; i < n; i++) {
+ xcord[i] = i + 1;
+ if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
+ ycord[i] = 0;
+ else
+ ycord[i] = -data[i];
+
+ ymx = (ycord[i] > ymx - 2) ? ycord[i] + 2 : ymx;
+ ymn = (ycord[i] < ymn) ? ycord[i] - 1 : ymn;
+ }
+
+ if (blocktype[gr][ch] == 2) {
+ sprintf(label2,
+ "SFB scale=%i preflag=%i %i%i%i",
+ pplot1->scalefac_scale[gr][ch],
+ pplot1->preflag[gr][ch],
+ pplot1->sub_gain[gr][ch][0],
+ pplot1->sub_gain[gr][ch][1], pplot1->sub_gain[gr][ch][2]);
+ }
+ else {
+ sprintf(label2, "SFB scale=%i preflag=%i", pplot1->scalefac_scale[gr][ch],
+ pplot1->preflag[gr][ch]);
+ }
+
+ if (gtkinfo.flag123)
+ ggain = (pplot1->qss[gr][ch]);
+ else
+ ggain = (pplot->LAMEqss[gr][ch]);
+
+ sprintf(title2, " ggain=%i", ggain);
+ strcat(label2, title2);
+
+ xmn = 1;
+ xmx = n + 1;
+ gpk_bargraph_draw(sfbbox[gr], n, xcord, ycord,
+ xmn, ymn, xmx, ymx, 1, label2, 0, grcolor[gr]);
+
+ ycord[0] = ycord[1] = 0;
+ xcord[0] = 1;
+ xcord[1] = n + 1;
+ gpk_rectangle_draw(sfbbox[gr], xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
+
+
+ }
+
+
+}
+
+
+
+static void
+update_progress(void)
+{
+ char label[80];
+
+ int tf = lame_get_totalframes(gfp);
+ if (gtkinfo.totalframes > 0)
+ tf = gtkinfo.totalframes;
+
+ sprintf(label, "Frame:%4i/%4i %6.2fs", pplot->frameNum, (int) tf - 1, pplot->frametime);
+ gtk_progress_set_value(GTK_PROGRESS(frameprogress), (gdouble) pplot->frameNum);
+ gtk_label_set_text(GTK_LABEL(framecounter), label);
+}
+
+
+
+static void
+analyze(void)
+{
+ if (idle_keepgoing) {
+ idle_count = 0;
+ idle_count_max = 0;
+ idle_keepgoing = 0;
+ idle_end = 0;
+ }
+ plot_frame();
+ update_progress();
+}
+
+static void
+plotclick(GtkWidget * widget, gpointer data)
+{
+ analyze();
+}
+
+
+
+
+static int
+frameadv1(GtkWidget * widget, gpointer data)
+{
+ int i;
+ if (idle_keepgoing) {
+ if (idle_back) {
+ /* frame displayed is the old frame. to advance, just swap in new frame */
+ idle_back--;
+ pplot = &Pinfo[READ_AHEAD + idle_back];
+ }
+ else {
+ /* advance the frame by reading in a new frame */
+ pplot = &Pinfo[READ_AHEAD];
+ if (mp3done) {
+ /* dont try to read any more frames, and quit if "finish MP3" was selected */
+ /* if (idle_finish) gtk_main_quit(); */
+ idle_count_max = 0;
+ idle_end = 0;
+ }
+ else {
+ /* read in the next frame */
+ for (i = NUMPINFO - 1; i > 0; i--)
+ memcpy(&Pinfo[i], &Pinfo[i - 1], sizeof(plotting_data));
+ pinfo = &Pinfo[0];
+ pinfo->num_samples = gtkmakeframe();
+ if (pinfo->num_samples == 0 && gtkinfo.totalframes == 0)
+ /* allow an extra frame to flush decoder buffers */
+ gtkinfo.totalframes = pinfo->frameNum + 2;
+
+ if (pinfo->sampfreq)
+ pinfo->frametime = (pinfo->frameNum) * 1152.0 / pinfo->sampfreq;
+ else
+ pinfo->frametime = 0;
+
+ /* eof?
+ if (!pinfo->num_samples) if (idle_finish) gtk_main_quit();
+ */
+
+ pinfo->totbits = 0;
+ {
+ int gr, ch;
+ for (gr = 0; gr < 2; gr++)
+ for (ch = 0; ch < 2; ch++) {
+ gtkinfo.totshort += (pinfo->mpg123blocktype[gr][ch] == 2);
+ gtkinfo.totmix += !(pinfo->mixed[gr][ch] == 0);
+ gtkinfo.totpreflag += (pinfo->preflag[gr][ch] == 1);
+ pinfo->totbits += pinfo->mainbits[gr][ch];
+ }
+ }
+ if (pinfo->frameNum > 0) /* start averaging at second frame */
+ gtkinfo.avebits = (gtkinfo.avebits * ((pinfo->frameNum) - 1)
+ + pinfo->totbits) / (pinfo->frameNum);
+
+ gtkinfo.maxbits = MAX(gtkinfo.maxbits, pinfo->totbits);
+ gtkinfo.totemph += !(pinfo->emph == 0);
+ gtkinfo.totms += !(pinfo->ms_stereo == 0);
+ gtkinfo.totis += !(pinfo->i_stereo == 0);
+
+ if (gtkinfo.totalframes > 0)
+ if (pplot->frameNum >= gtkinfo.totalframes - 1)
+ mp3done = 1;
+ }
+ }
+
+ idle_count++;
+ if (gtkinfo.pupdate)
+ plot_frame();
+ update_progress();
+ if ((idle_count >= idle_count_max) && (!idle_end))
+ analyze();
+ }
+ else {
+ /*no processing to do, sleep in order to not monopolize CPU */
+ msleep(10);
+ }
+ return 1;
+}
+
+
+static void
+frameadv(GtkWidget * widget, gpointer data)
+{
+ int adv;
+
+ if (!strcmp((char *) data, "-1")) {
+ /* ignore if we've already gone back as far as possible */
+ if (pplot->frameNum == 0 || (idle_back == NUMBACK))
+ return;
+ idle_back++;
+ pplot = &Pinfo[READ_AHEAD + idle_back];
+ analyze();
+ return;
+ }
+
+
+ adv = 1;
+ if (!strcmp((char *) data, "1"))
+ adv = 1;
+ if (!strcmp((char *) data, "10"))
+ adv = 10;
+ if (!strcmp((char *) data, "100"))
+ adv = 100;
+ if (!strcmp((char *) data, "finish"))
+ idle_end = 1;
+
+
+ if (idle_keepgoing) {
+ /* already running - que up additional frame advance requests */
+ idle_count_max += adv;
+ }
+ else {
+ /* turn on idleing */
+ idle_count_max = adv;
+ idle_count = 0;
+ idle_keepgoing = 1;
+ }
+}
+
+
+
+
+/* another callback */
+static void
+delete_event(GtkWidget * widget, GdkEvent * event, gpointer data)
+{
+ /* set MP3 done flag in case the File/Quit menu item has been selected */
+ mp3done = 1;
+
+ gtk_main_quit();
+}
+
+
+
+
+
+
+
+static void
+channel_option(GtkWidget * widget, gpointer data)
+{
+ long option;
+ option = (long) data;
+ switch (option) {
+ case 1:
+ gtkinfo.msflag = 0;
+ gtkinfo.chflag = 0;
+ break;
+ case 2:
+ gtkinfo.msflag = 0;
+ gtkinfo.chflag = 1;
+ break;
+ case 3:
+ gtkinfo.msflag = 1;
+ gtkinfo.chflag = 0;
+ break;
+ case 4:
+ gtkinfo.msflag = 1;
+ gtkinfo.chflag = 1;
+ }
+ analyze();
+}
+static void
+spec_option(GtkWidget * widget, gpointer data)
+{
+ long option;
+ option = (long) data;
+ switch (option) {
+ case 1:
+ gtkinfo.kbflag = 0;
+ break;
+ case 2:
+ gtkinfo.kbflag = 1;
+ break;
+ case 3:
+ gtkinfo.flag123 = 0;
+ break;
+ case 4:
+ gtkinfo.flag123 = 1;
+ break;
+ case 5:
+ gtkinfo.pupdate = 1;
+ break;
+ case 6:
+ gtkinfo.pupdate = 0;
+ break;
+ case 7:
+ gtkinfo.sfblines = !gtkinfo.sfblines;
+ break;
+ case 8:
+ gtkinfo.difference = !gtkinfo.difference;
+ break;
+ }
+ analyze();
+}
+
+static gint
+key_press_event(GtkWidget * widget, GdkEventKey * event)
+{
+ /* is a switch() statement in lame forbidden? */
+ if (event->keyval == '1') {
+ subblock_draw[0] = 1;
+ subblock_draw[1] = 0;
+ subblock_draw[2] = 0;
+ analyze();
+ }
+ else if (event->keyval == '2') {
+ subblock_draw[0] = 0;
+ subblock_draw[1] = 1;
+ subblock_draw[2] = 0;
+ analyze();
+ }
+ else if (event->keyval == '3') {
+ subblock_draw[0] = 0;
+ subblock_draw[1] = 0;
+ subblock_draw[2] = 1;
+ analyze();
+ }
+ else if (event->keyval == '0') {
+ subblock_draw[0] = 1;
+ subblock_draw[1] = 1;
+ subblock_draw[2] = 1;
+ analyze();
+ }
+ /* analyze(); */ /* dont redraw entire window for every key! */
+ return 0;
+}
+
+
+/*! Get the mp3x version string. */
+/*!
+ \param void
+ \return a pointer to a string which describes the version of mp3x.
+*/
+const char *
+get_mp3x_version(void)
+{
+#if MP3X_ALPHA_VERSION > 0
+ static /*@observer@ */ const char *const str =
+ XSTR(MP3X_MAJOR_VERSION) "." XSTR(MP3X_MINOR_VERSION)
+ " (alpha " XSTR(MP3X_ALPHA_VERSION) ", " __DATE__ " " __TIME__ ")";
+#elif MP3X_BETA_VERSION > 0
+ static /*@observer@ */ const char *const str =
+ XSTR(MP3X_MAJOR_VERSION) "." XSTR(MP3X_MINOR_VERSION)
+ " (beta " XSTR(MP3X_BETA_VERSION) ", " __DATE__ ")";
+#else
+ static /*@observer@ */ const char *const str =
+ XSTR(MP3X_MAJOR_VERSION) "." XSTR(MP3X_MINOR_VERSION);
+#endif
+
+ return str;
+}
+
+
+static void
+text_window(GtkWidget * widget, gpointer data)
+{
+ long option;
+ GtkWidget *hbox, *vbox, *button, *box;
+ GtkWidget *textwindow, *vscrollbar;
+ char text[256];
+
+ option = (long) data;
+
+ textwindow = gtk_window_new(GTK_WINDOW_DIALOG);
+ gtk_signal_connect_object(GTK_OBJECT(window), "delete_event",
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(textwindow));
+
+ gtk_container_set_border_width(GTK_CONTAINER(textwindow), 0);
+ vbox = gtk_vbox_new(FALSE, 0);
+ hbox = gtk_hbox_new(FALSE, 0);
+
+ button = gtk_button_new_with_label("close");
+ gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(textwindow));
+
+ box = gtk_text_new(NULL, NULL);
+ gtk_text_set_editable(GTK_TEXT(box), FALSE);
+ vscrollbar = gtk_vscrollbar_new(GTK_TEXT(box)->vadj);
+
+
+ switch (option) {
+ case 0:
+ gtk_window_set_title(GTK_WINDOW(textwindow), "Documentation");
+ gtk_widget_set_usize(box, 450, 500);
+ gtk_text_set_word_wrap(GTK_TEXT(box), TRUE);
+ /* text should be moved outside this function, may be in a separate file */
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
+ "Frame header information: "
+ "First the bitrate, sampling frequency and mono, stereo or jstereo "
+ "indicators are displayed . If the bitstream is jstereo, then mid/side "
+ "stereo or intensity stereo may be on (indicated in red). If "
+ "de-emphasis is used, this is also indicated in red. The mdb value is "
+ "main_data_begin. The encoded data starts this many bytes *before* the "
+ "frame header. A large value of mdb means the bitstream has saved some "
+ "bits into the reservoir, which it may allocate for some future frame. "
+ "The two numbers after mdb are the size (in bits) used to encode the "
+ "MDCT coefficients for this frame, followed byt the size of the bit "
+ "resevoir before encoding this frame. The maximum frame size and a "
+ "running average are given in the Stats pull down menu. A large "
+ "maximum frame size indicates the bitstream has made use of the bit "
+ "reservoir. \n\n", -1);
+
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
+ "PCM data (top graph): "
+ "The PCM data is plotted in black. The layer3 frame is divided into 2 "
+ "granules of 576 samples (marked with yellow vertical lines). In the "
+ "case of normal, start and stop blocks, the MDCT coefficients for each "
+ "granule are computed using a 1152 sample window centered over the "
+ "granule. In the case of short blocks, the granule is further divided "
+ "into 3 blocks of 192 samples (also marked with yellow vertical lines)."
+ "The MDCT coefficients for these blocks are computed using 384 sample "
+ "windows centered over the 192 sample window. (This info not available "
+ "when analyzing .mp3 files.) For the psycho-acoustic model, a windowed "
+ "FFT is computed for each granule. The range of these windows "
+ "is denoted by the blue and green bars.\n\n", -1);
+
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
+ "PCM re-synthesis data (second graph): "
+ "Same as the PCM window described above. The data displayed is the "
+ "result of encoding and then decoding the original sample. \n\n", -1);
+
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
+ "MDCT windows: "
+ "Shows the energy in the MDCT spectrum for granule 0 (left window) "
+ "and granule 1 (right window). The text also shows the blocktype "
+ "used, the number of bits used to encode the coefficients and the "
+ "number of extra bits allocated from the reservoir. The MDCT pull down "
+ "window will toggle between the original unquantized MDCT coefficients "
+ "and the compressed (quantized) coefficients.\n\n", -1);
+
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
+ "FFT window: "
+ "The gray bars show the energy in the FFT spectrum used by the "
+ "psycho-acoustic model. Granule 0 is in the left window, granule 1 in "
+ "the right window. The green and blue bars show how much distortion is "
+ "allowable, as computed by the psycho-acoustic model. The red bars show "
+ "the actual distortion after encoding. There is one FFT for each "
+ "granule, computed with a 1024 Hann window centered over the "
+ "appropriate granule. (the range of this 1024 sample window is shown "
+ "by the blue and green bars in the PCM data window). The Spectrum pull "
+ "down window will toggle between showing the energy in equally spaced "
+ "frequency domain and the scale factor bands used by layer3. Finally, "
+ "the perceptual entropy, total energy and number of scalefactor bands "
+ "with audible distortion is shown. (This info not available when "
+ "analyzing .mp3 files.)", -1);
+
+ break;
+ case 1:
+ /* Set the about box information */
+ gtk_window_set_title(GTK_WINDOW(textwindow), "About");
+ gtk_widget_set_usize(box, 350, 260);
+
+ sprintf(text, "LAME version %s \n%s\n\n", get_lame_version(), get_lame_url());
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+
+ sprintf(text, "psycho-acoustic model: GPSYCHO version %s\n", get_psy_version());
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+
+ sprintf(text, "frame analyzer: MP3x version %s\n\n", get_mp3x_version());
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
+ "decoder: mpg123/mpglib .59q \nMichael Hipp (www.mpg123.de)\n\n", -1);
+
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
+ "Encoder, decoder & psy-models based on ISO\ndemonstration source. ", -1);
+ break;
+
+ case 2:
+ gtk_window_set_title(GTK_WINDOW(textwindow), "Statistics");
+ gtk_widget_set_usize(box, 350, 260);
+ sprintf(text, "frames processed so far: %i \n", Pinfo[0].frameNum + 1);
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+ sprintf(text, "granules processed so far: %i \n\n", 4 * (Pinfo[0].frameNum + 1));
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+ sprintf(text, "mean bits/frame (approximate): %i\n", gtkinfo.approxbits);
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+ sprintf(text, "mean bits/frame (from LAME): %i\n", 4 * Pinfo[0].mean_bits);
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+ sprintf(text, "bitsize of largest frame: %i \n", gtkinfo.maxbits);
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+ sprintf(text, "average bits/frame: %3.1f \n\n", gtkinfo.avebits);
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+ sprintf(text, "ms_stereo frames: %i \n", gtkinfo.totms);
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+ sprintf(text, "i_stereo frames: %i \n", gtkinfo.totis);
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+ sprintf(text, "de-emphasis frames: %i \n", gtkinfo.totemph);
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+ sprintf(text, "short block granules: %i \n", gtkinfo.totshort);
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+ sprintf(text, "mixed block granules: %i \n", gtkinfo.totmix);
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+ sprintf(text, "preflag granules: %i \n", gtkinfo.totpreflag);
+ gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
+ break;
+ }
+
+
+
+ gtk_widget_show(vscrollbar);
+ gtk_widget_show(box);
+ gtk_widget_show(vbox);
+ gtk_widget_show(hbox);
+ gtk_widget_show(button);
+
+ gtk_box_pack_start(GTK_BOX(hbox), box, FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
+ gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(textwindow), vbox);
+ gtk_widget_show(textwindow);
+
+}
+
+
+
+
+/* #include <strings.h>*/
+
+
+/* This is the GtkItemFactoryEntry structure used to generate new menus.
+ Item 1: The menu path. The letter after the underscore indicates an
+ accelerator key once the menu is open.
+ Item 2: The accelerator key for the entry
+ Item 3: The callback function.
+ Item 4: The callback action. This changes the parameters with
+ which the function is called. The default is 0.
+ Item 5: The item type, used to define what kind of an item it is.
+ Here are the possible values:
+
+ NULL -> "<Item>"
+ "" -> "<Item>"
+ "<Title>" -> create a title item
+ "<Item>" -> create a simple item
+ "<CheckItem>" -> create a check item
+ "<ToggleItem>" -> create a toggle item
+ "<RadioItem>" -> create a radio item
+ <path> -> path of a radio item to link against
+ "<Separator>" -> create a separator
+ "<Branch>" -> create an item to hold sub items
+ "<LastBranch>" -> create a right justified branch
+*/
+
+
+#define C(chr) "<control>" #chr
+#define func(name) (GtkItemFactoryCallback) (name)
+
+static const GtkItemFactoryEntry menu_items[] = {
+ {"/_File", NULL, NULL, 0, "<Branch>"},
+#if 0
+ {"/File/_New", C(N), func(print_hello), 0, NULL},
+ {"/File/_Open", C(O), func(print_hello), 0, NULL},
+ {"/File/_Save", C(S), func(print_hello), 0, NULL},
+ {"/File/Save _As", NULL, NULL, 0, NULL},
+ {"/File/sep1", NULL, NULL, 0, "<Separator>"},
+ {"/File/Quit", C(Q), func(gtk_main_quit), 0, NULL},
+#endif
+ {"/File/_Quit", C(Q), func(delete_event), 0, NULL},
+
+ {"/_Plotting", NULL, NULL, 0, "<Branch>"},
+ {"/Plotting/_While advancing", NULL, func(spec_option), 5, NULL},
+ {"/Plotting/_After advancing", NULL, func(spec_option), 6, NULL},
+ {"/Plotting/Toggle SFB lines", NULL, func(spec_option), 7, NULL},
+ {"/Plotting/Toggle orig-diff", NULL, func(spec_option), 8, NULL},
+
+ {"/_Channel", NULL, NULL, 0, "<Branch>"},
+ {"/Channel/show _Left", NULL, func(channel_option), 1, NULL},
+ {"/Channel/show _Right", NULL, func(channel_option), 2, NULL},
+ {"/Channel/show _Mid", NULL, func(channel_option), 3, NULL},
+ {"/Channel/show _Side", NULL, func(channel_option), 4, NULL},
+
+ {"/_Spectrum", NULL, NULL, 0, "<Branch>"},
+ {"/Spectrum/_Scalefactor bands", NULL, func(spec_option), 1, NULL},
+ {"/Spectrum/_Wave number", NULL, func(spec_option), 2, NULL},
+
+ {"/_MDCT", NULL, NULL, 0, "<Branch>"},
+ {"/MDCT/_Original", NULL, func(spec_option), 3, NULL},
+ {"/MDCT/_Compressed", NULL, func(spec_option), 4, NULL},
+ {"/MDCT/_Toggle SFB lines", NULL, func(spec_option), 7, NULL},
+
+ {"/_Stats", NULL, NULL, 0, "<Branch>"},
+ {"/Stats/_Show", NULL, func(text_window), 2, NULL},
+
+ {"/_Help", NULL, NULL, 0, "<LastBranch>"},
+ {"/_Help/_Documentation", NULL, func(text_window), 0, NULL},
+ {"/_Help/_About", NULL, func(text_window), 1, NULL},
+};
+
+#undef C
+#undef func
+
+
+static void
+get_main_menu(GtkWidget * windows, GtkWidget ** menubar)
+{
+ unsigned int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
+ GtkItemFactory *item_factory;
+ GtkAccelGroup *accel_group;
+
+ accel_group = gtk_accel_group_new();
+
+ /* This function initializes the item factory.
+ Param 1: The type of menu - can be GTK_TYPE_MENU_BAR, GTK_TYPE_MENU,
+ or GTK_TYPE_OPTION_MENU.
+ Param 2: The path of the menu.
+ Param 3: A pointer to a gtk_accel_group. The item factory sets up
+ the accelerator table while generating menus.
+ */
+
+ item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
+
+ /* This function generates the menu items. Pass the item factory,
+ the number of items in the array, the array itself, and any
+ callback data for the the menu items. */
+ gtk_item_factory_create_items(item_factory, nmenu_items, (GtkItemFactoryEntry *) menu_items,
+ NULL);
+
+ /* Attach the new accelerator group to the window. */
+ gtk_accel_group_attach(accel_group, GTK_OBJECT(windows));
+
+ if (menubar)
+ /* Finally, return the actual menu bar created by the item factory. */
+ *menubar = gtk_item_factory_get_widget(item_factory, "<main>");
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+int
+gtkcontrol(lame_global_flags * gfp2, char *inPath)
+{
+ /* GtkWidget is the storage type for widgets */
+ GtkWidget *button;
+ GtkAdjustment *adj;
+ GtkWidget *mbox; /* main box */
+ GtkWidget *box1; /* frame control buttons go */
+ GtkWidget *box2; /* frame counters */
+ GtkWidget *box3; /* frame header info */
+ GtkWidget *table; /* table for all the plotting areas */
+ GtkWidget *menubar;
+
+ gint tableops, graphx, graphy;
+ char frameinfo[80];
+
+ graphx = 600; /* minimum allowed size of pixmap */
+ graphy = 95;
+
+ gfp = gfp2;
+ gfc = gfp->internal_flags;
+
+ /* set some global defaults/variables */
+ gtkinfo.filetype = is_mpeg_file_format(input_format) ? 1 : 0;
+ gtkinfo.msflag = 0;
+ gtkinfo.chflag = 0;
+ gtkinfo.kbflag = 0;
+ gtkinfo.flag123 = is_mpeg_file_format(input_format) ? 1 : 0; /* MP3 file=use mpg123 output */
+ gtkinfo.pupdate = 0;
+ gtkinfo.avebits = 0;
+ gtkinfo.maxbits = 0;
+ gtkinfo.approxbits = 0;
+ gtkinfo.totemph = 0;
+ gtkinfo.totms = 0;
+ gtkinfo.totis = 0;
+ gtkinfo.totshort = 0;
+ gtkinfo.totmix = 0;
+ gtkinfo.sfblines = 1;
+ gtkinfo.difference = 0;
+ gtkinfo.totalframes = 0;
+
+ memset((char *) Pinfo, 0, sizeof(Pinfo));
+ pplot = &Pinfo[READ_AHEAD];
+
+ strcpy(frameinfo, "MP3x: ");
+ strncat(frameinfo, inPath, 70);
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(window), frameinfo);
+ gtk_signal_connect(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(delete_event), NULL);
+
+ gtk_signal_connect_object(GTK_OBJECT(window), "key_press_event",
+ GTK_SIGNAL_FUNC(key_press_event), GTK_OBJECT(window));
+
+ gtk_container_set_border_width(GTK_CONTAINER(window), 0);
+
+
+ mbox = gtk_vbox_new(FALSE, 0);
+
+
+ /* layout of mbox */
+ box1 = gtk_hbox_new(FALSE, 0);
+ box2 = gtk_hbox_new(FALSE, 0);
+ box3 = gtk_hbox_new(FALSE, 0);
+ table = gtk_table_new(5, 2, FALSE);
+ tableops = GTK_FILL | GTK_EXPAND | GTK_SHRINK;
+ get_main_menu(window, &menubar);
+
+ gtk_box_pack_start(GTK_BOX(mbox), menubar, FALSE, TRUE, 0);
+ gtk_box_pack_end(GTK_BOX(mbox), box1, FALSE, TRUE, 0);
+ gtk_box_pack_end(GTK_BOX(mbox), box2, FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(mbox), box3, FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(mbox), table, TRUE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(window), mbox);
+
+
+ /*********************************************************************/
+ /* stuff in box3 frame header info */
+ /*********************************************************************/
+ /*
+ headerbox = gtk_label_new(" ");
+ gtk_label_set_justify(GTK_LABEL(headerbox),GTK_JUSTIFY_LEFT);
+ */
+ headerbox = gtk_text_new(NULL, NULL);
+ gtk_text_set_editable(GTK_TEXT(headerbox), FALSE);
+ gtk_widget_set_usize(headerbox, 200, 20);
+ gtk_widget_show(headerbox);
+ gtk_box_pack_start(GTK_BOX(box3), headerbox, TRUE, TRUE, 0);
+
+
+
+ /*********************************************************************/
+ /* stuff in box2 frame counters */
+ /*********************************************************************/
+ framecounter = gtk_label_new("");
+ gtk_widget_show(framecounter);
+ gtk_box_pack_start(GTK_BOX(box2), framecounter, FALSE, TRUE, 0);
+
+ adj = (GtkAdjustment *) gtk_adjustment_new(0, 0, (gint) lame_get_totalframes(gfp) - 1, 0, 0, 0);
+ frameprogress = gtk_progress_bar_new_with_adjustment(adj);
+ /* Set the format of the string that can be displayed in the
+ * trough of the progress bar:
+ * %p - percentage
+ * %v - value
+ * %l - lower range value
+ * %u - upper range value */
+ gtk_progress_set_format_string(GTK_PROGRESS(frameprogress), "%p%%");
+ gtk_progress_set_value(GTK_PROGRESS(frameprogress), (gdouble) 0);
+ gtk_progress_set_show_text(GTK_PROGRESS(frameprogress), TRUE);
+ gtk_widget_show(frameprogress);
+ gtk_box_pack_end(GTK_BOX(box2), frameprogress, FALSE, TRUE, 0);
+
+
+
+ /*********************************************************************/
+ /* stuff in box1 buttons along bottom */
+ /*********************************************************************/
+ button = gtk_button_new_with_label("-1");
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(frameadv), (gpointer) "-1");
+ gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label("+1");
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(frameadv), (gpointer) "1");
+ gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label("+10");
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(frameadv), (gpointer) "10");
+ gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label("+100");
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(frameadv), (gpointer) "100");
+ gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label("last frame");
+ gtk_signal_connect(GTK_OBJECT(button), "clicked",
+ GTK_SIGNAL_FUNC(frameadv), (gpointer) "finish");
+ gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label("stop/plot");
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(plotclick), NULL);
+ gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+
+ /*********************************************************************/
+ /* stuff in table. all the plotting windows */
+ /*********************************************************************/
+ pcmbox = gpk_plot_new(graphx, graphy);
+ gtk_table_attach(GTK_TABLE(table), pcmbox, 0, 2, 0, 1, tableops, tableops, 2, 2);
+ gtk_widget_show(pcmbox);
+
+ winbox = gpk_plot_new(graphy, graphy);
+ gtk_table_attach(GTK_TABLE(table), winbox, 0, 2, 1, 2, tableops, tableops, 2, 2);
+ gtk_widget_show(winbox);
+
+
+ mdctbox[0] = gpk_plot_new(graphy, graphy);
+ gtk_table_attach(GTK_TABLE(table), mdctbox[0], 0, 1, 2, 3, tableops, tableops, 2, 2);
+ gtk_widget_show(mdctbox[0]);
+
+ mdctbox[1] = gpk_plot_new(graphy, graphy);
+ gtk_table_attach(GTK_TABLE(table), mdctbox[1], 1, 2, 2, 3, tableops, tableops, 2, 2);
+ gtk_widget_show(mdctbox[1]);
+
+ enerbox[0] = gpk_plot_new(graphy, graphy);
+ gtk_table_attach(GTK_TABLE(table), enerbox[0], 0, 1, 3, 4, tableops, tableops, 2, 2);
+ gtk_widget_show(enerbox[0]);
+
+ enerbox[1] = gpk_plot_new(graphy, graphy);
+ gtk_table_attach(GTK_TABLE(table), enerbox[1], 1, 2, 3, 4, tableops, tableops, 2, 2);
+ gtk_widget_show(enerbox[1]);
+
+ sfbbox[0] = gpk_plot_new(graphy, graphy);
+ gtk_table_attach(GTK_TABLE(table), sfbbox[0], 0, 1, 4, 5, tableops, tableops, 2, 2);
+ gtk_widget_show(sfbbox[0]);
+
+ sfbbox[1] = gpk_plot_new(graphy, graphy);
+ gtk_table_attach(GTK_TABLE(table), sfbbox[1], 1, 2, 4, 5, tableops, tableops, 2, 2);
+ gtk_widget_show(sfbbox[1]);
+
+
+
+
+ gtk_idle_add((GtkFunction) frameadv1, NULL);
+ gtk_widget_show(menubar);
+ gtk_widget_show(box2);
+ gtk_widget_show(box3);
+ gtk_widget_show(table);
+ gtk_widget_show(box1);
+ gtk_widget_show(mbox);
+ gtk_widget_show(window); /* show smallest allowed window */
+
+ /* make window bigger. */
+ /* now the user will be able to shrink it, if desired */
+ /* gtk_widget_set_usize(mbox,500,500); */
+ /* gtk_widget_show (window); */ /* show smallest allowed window */
+
+
+
+ idle_keepgoing = 1; /* processing of frames is ON */
+ idle_count_max = READ_AHEAD + 1; /* number of frames to process before plotting */
+ idle_count = 0; /* pause & plot when idle_count=idle_count_max */
+
+ gtk_main();
+ assert(mp3done);
+ return (0);
+}
diff --git a/lib/liblame/frontend/gtkanal.h b/lib/liblame/frontend/gtkanal.h
new file mode 100644
index 0000000000..0ce210c13b
--- /dev/null
+++ b/lib/liblame/frontend/gtkanal.h
@@ -0,0 +1,25 @@
+/*
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_GTKCONTROL_H
+#define LAME_GTKCONTROL_H
+
+
+int gtkcontrol(lame_global_flags * gfp2, char *inPath);
+
+#endif
diff --git a/lib/liblame/frontend/lame_vc6.dsp b/lib/liblame/frontend/lame_vc6.dsp
new file mode 100644
index 0000000000..45536d0848
--- /dev/null
+++ b/lib/liblame/frontend/lame_vc6.dsp
@@ -0,0 +1,188 @@
+# Microsoft Developer Studio Project File - Name="lame" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=LAME - WIN32 DEBUG
+!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
+!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
+!MESSAGE
+!MESSAGE NMAKE /f "lame_vc6.mak".
+!MESSAGE
+!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
+!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
+!MESSAGE
+!MESSAGE NMAKE /f "lame_vc6.mak" CFG="LAME - WIN32 DEBUG"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "lame - Win32 Release" (basierend auf "Win32 (x86) Console Application")
+!MESSAGE "lame - Win32 Debug" (basierend auf "Win32 (x86) Console Application")
+!MESSAGE "lame - Win32 Release NASM" (basierend auf "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "lame - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\output\Release"
+# PROP Intermediate_Dir "..\obj\Release\frontend"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /O2 /Ob2 /I ".." /I "../mpglib" /I "../libmp3lame" /I "../include" /I "../" /D "NDEBUG" /D "WIN32" /D "_WIN32" /D "_CONSOLE" /D "_WINDOWS" /D "HAVE_MPGLIB" /D "HAVE_CONFIG_H" /YX /FD /c
+# ADD BASE RSC /l 0x40c /d "NDEBUG"
+# ADD RSC /l 0x40c /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"..\output\Release\lame.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "lame - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "\output\Debug"
+# PROP Intermediate_Dir "..\obj\Debug\frontend"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /ZI /Od /I "../" /I "../mpglib" /I "../libmp3lame" /I "../include" /D "_DEBUG" /D "WIN32" /D "_WIN32" /D "_CONSOLE" /D "_WINDOWS" /D "HAVE_MPGLIB" /D "HAVE_CONFIG_H" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x40c /d "_DEBUG"
+# ADD RSC /l 0x40c /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\output\Debug\lame.exe" /pdbtype:sept /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "lame - Win32 Release NASM"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "lame___Win32_Release_NASM"
+# PROP BASE Intermediate_Dir "lame___Win32_Release_NASM"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\output\Release_NASM"
+# PROP Intermediate_Dir "..\obj\Release_NASM\frontend"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /O2 /Ob2 /I ".." /I "../mpglib" /I "../libmp3lame" /I "../include" /I "../" /D "NDEBUG" /D "WIN32" /D "_WIN32" /D "_CONSOLE" /D "_WINDOWS" /D "HAVE_MPGLIB" /D "HAVE_CONFIG_H" /YX /FD /c
+# ADD CPP /nologo /W3 /O2 /Ob2 /I ".." /I "../mpglib" /I "../libmp3lame" /I "../include" /I "../" /D "NDEBUG" /D "WIN32" /D "_WIN32" /D "_CONSOLE" /D "_WINDOWS" /D "HAVE_MPGLIB" /D "HAVE_CONFIG_H" /D "HAVE_NASM" /D "MMX_choose_table" /YX /FD /c
+# ADD BASE RSC /l 0x40c /d "NDEBUG"
+# ADD RSC /l 0x40c /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../output/lame.exe"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"..\output\Release_NASM\lame.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "lame - Win32 Release"
+# Name "lame - Win32 Debug"
+# Name "lame - Win32 Release NASM"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\brhist.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\console.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\get_audio.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lametime.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\parse.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\portableio.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\timestatus.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\brhist.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\console.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\get_audio.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\lametime.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\parse.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\portableio.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\timestatus.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/lib/liblame/frontend/lame_vc8.vcproj b/lib/liblame/frontend/lame_vc8.vcproj
new file mode 100644
index 0000000000..f3d223805b
--- /dev/null
+++ b/lib/liblame/frontend/lame_vc8.vcproj
@@ -0,0 +1,552 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="lame_vc8"
+ ProjectGUID="{A5BC73DF-E8BB-45D5-984E-A209170D40BB}"
+ RootNamespace="lame_vc8"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../;../include;../libmp3lame"
+ PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_DEBUG;WIN32;_WIN32;_CONSOLE;_WINDOWS;HAVE_MPGLIB;HAVE_CONFIG_H"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="../output/lame.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../;../include;../libmp3lame"
+ PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_DEBUG;WIN32;_WIN32;_CONSOLE;_WINDOWS;HAVE_MPGLIB;HAVE_CONFIG_H"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="../output/lame.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../;../include;../libmp3lame"
+ PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;NDEBUG;WIN32;_WIN32;_CONSOLE;_WINDOWS;HAVE_MPGLIB;HAVE_CONFIG_H"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="../output/lame.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../;../include;../libmp3lame"
+ PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;NDEBUG;WIN32;_WIN32;_CONSOLE;_WINDOWS;HAVE_MPGLIB;HAVE_CONFIG_H"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="../output/lame.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug GTK|Win32"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug GTK|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../;../include;../libmp3lame"
+ PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_DEBUG;WIN32;_WIN32;_CONSOLE;_WINDOWS;HAVE_MPGLIB;HAVE_CONFIG_H"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="../output/lame.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\brhist.c"
+ >
+ </File>
+ <File
+ RelativePath=".\console.c"
+ >
+ </File>
+ <File
+ RelativePath=".\get_audio.c"
+ >
+ </File>
+ <File
+ RelativePath=".\lametime.c"
+ >
+ </File>
+ <File
+ RelativePath=".\main.c"
+ >
+ </File>
+ <File
+ RelativePath=".\parse.c"
+ >
+ </File>
+ <File
+ RelativePath=".\portableio.c"
+ >
+ </File>
+ <File
+ RelativePath=".\timestatus.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\brhist.h"
+ >
+ </File>
+ <File
+ RelativePath=".\console.h"
+ >
+ </File>
+ <File
+ RelativePath=".\get_audio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\lametime.h"
+ >
+ </File>
+ <File
+ RelativePath=".\main.h"
+ >
+ </File>
+ <File
+ RelativePath=".\parse.h"
+ >
+ </File>
+ <File
+ RelativePath=".\portableio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\timestatus.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/lib/liblame/frontend/lametime.c b/lib/liblame/frontend/lametime.c
new file mode 100644
index 0000000000..7cde228c4e
--- /dev/null
+++ b/lib/liblame/frontend/lametime.c
@@ -0,0 +1,169 @@
+/*
+ * Lame time routines source file
+ *
+ * Copyright (c) 2000 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: lametime.c,v 1.18.8.1 2009/01/18 15:44:28 robert Exp $ */
+
+/*
+ * name: GetCPUTime ( void )
+ *
+ * description: returns CPU time used by the process
+ * input: none
+ * output: time in seconds
+ * known bugs: may not work in SMP and RPC
+ * conforming: ANSI C
+ *
+ * There is some old difficult to read code at the end of this file.
+ * Can someone integrate this into this function (if useful)?
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdio.h>
+#include <time.h>
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+#include "lametime.h"
+
+#if !defined(CLOCKS_PER_SEC)
+# warning Your system does not define CLOCKS_PER_SEC, guessing one...
+# define CLOCKS_PER_SEC 1000000
+#endif
+
+
+double
+GetCPUTime(void)
+{
+ clock_t t;
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+ t = clock();
+#else
+ t = clock();
+#endif
+ return t / (double) CLOCKS_PER_SEC;
+}
+
+
+/*
+ * name: GetRealTime ( void )
+ *
+ * description: returns real (human) time elapsed relative to a fixed time (mostly 1970-01-01 00:00:00)
+ * input: none
+ * output: time in seconds
+ * known bugs: bad precision with time()
+ */
+
+#if defined(__unix__) || defined(SVR4) || defined(BSD)
+
+# include <sys/time.h>
+# include <unistd.h>
+
+double
+GetRealTime(void)
+{ /* conforming: SVr4, BSD 4.3 */
+ struct timeval t;
+
+ if (0 != gettimeofday(&t, NULL))
+ assert(0);
+ return t.tv_sec + 1.e-6 * t.tv_usec;
+}
+
+#elif defined(WIN16) || defined(WIN32)
+
+# include <stdio.h>
+# include <sys/types.h>
+# include <sys/timeb.h>
+
+double
+GetRealTime(void)
+{ /* conforming: Win 95, Win NT */
+ struct timeb t;
+
+ ftime(&t);
+ return t.time + 1.e-3 * t.millitm;
+}
+
+#else
+
+double
+GetRealTime(void)
+{ /* conforming: SVr4, SVID, POSIX, X/OPEN, BSD 4.3 */ /* BUT NOT GUARANTEED BY ANSI */
+ time_t t;
+
+ t = time(NULL);
+ return (double) t;
+}
+
+#endif
+
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+# include <io.h>
+# include <fcntl.h>
+#else
+# include <unistd.h>
+#endif
+
+int
+lame_set_stream_binary_mode(FILE * const fp)
+{
+#if defined __EMX__
+ _fsetmode(fp, "b");
+#elif defined __BORLANDC__
+ setmode(_fileno(fp), O_BINARY);
+#elif defined __CYGWIN__
+ setmode(fileno(fp), _O_BINARY);
+#elif defined _WIN32
+ _setmode(_fileno(fp), _O_BINARY);
+#else
+ (void) fp; /* doing nothing here, silencing the compiler only. */
+#endif
+ return 0;
+}
+
+
+#if defined(__riscos__)
+# include <kernel.h>
+# include <sys/swis.h>
+#elif defined(_WIN32)
+# include <sys/types.h>
+# include <sys/stat.h>
+#else
+# include <sys/stat.h>
+#endif
+
+off_t
+lame_get_file_size(const char *const filename)
+{
+ struct stat sb;
+
+ if (0 == stat(filename, &sb))
+ return sb.st_size;
+ return (off_t) - 1;
+}
+
+/* End of lametime.c */
diff --git a/lib/liblame/frontend/lametime.h b/lib/liblame/frontend/lametime.h
new file mode 100644
index 0000000000..cd416b1723
--- /dev/null
+++ b/lib/liblame/frontend/lametime.h
@@ -0,0 +1,34 @@
+/*
+ * Lame time routines include file
+ *
+ * Copyright (c) 2000 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_LAMETIME_H
+#define LAME_LAMETIME_H
+
+#include <sys/types.h>
+#include "lame.h"
+
+extern double GetCPUTime(void);
+extern double GetRealTime(void);
+
+extern int lame_set_stream_binary_mode(FILE * const fp);
+extern off_t lame_get_file_size(const char *const filename);
+
+#endif /* LAME_LAMETIME_H */
diff --git a/lib/liblame/frontend/main.c b/lib/liblame/frontend/main.c
new file mode 100644
index 0000000000..b8ce4036c2
--- /dev/null
+++ b/lib/liblame/frontend/main.c
@@ -0,0 +1,864 @@
+/*
+ * Command line frontend program
+ *
+ * Copyright (c) 1999 Mark Taylor
+ * 2000 Takehiro TOMINAGA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: main.c,v 1.107.2.1 2009/01/18 15:44:28 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdio.h>
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else
+# ifndef HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+char *strchr(), *strrchr();
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# define memmove(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#ifdef __sun__
+/* woraround for SunOS 4.x, it has SEEK_* defined here */
+#include <unistd.h>
+#endif
+
+#if defined(_WIN32)
+# include <windows.h>
+#endif
+
+
+/*
+ main.c is example code for how to use libmp3lame.a. To use this library,
+ you only need the library and lame.h. All other .h files are private
+ to the library.
+*/
+#include "lame.h"
+
+#include "console.h"
+#include "brhist.h"
+#include "parse.h"
+#include "main.h"
+#include "get_audio.h"
+#include "portableio.h"
+#include "timestatus.h"
+
+/* PLL 14/04/2000 */
+#if macintosh
+#include <console.h>
+#endif
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+
+
+
+/************************************************************************
+*
+* main
+*
+* PURPOSE: MPEG-1,2 Layer III encoder with GPSYCHO
+* psychoacoustic model.
+*
+************************************************************************/
+
+static int
+parse_args_from_string(lame_global_flags * const gfp, const char *p, char *inPath, char *outPath)
+{ /* Quick & very Dirty */
+ char *q;
+ char *f;
+ char *r[128];
+ int c = 0;
+ int ret;
+
+ if (p == NULL || *p == '\0')
+ return 0;
+
+ f = q = malloc(strlen(p) + 1);
+ strcpy(q, p);
+
+ r[c++] = "lhama";
+ while (1) {
+ r[c++] = q;
+ while (*q != ' ' && *q != '\0')
+ q++;
+ if (*q == '\0')
+ break;
+ *q++ = '\0';
+ }
+ r[c] = NULL;
+
+ ret = parse_args(gfp, c, r, inPath, outPath, NULL, NULL);
+ free(f);
+ return ret;
+}
+
+
+
+
+
+static FILE *
+init_files(lame_global_flags * gf, char *inPath, char *outPath, int *enc_delay, int *enc_padding)
+{
+ FILE *outf;
+ /* Mostly it is not useful to use the same input and output name.
+ This test is very easy and buggy and don't recognize different names
+ assigning the same file
+ */
+ if (0 != strcmp("-", outPath) && 0 == strcmp(inPath, outPath)) {
+ error_printf("Input file and Output file are the same. Abort.\n");
+ return NULL;
+ }
+
+ /* open the wav/aiff/raw pcm or mp3 input file. This call will
+ * open the file, try to parse the headers and
+ * set gf.samplerate, gf.num_channels, gf.num_samples.
+ * if you want to do your own file input, skip this call and set
+ * samplerate, num_channels and num_samples yourself.
+ */
+ init_infile(gf, inPath, enc_delay, enc_padding);
+ if ((outf = init_outfile(outPath, lame_get_decode_only(gf))) == NULL) {
+ error_printf("Can't init outfile '%s'\n", outPath);
+ return NULL;
+ }
+
+ return outf;
+}
+
+
+
+
+
+
+/* the simple lame decoder */
+/* After calling lame_init(), lame_init_params() and
+ * init_infile(), call this routine to read the input MP3 file
+ * and output .wav data to the specified file pointer*/
+/* lame_decoder will ignore the first 528 samples, since these samples
+ * represent the mpglib delay (and are all 0). skip = number of additional
+ * samples to skip, to (for example) compensate for the encoder delay */
+
+int
+lame_decoder(lame_global_flags * gfp, FILE * outf, int skip_start, char *inPath, char *outPath,
+ int *enc_delay, int *enc_padding)
+{
+ short int Buffer[2][1152];
+ int iread;
+ int skip_end = 0;
+ double wavsize;
+ int i;
+ void (*WriteFunction) (FILE * fp, char *p, int n);
+ int tmp_num_channels = lame_get_num_channels(gfp);
+
+
+
+ if (silent < 10)
+ console_printf("\rinput: %s%s(%g kHz, %i channel%s, ",
+ strcmp(inPath, "-") ? inPath : "<stdin>",
+ strlen(inPath) > 26 ? "\n\t" : " ",
+ lame_get_in_samplerate(gfp) / 1.e3,
+ tmp_num_channels, tmp_num_channels != 1 ? "s" : "");
+
+ switch (input_format) {
+ case sf_mp123: /* FIXME: !!! */
+ error_printf("Internal error. Aborting.");
+ exit(-1);
+
+ case sf_mp3:
+ if (skip_start == 0) {
+ if (*enc_delay > -1 || *enc_padding > -1) {
+ if (*enc_delay > -1)
+ skip_start = *enc_delay + 528 + 1;
+ if (*enc_padding > -1)
+ skip_end = *enc_padding - (528 + 1);
+ }
+ else
+ skip_start = lame_get_encoder_delay(gfp) + 528 + 1;
+ }
+ else {
+ /* user specified a value of skip. just add for decoder */
+ skip_start += 528 + 1; /* mp3 decoder has a 528 sample delay, plus user supplied "skip" */
+ }
+
+ if (silent < 10)
+ console_printf("MPEG-%u%s Layer %s", 2 - lame_get_version(gfp),
+ lame_get_out_samplerate(gfp) < 16000 ? ".5" : "", "III");
+ break;
+ case sf_mp2:
+ skip_start += 240 + 1;
+ if (silent < 10)
+ console_printf("MPEG-%u%s Layer %s", 2 - lame_get_version(gfp),
+ lame_get_out_samplerate(gfp) < 16000 ? ".5" : "", "II");
+ break;
+ case sf_mp1:
+ skip_start += 240 + 1;
+ if (silent < 10)
+ console_printf("MPEG-%u%s Layer %s", 2 - lame_get_version(gfp),
+ lame_get_out_samplerate(gfp) < 16000 ? ".5" : "", "I");
+ break;
+ case sf_raw:
+ if (silent < 10)
+ console_printf("raw PCM data");
+ mp3input_data.nsamp = lame_get_num_samples(gfp);
+ mp3input_data.framesize = 1152;
+ skip_start = 0; /* other formats have no delay */ /* is += 0 not better ??? */
+ break;
+ case sf_wave:
+ if (silent < 10)
+ console_printf("Microsoft WAVE");
+ mp3input_data.nsamp = lame_get_num_samples(gfp);
+ mp3input_data.framesize = 1152;
+ skip_start = 0; /* other formats have no delay */ /* is += 0 not better ??? */
+ break;
+ case sf_aiff:
+ if (silent < 10)
+ console_printf("SGI/Apple AIFF");
+ mp3input_data.nsamp = lame_get_num_samples(gfp);
+ mp3input_data.framesize = 1152;
+ skip_start = 0; /* other formats have no delay */ /* is += 0 not better ??? */
+ break;
+ default:
+ if (silent < 10)
+ console_printf("unknown");
+ mp3input_data.nsamp = lame_get_num_samples(gfp);
+ mp3input_data.framesize = 1152;
+ skip_start = 0; /* other formats have no delay */ /* is += 0 not better ??? */
+ assert(0);
+ break;
+ }
+
+ if (silent < 10) {
+ console_printf(")\noutput: %s%s(16 bit, Microsoft WAVE)\n",
+ strcmp(outPath, "-") ? outPath : "<stdout>",
+ strlen(outPath) > 45 ? "\n\t" : " ");
+
+ if (skip_start > 0)
+ console_printf("skipping initial %i samples (encoder+decoder delay)\n", skip_start);
+ if (skip_end > 0)
+ console_printf("skipping final %i samples (encoder padding-decoder delay)\n", skip_end);
+ }
+
+ if (0 == disable_wav_header)
+ WriteWaveHeader(outf, 0x7FFFFFFF, lame_get_in_samplerate(gfp), tmp_num_channels, 16);
+ /* unknown size, so write maximum 32 bit signed value */
+
+ wavsize = -(skip_start + skip_end);
+ WriteFunction = swapbytes ? WriteBytesSwapped : WriteBytes;
+ mp3input_data.totalframes = mp3input_data.nsamp / mp3input_data.framesize;
+
+ assert(tmp_num_channels >= 1 && tmp_num_channels <= 2);
+
+ do {
+ iread = get_audio16(gfp, Buffer); /* read in 'iread' samples */
+ if (iread >= 0) {
+ mp3input_data.framenum += iread / mp3input_data.framesize;
+ wavsize += iread;
+
+ if (silent <= 0) {
+ decoder_progress(&mp3input_data);
+ console_flush();
+ }
+
+ skip_start -= (i = skip_start < iread ? skip_start : iread); /* 'i' samples are to skip in this frame */
+
+ if (skip_end > 1152 && mp3input_data.framenum + 2 > mp3input_data.totalframes) {
+ iread -= (skip_end - 1152);
+ skip_end = 1152;
+ }
+ else if (mp3input_data.framenum == mp3input_data.totalframes && iread != 0)
+ iread -= skip_end;
+
+ for (; i < iread; i++) {
+ if (disable_wav_header) {
+ WriteFunction(outf, (char *) &Buffer[0][i], sizeof(short));
+ if (tmp_num_channels == 2)
+ WriteFunction(outf, (char *) &Buffer[1][i], sizeof(short));
+ }
+ else {
+ Write16BitsLowHigh(outf, Buffer[0][i]);
+ if (tmp_num_channels == 2)
+ Write16BitsLowHigh(outf, Buffer[1][i]);
+ }
+ }
+ if (flush_write == 1) {
+ fflush(outf);
+ }
+ }
+ } while (iread > 0);
+
+ i = (16 / 8) * tmp_num_channels;
+ assert(i > 0);
+ if (wavsize <= 0) {
+ if (silent < 10)
+ error_printf("WAVE file contains 0 PCM samples\n");
+ wavsize = 0;
+ }
+ else if (wavsize > 0xFFFFFFD0 / i) {
+ if (silent < 10)
+ error_printf("Very huge WAVE file, can't set filesize accordingly\n");
+ wavsize = 0xFFFFFFD0;
+ }
+ else {
+ wavsize *= i;
+ }
+
+ /* if outf is seekable, rewind and adjust length */
+ if (!disable_wav_header && strcmp("-", outPath)
+ && !fseek(outf, 0l, SEEK_SET))
+ WriteWaveHeader(outf, (int) wavsize, lame_get_in_samplerate(gfp),
+ tmp_num_channels, 16);
+ fclose(outf);
+
+ if (silent <= 0)
+ decoder_progress_finish();
+ return 0;
+}
+
+
+
+static void
+print_lame_tag_leading_info(lame_global_flags * gf)
+{
+ if (lame_get_bWriteVbrTag(gf))
+ console_printf("Writing LAME Tag...");
+}
+
+static void
+print_trailing_info(lame_global_flags * gf)
+{
+ if (lame_get_bWriteVbrTag(gf))
+ console_printf("done\n");
+
+ if (lame_get_findReplayGain(gf)) {
+ int RadioGain = lame_get_RadioGain(gf);
+ console_printf("ReplayGain: %s%.1fdB\n", RadioGain > 0 ? "+" : "",
+ ((float) RadioGain) / 10.0);
+ if (RadioGain > 0x1FE || RadioGain < -0x1FE)
+ error_printf
+ ("WARNING: ReplayGain exceeds the -51dB to +51dB range. Such a result is too\n"
+ " high to be stored in the header.\n");
+ }
+
+ /* if (the user requested printing info about clipping) and (decoding
+ on the fly has actually been performed) */
+ if (print_clipping_info && lame_get_decode_on_the_fly(gf)) {
+ float noclipGainChange = (float) lame_get_noclipGainChange(gf) / 10.0f;
+ float noclipScale = lame_get_noclipScale(gf);
+
+ if (noclipGainChange > 0.0) { /* clipping occurs */
+ console_printf
+ ("WARNING: clipping occurs at the current gain. Set your decoder to decrease\n"
+ " the gain by at least %.1fdB or encode again ", noclipGainChange);
+
+ /* advice the user on the scale factor */
+ if (noclipScale > 0) {
+ console_printf("using --scale %.2f\n", noclipScale);
+ console_printf(" or less (the value under --scale is approximate).\n");
+ }
+ else {
+ /* the user specified his own scale factor. We could suggest
+ * the scale factor of (32767.0/gfp->PeakSample)*(gfp->scale)
+ * but it's usually very inaccurate. So we'd rather advice him to
+ * disable scaling first and see our suggestion on the scale factor then. */
+ console_printf("using --scale <arg>\n"
+ " (For a suggestion on the optimal value of <arg> encode\n"
+ " with --scale 1 first)\n");
+ }
+
+ }
+ else { /* no clipping */
+ if (noclipGainChange > -0.1)
+ console_printf
+ ("\nThe waveform does not clip and is less than 0.1dB away from full scale.\n");
+ else
+ console_printf
+ ("\nThe waveform does not clip and is at least %.1fdB away from full scale.\n",
+ -noclipGainChange);
+ }
+ }
+
+}
+
+
+
+
+static int
+write_xing_frame(lame_global_flags * gf, FILE * outf)
+{
+ unsigned char mp3buffer[LAME_MAXMP3BUFFER];
+ size_t imp3, owrite;
+
+ imp3 = lame_get_lametag_frame(gf, mp3buffer, sizeof(mp3buffer));
+ if (imp3 > sizeof(mp3buffer)) {
+ error_printf("Error writing LAME-tag frame: buffer too small: buffer size=%d frame size=%d\n"
+ , sizeof(mp3buffer)
+ , imp3
+ );
+ return -1;
+ }
+ if (imp3 <= 0) {
+ return 0;
+ }
+ owrite = (int) fwrite(mp3buffer, 1, imp3, outf);
+ if (owrite != imp3) {
+ error_printf("Error writing LAME-tag \n");
+ return -1;
+ }
+ if (flush_write == 1) {
+ fflush(outf);
+ }
+ return imp3;
+}
+
+
+
+static int
+lame_encoder(lame_global_flags * gf, FILE * outf, int nogap, char *inPath, char *outPath)
+{
+ unsigned char mp3buffer[LAME_MAXMP3BUFFER];
+ int Buffer[2][1152];
+ int iread, imp3, owrite, id3v2_size;
+
+ encoder_progress_begin(gf, inPath, outPath);
+
+ imp3 = lame_get_id3v2_tag(gf, mp3buffer, sizeof(mp3buffer));
+ if ((size_t)imp3 > sizeof(mp3buffer)) {
+ encoder_progress_end(gf);
+ error_printf("Error writing ID3v2 tag: buffer too small: buffer size=%d ID3v2 size=%d\n"
+ , sizeof(mp3buffer)
+ , imp3
+ );
+ return 1;
+ }
+ owrite = (int) fwrite(mp3buffer, 1, imp3, outf);
+ if (owrite != imp3) {
+ encoder_progress_end(gf);
+ error_printf("Error writing ID3v2 tag \n");
+ return 1;
+ }
+ if (flush_write == 1) {
+ fflush(outf);
+ }
+ id3v2_size = imp3;
+
+ /* encode until we hit eof */
+ do {
+ /* read in 'iread' samples */
+ iread = get_audio(gf, Buffer);
+
+ if (iread >= 0) {
+ encoder_progress(gf);
+
+ /* encode */
+ imp3 = lame_encode_buffer_int(gf, Buffer[0], Buffer[1], iread,
+ mp3buffer, sizeof(mp3buffer));
+
+ /* was our output buffer big enough? */
+ if (imp3 < 0) {
+ if (imp3 == -1)
+ error_printf("mp3 buffer is not big enough... \n");
+ else
+ error_printf("mp3 internal error: error code=%i\n", imp3);
+ return 1;
+ }
+ owrite = (int) fwrite(mp3buffer, 1, imp3, outf);
+ if (owrite != imp3) {
+ error_printf("Error writing mp3 output \n");
+ return 1;
+ }
+ }
+ if (flush_write == 1) {
+ fflush(outf);
+ }
+ } while (iread > 0);
+
+ if (nogap)
+ imp3 = lame_encode_flush_nogap(gf, mp3buffer, sizeof(mp3buffer)); /* may return one more mp3 frame */
+ else
+ imp3 = lame_encode_flush(gf, mp3buffer, sizeof(mp3buffer)); /* may return one more mp3 frame */
+
+ if (imp3 < 0) {
+ if (imp3 == -1)
+ error_printf("mp3 buffer is not big enough... \n");
+ else
+ error_printf("mp3 internal error: error code=%i\n", imp3);
+ return 1;
+
+ }
+
+ encoder_progress_end(gf);
+
+ owrite = (int) fwrite(mp3buffer, 1, imp3, outf);
+ if (owrite != imp3) {
+ error_printf("Error writing mp3 output \n");
+ return 1;
+ }
+ if (flush_write == 1) {
+ fflush(outf);
+ }
+
+
+ imp3 = lame_get_id3v1_tag(gf, mp3buffer, sizeof(mp3buffer));
+ if ((size_t)imp3 > sizeof(mp3buffer)) {
+ error_printf("Error writing ID3v1 tag: buffer too small: buffer size=%d ID3v1 size=%d\n"
+ , sizeof(mp3buffer)
+ , imp3
+ );
+ }
+ else {
+ if (imp3 > 0) {
+ owrite = (int) fwrite(mp3buffer, 1, imp3, outf);
+ if (owrite != imp3) {
+ error_printf("Error writing ID3v1 tag \n");
+ return 1;
+ }
+ if (flush_write == 1) {
+ fflush(outf);
+ }
+ }
+ }
+
+ if (silent <= 0) {
+ print_lame_tag_leading_info(gf);
+ }
+ if (fseek(outf, id3v2_size, SEEK_SET) != 0) {
+ error_printf("fatal error: can't update LAME-tag frame!\n");
+ }
+ else {
+ write_xing_frame(gf, outf);
+ }
+
+ if (silent <= 0) {
+ print_trailing_info(gf);
+ }
+ return 0;
+}
+
+
+
+
+
+
+static void
+brhist_init_package(lame_global_flags * gf)
+{
+#ifdef BRHIST
+ if (brhist) {
+ if (brhist_init(gf, lame_get_VBR_min_bitrate_kbps(gf), lame_get_VBR_max_bitrate_kbps(gf))) {
+ /* fail to initialize */
+ brhist = 0;
+ }
+ }
+ else {
+ brhist_init(gf, 128, 128); /* Dirty hack */
+ }
+#endif
+}
+
+
+
+static
+ void
+parse_nogap_filenames(int nogapout, char *inPath, char *outPath, char *outdir)
+{
+
+ char *slasher;
+ size_t n;
+
+ strcpy(outPath, outdir);
+ if (!nogapout) {
+ strncpy(outPath, inPath, PATH_MAX + 1 - 4);
+ n = strlen(outPath);
+ /* nuke old extension, if one */
+ if (outPath[n - 3] == 'w'
+ && outPath[n - 2] == 'a' && outPath[n - 1] == 'v' && outPath[n - 4] == '.') {
+ outPath[n - 3] = 'm';
+ outPath[n - 2] = 'p';
+ outPath[n - 1] = '3';
+ }
+ else {
+ outPath[n + 0] = '.';
+ outPath[n + 1] = 'm';
+ outPath[n + 2] = 'p';
+ outPath[n + 3] = '3';
+ outPath[n + 4] = 0;
+ }
+ }
+ else {
+ slasher = inPath;
+ slasher += PATH_MAX + 1 - 4;
+
+ /* backseek to last dir delemiter */
+ while (*slasher != '/' && *slasher != '\\' && slasher != inPath && *slasher != ':') {
+ slasher--;
+ }
+
+ /* skip one foward if needed */
+ if (slasher != inPath
+ && (outPath[strlen(outPath) - 1] == '/'
+ || outPath[strlen(outPath) - 1] == '\\' || outPath[strlen(outPath) - 1] == ':'))
+ slasher++;
+ else if (slasher == inPath
+ && (outPath[strlen(outPath) - 1] != '/'
+ &&
+ outPath[strlen(outPath) - 1] != '\\' && outPath[strlen(outPath) - 1] != ':'))
+#ifdef _WIN32
+ strcat(outPath, "\\");
+#elif __OS2__
+ strcat(outPath, "\\");
+#else
+ strcat(outPath, "/");
+#endif
+
+ strncat(outPath, slasher, PATH_MAX + 1 - 4);
+ n = strlen(outPath);
+ /* nuke old extension */
+ if (outPath[n - 3] == 'w'
+ && outPath[n - 2] == 'a' && outPath[n - 1] == 'v' && outPath[n - 4] == '.') {
+ outPath[n - 3] = 'm';
+ outPath[n - 2] = 'p';
+ outPath[n - 1] = '3';
+ }
+ else {
+ outPath[n + 0] = '.';
+ outPath[n + 1] = 'm';
+ outPath[n + 2] = 'p';
+ outPath[n + 3] = '3';
+ outPath[n + 4] = 0;
+ }
+ }
+}
+
+
+
+
+/***********************************************************************
+*
+* Message Output
+*
+***********************************************************************/
+
+
+int
+main(int argc, char **argv)
+{
+ int ret;
+ lame_global_flags *gf;
+ char outPath[PATH_MAX + 1];
+ char nogapdir[PATH_MAX + 1];
+ char inPath[PATH_MAX + 1];
+
+ /* add variables for encoder delay/padding */
+ int enc_delay = -1;
+ int enc_padding = -1;
+
+ /* support for "nogap" encoding of up to 200 .wav files */
+#define MAX_NOGAP 200
+ int nogapout = 0;
+ int max_nogap = MAX_NOGAP;
+ char nogap_inPath_[MAX_NOGAP][PATH_MAX+1];
+ char* nogap_inPath[MAX_NOGAP];
+
+ int i;
+ FILE *outf;
+
+#if macintosh
+ argc = ccommand(&argv);
+#endif
+#if 0
+ /* rh 061207
+ the following fix seems to be a workaround for a problem in the
+ parent process calling LAME. It would be better to fix the broken
+ application => code disabled.
+ */
+#if defined(_WIN32)
+ /* set affinity back to all CPUs. Fix for EAC/lame on SMP systems from
+ "Todd Richmond" <todd.richmond@openwave.com> */
+ typedef BOOL(WINAPI * SPAMFunc) (HANDLE, DWORD_PTR);
+ SPAMFunc func;
+ SYSTEM_INFO si;
+
+ if ((func = (SPAMFunc) GetProcAddress(GetModuleHandleW(L"KERNEL32.DLL"),
+ "SetProcessAffinityMask")) != NULL) {
+ GetSystemInfo(&si);
+ func(GetCurrentProcess(), si.dwActiveProcessorMask);
+ }
+#endif
+#endif
+
+#ifdef __EMX__
+ /* This gives wildcard expansion on Non-POSIX shells with OS/2 */
+ _wildcard(&argc, &argv);
+#endif
+
+ memset(nogap_inPath_, 0, sizeof(nogap_inPath_));
+ for (i = 0; i < MAX_NOGAP; ++i) {
+ nogap_inPath[i] = &nogap_inPath_[i][0];
+ }
+
+ memset(inPath, 0, sizeof(inPath));
+
+ frontend_open_console();
+
+ /* initialize libmp3lame */
+ input_format = sf_unknown;
+ if (NULL == (gf = lame_init())) {
+ error_printf("fatal error during initialization\n");
+ frontend_close_console();
+ return 1;
+ }
+ lame_set_errorf(gf, &frontend_errorf);
+ lame_set_debugf(gf, &frontend_debugf);
+ lame_set_msgf(gf, &frontend_msgf);
+ if (argc <= 1) {
+ usage(stderr, argv[0]); /* no command-line args, print usage, exit */
+ lame_close(gf);
+ frontend_close_console();
+ return 1;
+ }
+
+ /* parse the command line arguments, setting various flags in the
+ * struct 'gf'. If you want to parse your own arguments,
+ * or call libmp3lame from a program which uses a GUI to set arguments,
+ * skip this call and set the values of interest in the gf struct.
+ * (see the file API and lame.h for documentation about these parameters)
+ */
+ parse_args_from_string(gf, getenv("LAMEOPT"), inPath, outPath);
+ ret = parse_args(gf, argc, argv, inPath, outPath, nogap_inPath, &max_nogap);
+ if (ret < 0) {
+ lame_close(gf);
+ frontend_close_console();
+ return ret == -2 ? 0 : 1;
+ }
+ if (update_interval < 0.)
+ update_interval = 2.;
+
+ if (outPath[0] != '\0' && max_nogap > 0) {
+ strncpy(nogapdir, outPath, PATH_MAX + 1);
+ nogapout = 1;
+ }
+
+ /* initialize input file. This also sets samplerate and as much
+ other data on the input file as available in the headers */
+ if (max_nogap > 0) {
+ /* for nogap encoding of multiple input files, it is not possible to
+ * specify the output file name, only an optional output directory. */
+ parse_nogap_filenames(nogapout, nogap_inPath[0], outPath, nogapdir);
+ outf = init_files(gf, nogap_inPath[0], outPath, &enc_delay, &enc_padding);
+ }
+ else {
+ outf = init_files(gf, inPath, outPath, &enc_delay, &enc_padding);
+ }
+ if (outf == NULL) {
+ lame_close(gf);
+ frontend_close_console();
+ return -1;
+ }
+ /* turn off automatic writing of ID3 tag data into mp3 stream
+ * we have to call it before 'lame_init_params', because that
+ * function would spit out ID3v2 tag data.
+ */
+ lame_set_write_id3tag_automatic(gf, 0);
+
+ /* Now that all the options are set, lame needs to analyze them and
+ * set some more internal options and check for problems
+ */
+ i = lame_init_params(gf);
+ if (i < 0) {
+ if (i == -1) {
+ display_bitrates(stderr);
+ }
+ error_printf("fatal error during initialization\n");
+ lame_close(gf);
+ frontend_close_console();
+ return i;
+ }
+
+ if (silent > 0) {
+ brhist = 0; /* turn off VBR histogram */
+ }
+
+
+ if (lame_get_decode_only(gf)) {
+ /* decode an mp3 file to a .wav */
+ if (mp3_delay_set)
+ lame_decoder(gf, outf, mp3_delay, inPath, outPath, &enc_delay, &enc_padding);
+ else
+ lame_decoder(gf, outf, 0, inPath, outPath, &enc_delay, &enc_padding);
+
+ }
+ else {
+ if (max_nogap > 0) {
+ /*
+ * encode multiple input files using nogap option
+ */
+ for (i = 0; i < max_nogap; ++i) {
+ int use_flush_nogap = (i != (max_nogap - 1));
+ if (i > 0) {
+ parse_nogap_filenames(nogapout, nogap_inPath[i], outPath, nogapdir);
+ /* note: if init_files changes anything, like
+ samplerate, num_channels, etc, we are screwed */
+ outf = init_files(gf, nogap_inPath[i], outPath, &enc_delay, &enc_padding);
+ /* reinitialize bitstream for next encoding. this is normally done
+ * by lame_init_params(), but we cannot call that routine twice */
+ lame_init_bitstream(gf);
+ }
+ brhist_init_package(gf);
+ lame_set_nogap_total(gf, max_nogap);
+ lame_set_nogap_currentindex(gf, i);
+
+ ret = lame_encoder(gf, outf, use_flush_nogap, nogap_inPath[i], outPath);
+
+ fclose(outf); /* close the output file */
+ close_infile(); /* close the input file */
+
+ }
+ }
+ else {
+ /*
+ * encode a single input file
+ */
+ brhist_init_package(gf);
+
+ ret = lame_encoder(gf, outf, 0, inPath, outPath);
+
+ fclose(outf); /* close the output file */
+ close_infile(); /* close the input file */
+ }
+ }
+ lame_close(gf);
+ frontend_close_console();
+ return ret;
+}
diff --git a/lib/liblame/frontend/main.h b/lib/liblame/frontend/main.h
new file mode 100644
index 0000000000..f7186a934b
--- /dev/null
+++ b/lib/liblame/frontend/main.h
@@ -0,0 +1,58 @@
+/*
+ * Command line frontend program
+ *
+ * Copyright (c) 1999 Mark Taylor
+ * 2000 Takehiro TOMIANGA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#include "get_audio.h"
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+
+/* GLOBAL VARIABLES used by parse.c and main.c.
+ instantiated in parce.c. ugly, ugly */
+extern sound_file_format input_format;
+extern int swapbytes; /* force byte swapping default=0 */
+extern int silent;
+extern int brhist;
+
+extern int mp3_delay; /* for decoder only */
+extern int mp3_delay_set; /* for decoder only */
+extern float update_interval; /* to use Frank's time status display */
+extern int disable_wav_header; /* for decoder only */
+extern mp3data_struct mp3input_data; /* used by MP3 */
+extern int print_clipping_info; /* print info whether waveform clips */
+extern int in_signed;
+extern int in_unsigned;
+extern int in_bitwidth;
+extern int flush_write;
+
+#define Min(A, B) ((A) < (B) ? (A) : (B))
+#define Max(A, B) ((A) > (B) ? (A) : (B))
+
+
+enum ByteOrder { ByteOrderLittleEndian, ByteOrderBigEndian };
+extern enum ByteOrder in_endian;
diff --git a/lib/liblame/frontend/mp3rtp.c b/lib/liblame/frontend/mp3rtp.c
new file mode 100644
index 0000000000..a755f4ced1
--- /dev/null
+++ b/lib/liblame/frontend/mp3rtp.c
@@ -0,0 +1,278 @@
+/* $Id: mp3rtp.c,v 1.25.8.1 2008/08/05 14:16:06 robert Exp $ */
+
+/* Still under work ..., need a client for test, where can I get one? */
+
+/*
+ * experimental translation:
+ *
+ * gcc -I..\include -I..\libmp3lame -o mp3rtp mp3rtp.c ../libmp3lame/libmp3lame.a lametime.c get_audio.c portableio.c ieeefloat.c timestatus.c parse.c rtp.c -lm
+ *
+ * wavrec -t 14400 -s 44100 -S /proc/self/fd/1 | ./mp3rtp 10.1.1.42 -V2 -b128 -B256 - my_mp3file.mp3
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else
+# ifndef HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+char *strchr(), *strrchr();
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# define memmove(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#include <time.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include "lame.h"
+#include "main.h"
+#include "parse.h"
+#include "lametime.h"
+#include "timestatus.h"
+#include "get_audio.h"
+#include "rtp.h"
+#include "console.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+/*
+ * Encode (via LAME) to mp3 with RTP streaming of the output.
+ *
+ * Author: Felix von Leitner <leitner@vim.org>
+ *
+ * mp3rtp ip[:port[:ttl]] [lame encoding options] infile outfile
+ *
+ * examples:
+ * arecord -b 16 -s 22050 -w | ./mp3rtp 224.17.23.42:5004:2 -b 56 - /dev/null
+ * arecord -b 16 -s 44100 -w | ./mp3rtp 10.1.1.42 -V2 -b128 -B256 - my_mp3file.mp3
+ *
+ */
+
+struct rtpheader RTPheader;
+struct sockaddr_in rtpsi;
+int rtpsocket;
+
+void
+rtp_output(const char *mp3buffer, const int mp3size)
+{
+ sendrtp(rtpsocket, &rtpsi, &RTPheader, mp3buffer, mp3size);
+ RTPheader.timestamp += 5;
+ RTPheader.b.sequence++;
+}
+
+#if 0
+struct rtpheader RTPheader;
+SOCKET rtpsocket;
+
+void
+rtp_output(char *mp3buffer, int mp3size)
+{
+ rtp_send(rtpsocket, &RTPheader, mp3buffer, mp3size);
+ RTPheader.timestamp += 5;
+ RTPheader.b.sequence++;
+}
+#endif
+
+
+
+
+static unsigned int
+maxvalue(int Buffer[2][1152])
+{
+ unsigned int max = 0;
+ int i;
+
+ for (i = 0; i < 1152; i++) {
+ if (abs(Buffer[0][i]) > max)
+ max = abs(Buffer[0][i]);
+ if (abs(Buffer[1][i]) > max)
+ max = abs(Buffer[1][i]);
+ }
+ return max >> 16;
+}
+
+static void
+levelmessage(unsigned int maxv)
+{
+ char buff[] = "| . | . | . | . | . | . | . | . | . | . | \r";
+ static unsigned int max = 0;
+ static unsigned int tmp = 0;
+
+ buff[tmp] = '+';
+ tmp = (maxv * 61 + 16384) / (32767 + 16384 / 61);
+ if (tmp > sizeof(buff) - 2)
+ tmp = sizeof(buff) - 2;
+ if (max < tmp)
+ max = tmp;
+ buff[max] = 'x';
+ buff[tmp] = '#';
+ console_printf(buff);
+ console_flush();
+}
+
+
+/************************************************************************
+*
+* main
+*
+* PURPOSE: MPEG-1,2 Layer III encoder with GPSYCHO
+* psychoacoustic model.
+*
+************************************************************************/
+
+int
+main(int argc, char **argv)
+{
+ unsigned char mp3buffer[LAME_MAXMP3BUFFER];
+ char inPath[PATH_MAX + 1];
+ char outPath[PATH_MAX + 1];
+ int Buffer[2][1152];
+
+ lame_global_flags *gf;
+
+ int ret;
+ int wavsamples;
+ int mp3bytes;
+ FILE *outf;
+
+ char ip[16];
+ unsigned port = 5004;
+ unsigned ttl = 2;
+ char dummy;
+
+ int enc_delay = -1;
+ int enc_padding = -1;
+
+ frontend_open_console();
+ if (argc <= 2) {
+ console_printf("Encode (via LAME) to mp3 with RTP streaming of the output\n"
+ "\n"
+ " mp3rtp ip[:port[:ttl]] [lame encoding options] infile outfile\n"
+ "\n"
+ " examples:\n"
+ " arecord -b 16 -s 22050 -w | ./mp3rtp 224.17.23.42:5004:2 -b 56 - /dev/null\n"
+ " arecord -b 16 -s 44100 -w | ./mp3rtp 10.1.1.42 -V2 -b128 -B256 - my_mp3file.mp3\n"
+ "\n");
+ frontend_close_console();
+ return 1;
+ }
+
+ switch (sscanf(argv[1], "%11[.0-9]:%u:%u%c", ip, &port, &ttl, &dummy)) {
+ case 1:
+ case 2:
+ case 3:
+ break;
+ default:
+ error_printf("Illegal destination selector '%s', must be ip[:port[:ttl]]\n", argv[1]);
+ frontend_close_console();
+ return -1;
+ }
+
+ rtpsocket = makesocket(ip, port, ttl, &rtpsi);
+ srand(getpid() ^ time(NULL));
+ initrtp(&RTPheader);
+
+ /* initialize encoder */
+ gf = lame_init();
+ if (NULL == gf) {
+ error_printf("fatal error during initialization\n");
+ frontend_close_console();
+ return 1;
+ }
+ lame_set_errorf(gf, &frontend_errorf);
+ lame_set_debugf(gf, &frontend_debugf);
+ lame_set_msgf(gf, &frontend_msgf);
+
+ /* Remove the argumets that are rtp related, and then
+ * parse the command line arguments, setting various flags in the
+ * struct pointed to by 'gf'. If you want to parse your own arguments,
+ * or call libmp3lame from a program which uses a GUI to set arguments,
+ * skip this call and set the values of interest in the gf struct.
+ * (see lame.h for documentation about these parameters)
+ */
+
+ argv[1] = argv[0];
+ parse_args(gf, argc - 1, argv + 1, inPath, outPath, NULL, NULL);
+
+ /* open the output file. Filename parsed into gf.inPath */
+ if (0 == strcmp(outPath, "-")) {
+ lame_set_stream_binary_mode(outf = stdout);
+ }
+ else {
+ if ((outf = fopen(outPath, "wb+")) == NULL) {
+ error_printf("Could not create \"%s\".\n", outPath);
+ frontend_close_console();
+ return 1;
+ }
+ }
+
+
+ /* open the wav/aiff/raw pcm or mp3 input file. This call will
+ * open the file with name gf.inFile, try to parse the headers and
+ * set gf.samplerate, gf.num_channels, gf.num_samples.
+ * if you want to do your own file input, skip this call and set
+ * these values yourself.
+ */
+ init_infile(gf, inPath, &enc_delay, &enc_padding);
+
+
+ /* Now that all the options are set, lame needs to analyze them and
+ * set some more options
+ */
+ ret = lame_init_params(gf);
+ if (ret < 0) {
+ if (ret == -1)
+ display_bitrates(stderr);
+ error_printf("fatal error during initialization\n");
+ frontend_close_console();
+ return -1;
+ }
+
+ lame_print_config(gf); /* print useful information about options being used */
+
+ if (update_interval < 0.)
+ update_interval = 2.;
+
+ /* encode until we hit EOF */
+ while ((wavsamples = get_audio(gf, Buffer)) > 0) { /* read in 'wavsamples' samples */
+ levelmessage(maxvalue(Buffer));
+ mp3bytes = lame_encode_buffer_int(gf, /* encode the frame */
+ Buffer[0], Buffer[1], wavsamples,
+ mp3buffer, sizeof(mp3buffer));
+
+ rtp_output(mp3buffer, mp3bytes); /* write MP3 output to RTP port */
+ fwrite(mp3buffer, 1, mp3bytes, outf); /* write the MP3 output to file */
+ }
+
+ mp3bytes = lame_encode_flush(gf, /* may return one or more mp3 frame */
+ mp3buffer, sizeof(mp3buffer));
+ rtp_output(mp3buffer, mp3bytes); /* write MP3 output to RTP port */
+ fwrite(mp3buffer, 1, mp3bytes, outf); /* write the MP3 output to file */
+
+ lame_mp3_tags_fid(gf, outf); /* add VBR tags to mp3 file */
+
+ lame_close(gf);
+ fclose(outf);
+ close_infile(); /* close the sound input file */
+ frontend_close_console();
+ return 0;
+}
+
+/* end of mp3rtp.c */
diff --git a/lib/liblame/frontend/mp3x.c b/lib/liblame/frontend/mp3x.c
new file mode 100644
index 0000000000..d849ef3a7f
--- /dev/null
+++ b/lib/liblame/frontend/mp3x.c
@@ -0,0 +1,80 @@
+/* $Id: mp3x.c,v 1.25 2008/03/09 17:13:23 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "lame-analysis.h"
+#include <gtk/gtk.h>
+#include "parse.h"
+#include "get_audio.h"
+#include "gtkanal.h"
+#include "lametime.h"
+
+#include "main.h"
+#include "console.h"
+
+
+
+
+
+/************************************************************************
+*
+* main
+*
+* PURPOSE: MPEG-1,2 Layer III encoder with GPSYCHO
+* psychoacoustic model.
+*
+************************************************************************/
+int
+main(int argc, char **argv)
+{
+ char mp3buffer[LAME_MAXMP3BUFFER];
+ lame_global_flags *gf;
+ char outPath[PATH_MAX + 1];
+ char inPath[PATH_MAX + 1];
+ int ret;
+ int enc_delay = -1;
+ int enc_padding = -1;
+
+ frontend_open_console();
+ gf = lame_init();
+ if (NULL == gf) {
+ error_printf("fatal error during initialization\n");
+ frontend_close_console();
+ return 1;
+ }
+ lame_set_errorf(gf, &frontend_errorf);
+ lame_set_debugf(gf, &frontend_debugf);
+ lame_set_msgf(gf, &frontend_msgf);
+ if (argc <= 1) {
+ usage(stderr, argv[0]); /* no command-line args */
+ frontend_close_console();
+ return -1;
+ }
+ ret = parse_args(gf, argc, argv, inPath, outPath, NULL, NULL);
+ if (ret < 0) {
+ frontend_close_console();
+ return ret == -2 ? 0 : 1;
+ }
+ (void) lame_set_analysis(gf, 1);
+
+ init_infile(gf, inPath, &enc_delay, &enc_padding);
+ lame_init_params(gf);
+ lame_print_config(gf);
+
+
+ gtk_init(&argc, &argv);
+ gtkcontrol(gf, inPath);
+
+ lame_encode_flush(gf, mp3buffer, sizeof(mp3buffer));
+ lame_close(gf);
+ close_infile();
+ frontend_close_console();
+ return 0;
+}
diff --git a/lib/liblame/frontend/mp3x_vc6.dsp b/lib/liblame/frontend/mp3x_vc6.dsp
new file mode 100644
index 0000000000..10f054c966
--- /dev/null
+++ b/lib/liblame/frontend/mp3x_vc6.dsp
@@ -0,0 +1,181 @@
+# Microsoft Developer Studio Project File - Name="MP3x" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=MP3x - Win32 Debug
+!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
+!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
+!MESSAGE
+!MESSAGE NMAKE /f "mp3x_vc6.mak".
+!MESSAGE
+!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
+!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
+!MESSAGE
+!MESSAGE NMAKE /f "mp3x_vc6.mak" CFG="MP3x - Win32 Debug"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "MP3x - Win32 Debug" (basierend auf "Win32 (x86) Console Application")
+!MESSAGE "MP3x - Win32 Release" (basierend auf "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "MP3x - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "MP3x___Win32_Debug"
+# PROP BASE Intermediate_Dir "MP3x___Win32_Debug"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\output\Debug"
+# PROP Intermediate_Dir "..\obj\Debug\frontend"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /I "./WinGtk/src/gtk+" /I "./WinGtk/src/glib" /I "./WinGtk/src/gtk+/gdk" /I "../include" /I "../libmp3lame" /I "../mp3x" /I "../frontend" /I ".." /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "HAVE_MPGLIB" /D "LAMESNDFILE" /D "BRHIST" /D "HAVE_CONFIG_H" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /W3 /Gm /ZI /Od /I "./WinGtk/src/gtk+" /I "./WinGtk/src/glib" /I "./WinGtk/src/gtk+/gdk" /I "../include" /I "../libmp3lame" /I "../mp3x" /I "../frontend" /I ".." /D "_MBCS" /D "LAMESNDFILE" /D "BRHIST" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "HAVE_MPGLIB" /D "HAVE_CONFIG_H" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 glib-2.0.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib gdk.lib gtk.lib /nologo /subsystem:console /debug /machine:I386 /out:"../output/mp3x.exe" /pdbtype:sept /libpath:"./WinGtk/src/gtk+/gtk" /libpath:"./WinGtk/src/gtk+/gdk" /libpath:"./WinGtk/src/glib"
+# ADD LINK32 glib-2.0.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib gdk.lib gtk.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\output\Debug\mp3x.exe" /pdbtype:sept /libpath:"./WinGtk/src/gtk+/gtk" /libpath:"./WinGtk/src/gtk+/gdk" /libpath:"./WinGtk/src/glib" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "MP3x - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "MP3x___Win32_Release"
+# PROP BASE Intermediate_Dir "MP3x___Win32_Release"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\output\Release"
+# PROP Intermediate_Dir "..\obj\Release\frontend"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /O2 /I "./WinGTK/gtk-plus" /I "./WinGTK/glib-1.2" /I "./WinGtk/src/gtk+" /I "./WinGtk/src/glib" /I "./WinGtk/src/gtk+/gdk" /I "../include" /I "../libmp3lame" /I "../mp3x" /I "../frontend" /I ".." /D "NDEBUG" /D "LAMEPARSE" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "HAVE_MPGLIB" /D "LAMESNDFILE" /D "BRHIST" /D "HAVE_CONFIG_H" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /W3 /O2 /I "./WinGTK/gtk-plus" /I "./WinGTK/glib-1.2" /I "./WinGtk/src/gtk+" /I "./WinGtk/src/glib" /I "./WinGtk/src/gtk+/gdk" /I "../include" /I "../libmp3lame" /I "../mp3x" /I "../frontend" /I ".." /D "NDEBUG" /D "LAMEPARSE" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "HAVE_MPGLIB" /D "LAMESNDFILE" /D "BRHIST" /D "HAVE_CONFIG_H" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 glib-1.3.lib glib-2.0.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib gdk.lib gtk.lib /nologo /subsystem:console /profile /map /machine:I386 /out:"../output/mp3x.exe" /libpath:"./WinGtk/src/gtk+/gtk" /libpath:"./WinGtk/src/gtk+/gdk" /libpath:"./WinGtk/src/glib"
+# ADD LINK32 glib-2.0.lib glib-2.0.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib gdk.lib gtk.lib /nologo /subsystem:console /profile /map /machine:I386 /out:"..\output\Release\mp3x.exe" /libpath:"./WinGtk/src/gtk+/gtk" /libpath:"./WinGtk/src/gtk+/gdk" /libpath:"./WinGtk/src/glib" /opt:NOWIN98
+
+!ENDIF
+
+# Begin Target
+
+# Name "MP3x - Win32 Debug"
+# Name "MP3x - Win32 Release"
+# Begin Group "Source"
+
+# PROP Default_Filter "c"
+# Begin Source File
+
+SOURCE=..\frontend\brhist.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\frontend\console.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\frontend\get_audio.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\gpkplotting.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\gtkanal.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\frontend\lametime.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mp3x.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\frontend\parse.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\frontend\portableio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\frontend\timestatus.c
+# End Source File
+# End Group
+# Begin Group "Include"
+
+# PROP Default_Filter "h"
+# Begin Source File
+
+SOURCE=..\frontend\brhist.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\configMS.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\frontend\console.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\frontend\get_audio.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\gpkplotting.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\frontend\lametime.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\frontend\parse.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\frontend\portableio.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\frontend\timestatus.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\README.WINGTK
+# End Source File
+# End Target
+# End Project
diff --git a/lib/liblame/frontend/parse.c b/lib/liblame/frontend/parse.c
new file mode 100644
index 0000000000..2c6a10c523
--- /dev/null
+++ b/lib/liblame/frontend/parse.c
@@ -0,0 +1,2341 @@
+/*
+ * Command line parsing related functions
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: parse.c,v 1.247.2.8 2009/12/11 22:44:25 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <ctype.h>
+
+#ifdef STDC_HEADERS
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+#else
+# ifndef HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+char *strchr(), *strrchr();
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# define memmove(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#ifdef __OS2__
+#include <os2.h>
+#define PRTYC_IDLE 1
+#define PRTYC_REGULAR 2
+#define PRTYD_MINIMUM -31
+#define PRTYD_MAXIMUM 31
+#endif
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#include "lame.h"
+#include "set_get.h"
+
+#include "brhist.h"
+#include "parse.h"
+#include "main.h"
+#include "get_audio.h"
+#include "version.h"
+#include "console.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+
+#ifdef HAVE_ICONV
+#include <iconv.h>
+#include <errno.h>
+#endif
+
+#if defined DEBUG || _DEBUG || _ALLOW_INTERNAL_OPTIONS
+#define INTERNAL_OPTS 1
+#else
+#define INTERNAL_OPTS LAME_ALPHA_VERSION
+#endif
+
+#if (INTERNAL_OPTS!=0)
+#define DEV_HELP(a) a
+#else
+#define DEV_HELP(a)
+#endif
+
+
+
+/* GLOBAL VARIABLES. set by parse_args() */
+/* we need to clean this up */
+sound_file_format input_format;
+int swapbytes = 0; /* force byte swapping default=0 */
+int silent; /* Verbosity */
+int ignore_tag_errors; /* Ignore errors in values passed for tags */
+int brhist;
+float update_interval; /* to use Frank's time status display */
+int mp3_delay; /* to adjust the number of samples truncated
+ during decode */
+int mp3_delay_set; /* user specified the value of the mp3 encoder
+ delay to assume for decoding */
+
+int disable_wav_header;
+mp3data_struct mp3input_data; /* used by MP3 */
+int print_clipping_info; /* print info whether waveform clips */
+
+
+int in_signed = -1;
+
+enum ByteOrder in_endian = ByteOrderLittleEndian;
+
+int in_bitwidth = 16;
+
+int flush_write = 0;
+
+
+
+/**
+ * Long Filename support for the WIN32 platform
+ *
+ */
+#ifdef WIN32
+#include <winbase.h>
+static void
+dosToLongFileName(char *fn)
+{
+ const int MSIZE = PATH_MAX + 1 - 4; /* we wanna add ".mp3" later */
+ WIN32_FIND_DATAA lpFindFileData;
+ HANDLE h = FindFirstFileA(fn, &lpFindFileData);
+ if (h != INVALID_HANDLE_VALUE) {
+ int a;
+ char *q, *p;
+ FindClose(h);
+ for (a = 0; a < MSIZE; a++) {
+ if ('\0' == lpFindFileData.cFileName[a])
+ break;
+ }
+ if (a >= MSIZE || a == 0)
+ return;
+ q = strrchr(fn, '\\');
+ p = strrchr(fn, '/');
+ if (p - q > 0)
+ q = p;
+ if (q == NULL)
+ q = strrchr(fn, ':');
+ if (q == NULL)
+ strncpy(fn, lpFindFileData.cFileName, a);
+ else {
+ a += q - fn + 1;
+ if (a >= MSIZE)
+ return;
+ strncpy(++q, lpFindFileData.cFileName, MSIZE - a);
+ }
+ }
+}
+#endif
+#if defined(WIN32)
+#include <windows.h>
+BOOL
+SetPriorityClassMacro(DWORD p)
+{
+ HANDLE op = GetCurrentProcess();
+ return SetPriorityClass(op, p);
+}
+
+static void
+setWin32Priority(lame_global_flags * gfp, int Priority)
+{
+ switch (Priority) {
+ case 0:
+ case 1:
+ SetPriorityClassMacro(IDLE_PRIORITY_CLASS);
+ console_printf("==> Priority set to Low.\n");
+ break;
+ default:
+ case 2:
+ SetPriorityClassMacro(NORMAL_PRIORITY_CLASS);
+ console_printf("==> Priority set to Normal.\n");
+ break;
+ case 3:
+ case 4:
+ SetPriorityClassMacro(HIGH_PRIORITY_CLASS);
+ console_printf("==> Priority set to High.\n");
+ break;
+ }
+}
+#endif
+
+
+#if defined(__OS2__)
+/* OS/2 priority functions */
+static int
+setOS2Priority(lame_global_flags * gfp, int Priority)
+{
+ int rc;
+
+ switch (Priority) {
+
+ case 0:
+ rc = DosSetPriority(0, /* Scope: only one process */
+ PRTYC_IDLE, /* select priority class (idle, regular, etc) */
+ 0, /* set delta */
+ 0); /* Assume current process */
+ console_printf("==> Priority set to 0 (Low priority).\n");
+ break;
+
+ case 1:
+ rc = DosSetPriority(0, /* Scope: only one process */
+ PRTYC_IDLE, /* select priority class (idle, regular, etc) */
+ PRTYD_MAXIMUM, /* set delta */
+ 0); /* Assume current process */
+ console_printf("==> Priority set to 1 (Medium priority).\n");
+ break;
+
+ case 2:
+ rc = DosSetPriority(0, /* Scope: only one process */
+ PRTYC_REGULAR, /* select priority class (idle, regular, etc) */
+ PRTYD_MINIMUM, /* set delta */
+ 0); /* Assume current process */
+ console_printf("==> Priority set to 2 (Regular priority).\n");
+ break;
+
+ case 3:
+ rc = DosSetPriority(0, /* Scope: only one process */
+ PRTYC_REGULAR, /* select priority class (idle, regular, etc) */
+ 0, /* set delta */
+ 0); /* Assume current process */
+ console_printf("==> Priority set to 3 (High priority).\n");
+ break;
+
+ case 4:
+ rc = DosSetPriority(0, /* Scope: only one process */
+ PRTYC_REGULAR, /* select priority class (idle, regular, etc) */
+ PRTYD_MAXIMUM, /* set delta */
+ 0); /* Assume current process */
+ console_printf("==> Priority set to 4 (Maximum priority). I hope you enjoy it :)\n");
+ break;
+
+ default:
+ console_printf("==> Invalid priority specified! Assuming idle priority.\n");
+ }
+
+
+ return 0;
+}
+#endif
+
+
+extern int
+id3tag_set_textinfo_ucs2(lame_global_flags* gfp, char const* id, unsigned short const* text);
+
+extern int
+id3tag_set_comment_ucs2(lame_global_flags* gfp, char const* lng, unsigned short const* desc, unsigned short const* text);
+
+/* possible text encodings */
+typedef enum TextEncoding
+{ TENC_RAW /* bytes will be stored as-is into ID3 tags, which are Latin1/UCS2 per definition */
+, TENC_LATIN1 /* text will be converted from local encoding to Latin1, as ID3 needs it */
+, TENC_UCS2 /* text will be converted from local encoding to UCS-2, as ID3v2 wants it */
+} TextEncoding;
+
+#ifdef HAVE_ICONV
+
+/* search for Zero termination in multi-byte strings */
+static size_t
+strlenMultiByte(char const* str, size_t w)
+{
+ size_t n = 0;
+ if (str != 0) {
+ size_t i, x = 0;
+ for (n = 0; ; ++n) {
+ x = 0;
+ for (i = 0; i < w; ++i) {
+ x += *str++ == 0 ? 1 : 0;
+ }
+ if (x == w) {
+ break;
+ }
+ }
+ }
+ return n;
+}
+
+
+static size_t
+currCharCodeSize(void)
+{
+ size_t n = 1;
+ char dst[32];
+ char* src = "A";
+ char* env_lang = getenv("LANG");
+ char* xxx_code = env_lang == NULL ? NULL : strrchr(env_lang, '.');
+ char* cur_code = xxx_code == NULL ? "" : xxx_code+1;
+ iconv_t xiconv = iconv_open(cur_code, "ISO_8859-1");
+ if (xiconv != (iconv_t)-1) {
+ for (n = 0; n < 32; ++n) {
+ char* i_ptr = src;
+ char* o_ptr = dst;
+ size_t srcln = 1;
+ size_t avail = n;
+ size_t rc = iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
+ if (rc != (size_t)-1) {
+ break;
+ }
+ }
+ iconv_close(xiconv);
+ }
+ return n;
+}
+
+#if 0
+static
+char* fromLatin1( char* src )
+{
+ char* dst = 0;
+ if (src != 0) {
+ size_t const l = strlen(src);
+ size_t const n = l*4;
+ dst = calloc(n+4, 4);
+ if (dst != 0) {
+ char* env_lang = getenv("LANG");
+ char* xxx_code = env_lang == NULL ? NULL : strrchr(env_lang, '.');
+ char* cur_code = xxx_code == NULL ? "" : xxx_code+1;
+ iconv_t xiconv = iconv_open(cur_code, "ISO_8859-1");
+ if (xiconv != (iconv_t)-1) {
+ char* i_ptr = src;
+ char* o_ptr = dst;
+ size_t srcln = l;
+ size_t avail = n;
+ iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
+ iconv_close(xiconv);
+ }
+ }
+ }
+ return dst;
+}
+
+static
+char* fromUcs2( char* src )
+{
+ char* dst = 0;
+ if (src != 0) {
+ size_t const l = strlenMultiByte(src, 2);
+ size_t const n = l*4;
+ dst = calloc(n+4, 4);
+ if (dst != 0) {
+ char* env_lang = getenv("LANG");
+ char* xxx_code = env_lang == NULL ? NULL : strrchr(env_lang, '.');
+ char* cur_code = xxx_code == NULL ? "" : xxx_code+1;
+ iconv_t xiconv = iconv_open(cur_code, "UCS-2LE");
+ if (xiconv != (iconv_t)-1) {
+ char* i_ptr = (char*)src;
+ char* o_ptr = dst;
+ size_t srcln = l*2;
+ size_t avail = n;
+ iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
+ iconv_close(xiconv);
+ }
+ }
+ }
+ return dst;
+}
+#endif
+
+static
+char* toLatin1( char* src )
+{
+ size_t w = currCharCodeSize();
+ char* dst = 0;
+ if (src != 0) {
+ size_t const l = strlenMultiByte(src, w);
+ size_t const n = l*4;
+ dst = calloc(n+4, 4);
+ if (dst != 0) {
+ char* env_lang = getenv("LANG");
+ char* xxx_code = env_lang == NULL ? NULL : strrchr(env_lang, '.');
+ char* cur_code = xxx_code == NULL ? "" : xxx_code+1;
+ iconv_t xiconv = iconv_open("ISO_8859-1", cur_code);
+ if (xiconv != (iconv_t)-1) {
+ char* i_ptr = (char*)src;
+ char* o_ptr = dst;
+ size_t srcln = l*w;
+ size_t avail = n;
+ iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
+ iconv_close(xiconv);
+ }
+ }
+ }
+ return dst;
+}
+
+
+static
+char* toUcs2( char* src )
+{
+ size_t w = currCharCodeSize();
+ char* dst = 0;
+ if (src != 0) {
+ size_t const l = strlenMultiByte(src, w);
+ size_t const n = (l+1)*4;
+ dst = calloc(n+4, 4);
+ if (dst != 0) {
+ char* env_lang = getenv("LANG");
+ char* xxx_code = env_lang == NULL ? NULL : strrchr(env_lang, '.');
+ char* cur_code = xxx_code == NULL ? "" : xxx_code+1;
+ iconv_t xiconv = iconv_open("UCS-2LE", cur_code);
+ dst[0] = 0xff;
+ dst[1] = 0xfe;
+ if (xiconv != (iconv_t)-1) {
+ char* i_ptr = (char*)src;
+ char* o_ptr = &dst[2];
+ size_t srcln = l*w;
+ size_t avail = n;
+ iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
+ iconv_close(xiconv);
+ }
+ }
+ }
+ return dst;
+}
+
+
+static int
+set_id3v2tag(lame_global_flags* gfp, int type, unsigned short const* str)
+{
+ switch (type)
+ {
+ case 'a': return id3tag_set_textinfo_ucs2(gfp, "TPE1", str);
+ case 't': return id3tag_set_textinfo_ucs2(gfp, "TIT2", str);
+ case 'l': return id3tag_set_textinfo_ucs2(gfp, "TALB", str);
+ case 'g': return id3tag_set_textinfo_ucs2(gfp, "TCON", str);
+ case 'c': return id3tag_set_comment_ucs2(gfp, 0, 0, str);
+ case 'n': return id3tag_set_textinfo_ucs2(gfp, "TRCK", str);
+ }
+ return 0;
+}
+#endif
+
+static int
+set_id3tag(lame_global_flags* gfp, int type, char const* str)
+{
+ switch (type)
+ {
+ case 'a': return id3tag_set_artist(gfp, str), 0;
+ case 't': return id3tag_set_title(gfp, str), 0;
+ case 'l': return id3tag_set_album(gfp, str), 0;
+ case 'g': return id3tag_set_genre(gfp, str);
+ case 'c': return id3tag_set_comment(gfp, str), 0;
+ case 'n': return id3tag_set_track(gfp, str);
+ case 'y': return id3tag_set_year(gfp, str), 0;
+ case 'v': return id3tag_set_fieldvalue(gfp, str);
+ }
+ return 0;
+}
+
+static int
+id3_tag(lame_global_flags* gfp, int type, TextEncoding enc, char* str)
+{
+ void* x = 0;
+ int result;
+ switch (enc)
+ {
+ default:
+ case TENC_RAW: x = strdup(str); break;
+#ifdef HAVE_ICONV
+ case TENC_LATIN1: x = toLatin1(str); break;
+ case TENC_UCS2: x = toUcs2(str); break;
+#endif
+ }
+ switch (enc)
+ {
+ default:
+ case TENC_RAW:
+ case TENC_LATIN1: result = set_id3tag(gfp, type, x); break;
+#ifdef HAVE_ICONV
+ case TENC_UCS2: result = set_id3v2tag(gfp, type, x); break;
+#endif
+ }
+ free(x);
+ return result;
+}
+
+
+
+
+/************************************************************************
+*
+* license
+*
+* PURPOSE: Writes version and license to the file specified by fp
+*
+************************************************************************/
+
+static int
+lame_version_print(FILE * const fp)
+{
+ const char *b = get_lame_os_bitness();
+ const char *v = get_lame_version();
+ const char *u = get_lame_url();
+ const size_t lenb = strlen(b);
+ const size_t lenv = strlen(v);
+ const size_t lenu = strlen(u);
+ const size_t lw = 80; /* line width of terminal in characters */
+ const size_t sw = 16; /* static width of text */
+
+ if (lw >= lenb + lenv + lenu + sw || lw < lenu + 2)
+ /* text fits in 80 chars per line, or line even too small for url */
+ if (lenb > 0)
+ fprintf(fp, "LAME %s version %s (%s)\n\n", b, v, u);
+ else
+ fprintf(fp, "LAME version %s (%s)\n\n", v, u);
+ else
+ /* text too long, wrap url into next line, right aligned */
+ if (lenb > 0)
+ fprintf(fp, "LAME %s version %s\n%*s(%s)\n\n", b, v, lw - 2 - lenu, "", u);
+ else
+ fprintf(fp, "LAME version %s\n%*s(%s)\n\n", v, lw - 2 - lenu, "", u);
+
+ if (LAME_ALPHA_VERSION)
+ fprintf(fp, "warning: alpha versions should be used for testing only\n\n");
+
+
+ return 0;
+}
+
+static int
+print_license(FILE * const fp)
+{ /* print version & license */
+ lame_version_print(fp);
+ fprintf(fp,
+ "Can I use LAME in my commercial program?\n"
+ "\n"
+ "Yes, you can, under the restrictions of the LGPL. In particular, you\n"
+ "can include a compiled version of the LAME library (for example,\n"
+ "lame.dll) with a commercial program. Some notable requirements of\n"
+ "the LGPL:\n" "\n");
+ fprintf(fp,
+ "1. In your program, you cannot include any source code from LAME, with\n"
+ " the exception of files whose only purpose is to describe the library\n"
+ " interface (such as lame.h).\n" "\n");
+ fprintf(fp,
+ "2. Any modifications of LAME must be released under the LGPL.\n"
+ " The LAME project (www.mp3dev.org) would appreciate being\n"
+ " notified of any modifications.\n" "\n");
+ fprintf(fp,
+ "3. You must give prominent notice that your program is:\n"
+ " A. using LAME (including version number)\n"
+ " B. LAME is under the LGPL\n"
+ " C. Provide a copy of the LGPL. (the file COPYING contains the LGPL)\n"
+ " D. Provide a copy of LAME source, or a pointer where the LAME\n"
+ " source can be obtained (such as www.mp3dev.org)\n"
+ " An example of prominent notice would be an \"About the LAME encoding engine\"\n"
+ " button in some pull down menu within the executable of your program.\n" "\n");
+ fprintf(fp,
+ "4. If you determine that distribution of LAME requires a patent license,\n"
+ " you must obtain such license.\n" "\n" "\n");
+ fprintf(fp,
+ "*** IMPORTANT NOTE ***\n"
+ "\n"
+ "The decoding functions provided in LAME use the mpglib decoding engine which\n"
+ "is under the GPL. They may not be used by any program not released under the\n"
+ "GPL unless you obtain such permission from the MPG123 project (www.mpg123.de).\n"
+ "\n");
+ return 0;
+}
+
+
+/************************************************************************
+*
+* usage
+*
+* PURPOSE: Writes command line syntax to the file specified by fp
+*
+************************************************************************/
+
+int
+usage(FILE * const fp, const char *ProgramName)
+{ /* print general syntax */
+ lame_version_print(fp);
+ fprintf(fp,
+ "usage: %s [options] <infile> [outfile]\n"
+ "\n"
+ " <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n"
+ "\n"
+ "Try:\n"
+ " \"%s --help\" for general usage information\n"
+ " or:\n"
+ " \"%s --preset help\" for information on suggested predefined settings\n"
+ " or:\n"
+ " \"%s --longhelp\"\n"
+ " or \"%s -?\" for a complete options list\n\n",
+ ProgramName, ProgramName, ProgramName, ProgramName, ProgramName);
+ return 0;
+}
+
+
+/************************************************************************
+*
+* usage
+*
+* PURPOSE: Writes command line syntax to the file specified by fp
+* but only the most important ones, to fit on a vt100 terminal
+*
+************************************************************************/
+
+int
+short_help(const lame_global_flags * gfp, FILE * const fp, const char *ProgramName)
+{ /* print short syntax help */
+ lame_version_print(fp);
+ fprintf(fp,
+ "usage: %s [options] <infile> [outfile]\n"
+ "\n"
+ " <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n"
+ "\n" "RECOMMENDED:\n" " lame -V2 input.wav output.mp3\n" "\n", ProgramName);
+ fprintf(fp,
+ "OPTIONS:\n"
+ " -b bitrate set the bitrate, default 128 kbps\n"
+ " -h higher quality, but a little slower. Recommended.\n"
+ " -f fast mode (lower quality)\n"
+ " -V n quality setting for VBR. default n=%i\n"
+ " 0=high quality,bigger files. 9=smaller files\n",
+ lame_get_VBR_q(gfp));
+ fprintf(fp,
+ " --preset type type must be \"medium\", \"standard\", \"extreme\", \"insane\",\n"
+ " or a value for an average desired bitrate and depending\n"
+ " on the value specified, appropriate quality settings will\n"
+ " be used.\n"
+ " \"--preset help\" gives more info on these\n" "\n");
+ fprintf(fp,
+#if defined(WIN32)
+ " --priority type sets the process priority\n"
+ " 0,1 = Low priority\n"
+ " 2 = normal priority\n"
+ " 3,4 = High priority\n" "\n"
+#endif
+#if defined(__OS2__)
+ " --priority type sets the process priority\n"
+ " 0 = Low priority\n"
+ " 1 = Medium priority\n"
+ " 2 = Regular priority\n"
+ " 3 = High priority\n"
+ " 4 = Maximum priority\n" "\n"
+#endif
+ " --longhelp full list of options\n" "\n"
+ " --license print License information\n\n"
+ );
+
+ return 0;
+}
+
+/************************************************************************
+*
+* usage
+*
+* PURPOSE: Writes command line syntax to the file specified by fp
+*
+************************************************************************/
+
+static void
+wait_for(FILE * const fp, int lessmode)
+{
+ if (lessmode) {
+ fflush(fp);
+ getchar();
+ }
+ else {
+ fprintf(fp, "\n");
+ }
+ fprintf(fp, "\n");
+}
+
+int
+long_help(const lame_global_flags * gfp, FILE * const fp, const char *ProgramName, int lessmode)
+{ /* print long syntax help */
+ lame_version_print(fp);
+ fprintf(fp,
+ "usage: %s [options] <infile> [outfile]\n"
+ "\n"
+ " <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n"
+ "\n" "RECOMMENDED:\n" " lame -V2 input.wav output.mp3\n" "\n", ProgramName);
+ fprintf(fp,
+ "OPTIONS:\n"
+ " Input options:\n"
+ " --scale <arg> scale input (multiply PCM data) by <arg>\n"
+ " --scale-l <arg> scale channel 0 (left) input (multiply PCM data) by <arg>\n"
+ " --scale-r <arg> scale channel 1 (right) input (multiply PCM data) by <arg>\n"
+#if (defined HAVE_MPGLIB || defined AMIGA_MPEGA)
+ " --mp1input input file is a MPEG Layer I file\n"
+ " --mp2input input file is a MPEG Layer II file\n"
+ " --mp3input input file is a MPEG Layer III file\n"
+#endif
+ " --nogap <file1> <file2> <...>\n"
+ " gapless encoding for a set of contiguous files\n"
+ " --nogapout <dir>\n"
+ " output dir for gapless encoding (must precede --nogap)\n"
+ " --nogaptags allow the use of VBR tags in gapless encoding\n"
+ );
+ fprintf(fp,
+ "\n"
+ " Input options for RAW PCM:\n"
+ " -r input is raw pcm\n"
+ " -x force byte-swapping of input\n"
+ " -s sfreq sampling frequency of input file (kHz) - default 44.1 kHz\n"
+ " --bitwidth w input bit width is w (default 16)\n"
+ " --signed input is signed (default)\n"
+ " --unsigned input is unsigned\n"
+ " --little-endian input is little-endian (default)\n"
+ " --big-endian input is big-endian\n"
+ );
+
+ wait_for(fp, lessmode);
+ fprintf(fp,
+ " Operational options:\n"
+ " -a downmix from stereo to mono file for mono encoding\n"
+ " -m <mode> (j)oint, (s)imple, (f)orce, (d)dual-mono, (m)ono\n"
+ " default is (j) or (s) depending on bitrate\n"
+ " joint = joins the best possible of MS and LR stereo\n"
+ " simple = force LR stereo on all frames\n"
+ " force = force MS stereo on all frames.\n"
+ " --preset type type must be \"medium\", \"standard\", \"extreme\", \"insane\",\n"
+ " or a value for an average desired bitrate and depending\n"
+ " on the value specified, appropriate quality settings will\n"
+ " be used.\n"
+ " \"--preset help\" gives more info on these\n"
+ " --comp <arg> choose bitrate to achive a compression ratio of <arg>\n");
+ fprintf(fp, " --replaygain-fast compute RG fast but slightly inaccurately (default)\n"
+#ifdef DECODE_ON_THE_FLY
+ " --replaygain-accurate compute RG more accurately and find the peak sample\n"
+#endif
+ " --noreplaygain disable ReplayGain analysis\n"
+#ifdef DECODE_ON_THE_FLY
+ " --clipdetect enable --replaygain-accurate and print a message whether\n"
+ " clipping occurs and how far the waveform is from full scale\n"
+#endif
+ );
+ fprintf(fp,
+ " --flush flush output stream as soon as possible\n"
+ " --freeformat produce a free format bitstream\n"
+ " --decode input=mp3 file, output=wav\n"
+ " -t disable writing wav header when using --decode\n");
+
+ wait_for(fp, lessmode);
+ fprintf(fp,
+ " Verbosity:\n"
+ " --disptime <arg>print progress report every arg seconds\n"
+ " -S don't print progress report, VBR histograms\n"
+ " --nohist disable VBR histogram display\n"
+ " --silent don't print anything on screen\n"
+ " --quiet don't print anything on screen\n"
+ " --brief print more useful information\n"
+ " --verbose print a lot of useful information\n" "\n");
+ fprintf(fp,
+ " Noise shaping & psycho acoustic algorithms:\n"
+ " -q <arg> <arg> = 0...9. Default -q 5 \n"
+ " -q 0: Highest quality, very slow \n"
+ " -q 9: Poor quality, but fast \n"
+ " -h Same as -q 2. Recommended.\n"
+ " -f Same as -q 7. Fast, ok quality\n");
+
+ wait_for(fp, lessmode);
+ fprintf(fp,
+ " CBR (constant bitrate, the default) options:\n"
+ " -b <bitrate> set the bitrate in kbps, default 128 kbps\n"
+ " --cbr enforce use of constant bitrate\n"
+ "\n"
+ " ABR options:\n"
+ " --abr <bitrate> specify average bitrate desired (instead of quality)\n" "\n");
+ fprintf(fp,
+ " VBR options:\n"
+ " -V n quality setting for VBR. default n=%i\n"
+ " 0=high quality,bigger files. 9=smaller files\n"
+ " -v the same as -V 4\n"
+ " --vbr-old use old variable bitrate (VBR) routine\n"
+ " --vbr-new use new variable bitrate (VBR) routine (default)\n"
+ ,
+ lame_get_VBR_q(gfp));
+ fprintf(fp,
+ " -b <bitrate> specify minimum allowed bitrate, default 32 kbps\n"
+ " -B <bitrate> specify maximum allowed bitrate, default 320 kbps\n"
+ " -F strictly enforce the -b option, for use with players that\n"
+ " do not support low bitrate mp3\n"
+ " -t disable writing LAME Tag\n"
+ " -T enable and force writing LAME Tag\n");
+
+ wait_for(fp, lessmode);
+ DEV_HELP(fprintf(fp,
+ " ATH related:\n"
+ " --noath turns ATH down to a flat noise floor\n"
+ " --athshort ignore GPSYCHO for short blocks, use ATH only\n"
+ " --athonly ignore GPSYCHO completely, use ATH only\n"
+ " --athtype n selects between different ATH types [0-4]\n"
+ " --athlower x lowers ATH by x dB\n");
+ fprintf(fp, " --athaa-type n ATH auto adjust: 0 'no' else 'loudness based'\n"
+/** OBSOLETE " --athaa-loudapprox n n=1 total energy or n=2 equal loudness curve\n"*/
+ " --athaa-sensitivity x activation offset in -/+ dB for ATH auto-adjustment\n"
+ "\n");
+ )
+ fprintf(fp,
+ " PSY related:\n"
+ DEV_HELP(
+ " --short use short blocks when appropriate\n"
+ " --noshort do not use short blocks\n"
+ " --allshort use only short blocks\n"
+ )
+ );
+ fprintf(fp,
+ " --temporal-masking x x=0 disables, x=1 enables temporal masking effect\n"
+ " --nssafejoint M/S switching criterion\n"
+ " --nsmsfix <arg> M/S switching tuning [effective 0-3.5]\n"
+ " --interch x adjust inter-channel masking ratio\n"
+ " --ns-bass x adjust masking for sfbs 0 - 6 (long) 0 - 5 (short)\n"
+ " --ns-alto x adjust masking for sfbs 7 - 13 (long) 6 - 10 (short)\n"
+ " --ns-treble x adjust masking for sfbs 14 - 21 (long) 11 - 12 (short)\n");
+ fprintf(fp,
+ " --ns-sfb21 x change ns-treble by x dB for sfb21\n"
+ DEV_HELP(" --shortthreshold x,y short block switching threshold,\n"
+ " x for L/R/M channel, y for S channel\n"
+ " Noise Shaping related:\n"
+ " --substep n use pseudo substep noise shaping method types 0-2\n")
+ );
+
+ wait_for(fp, lessmode);
+
+ fprintf(fp,
+ " experimental switches:\n"
+ DEV_HELP(
+ " -X n[,m] selects between different noise measurements\n"
+ " n for long block, m for short. if m is omitted, m = n\n"
+ )
+ " -Y lets LAME ignore noise in sfb21, like in CBR\n"
+ DEV_HELP(
+ " -Z [n] currently no effects\n"
+ )
+ );
+
+ wait_for(fp, lessmode);
+
+ fprintf(fp,
+ " MP3 header/stream options:\n"
+ " -e <emp> de-emphasis n/5/c (obsolete)\n"
+ " -c mark as copyright\n"
+ " -o mark as non-original\n"
+ " -p error protection. adds 16 bit checksum to every frame\n"
+ " (the checksum is computed correctly)\n"
+ " --nores disable the bit reservoir\n"
+ " --strictly-enforce-ISO comply as much as possible to ISO MPEG spec\n" "\n");
+ fprintf(fp,
+ " Filter options:\n"
+ " --lowpass <freq> frequency(kHz), lowpass filter cutoff above freq\n"
+ " --lowpass-width <freq> frequency(kHz) - default 15%% of lowpass freq\n"
+ " --highpass <freq> frequency(kHz), highpass filter cutoff below freq\n"
+ " --highpass-width <freq> frequency(kHz) - default 15%% of highpass freq\n");
+ fprintf(fp,
+ " --resample <sfreq> sampling frequency of output file(kHz)- default=automatic\n");
+
+ wait_for(fp, lessmode);
+ fprintf(fp,
+ " ID3 tag options:\n"
+ " --tt <title> audio/song title (max 30 chars for version 1 tag)\n"
+ " --ta <artist> audio/song artist (max 30 chars for version 1 tag)\n"
+ " --tl <album> audio/song album (max 30 chars for version 1 tag)\n"
+ " --ty <year> audio/song year of issue (1 to 9999)\n"
+ " --tc <comment> user-defined text (max 30 chars for v1 tag, 28 for v1.1)\n"
+ " --tn <track[/total]> audio/song track number and (optionally) the total\n"
+ " number of tracks on the original recording. (track\n"
+ " and total each 1 to 255. just the track number\n"
+ " creates v1.1 tag, providing a total forces v2.0).\n"
+ " --tg <genre> audio/song genre (name or number in list)\n"
+ " --ti <file> audio/song albumArt (jpeg/png/gif file, 128KB max, v2.3)\n"
+ " --tv <id=value> user-defined frame specified by id and value (v2.3 tag)\n");
+ fprintf(fp,
+ " --add-id3v2 force addition of version 2 tag\n"
+ " --id3v1-only add only a version 1 tag\n"
+ " --id3v2-only add only a version 2 tag\n"
+ " --space-id3v1 pad version 1 tag with spaces instead of nulls\n"
+ " --pad-id3v2 same as '--pad-id3v2-size 128'\n"
+ " --pad-id3v2-size <value> adds version 2 tag, pad with extra <value> bytes\n"
+ " --genre-list print alphabetically sorted ID3 genre list and exit\n"
+ " --ignore-tag-errors ignore errors in values passed for tags\n" "\n");
+ fprintf(fp,
+ " Note: A version 2 tag will NOT be added unless one of the input fields\n"
+ " won't fit in a version 1 tag (e.g. the title string is longer than 30\n"
+ " characters), or the '--add-id3v2' or '--id3v2-only' options are used,\n"
+ " or output is redirected to stdout.\n"
+#if defined(WIN32)
+ "\n\nMS-Windows-specific options:\n"
+ " --priority <type> sets the process priority:\n"
+ " 0,1 = Low priority (IDLE_PRIORITY_CLASS)\n"
+ " 2 = normal priority (NORMAL_PRIORITY_CLASS, default)\n"
+ " 3,4 = High priority (HIGH_PRIORITY_CLASS))\n"
+ " Note: Calling '--priority' without a parameter will select priority 0.\n"
+#endif
+#if defined(__OS2__)
+ "\n\nOS/2-specific options:\n"
+ " --priority <type> sets the process priority:\n"
+ " 0 = Low priority (IDLE, delta = 0)\n"
+ " 1 = Medium priority (IDLE, delta = +31)\n"
+ " 2 = Regular priority (REGULAR, delta = -31)\n"
+ " 3 = High priority (REGULAR, delta = 0)\n"
+ " 4 = Maximum priority (REGULAR, delta = +31)\n"
+ " Note: Calling '--priority' without a parameter will select priority 0.\n"
+#endif
+ "\nMisc:\n --license print License information\n\n"
+ );
+
+#if defined(HAVE_NASM)
+ wait_for(fp, lessmode);
+ fprintf(fp,
+ " Platform specific:\n"
+ " --noasm <instructions> disable assembly optimizations for mmx/3dnow/sse\n");
+ wait_for(fp, lessmode);
+#endif
+
+ display_bitrates(fp);
+
+ return 0;
+}
+
+static void
+display_bitrate(FILE * const fp, const char *const version, const int d, const int indx)
+{
+ int i;
+ int nBitrates = 14;
+ if (d == 4)
+ nBitrates = 8;
+
+
+ fprintf(fp,
+ "\nMPEG-%-3s layer III sample frequencies (kHz): %2d %2d %g\n"
+ "bitrates (kbps):", version, 32 / d, 48 / d, 44.1 / d);
+ for (i = 1; i <= nBitrates; i++)
+ fprintf(fp, " %2i", bitrate_table[indx][i]);
+ fprintf(fp, "\n");
+}
+
+int
+display_bitrates(FILE * const fp)
+{
+ display_bitrate(fp, "1", 1, 1);
+ display_bitrate(fp, "2", 2, 0);
+ display_bitrate(fp, "2.5", 4, 0);
+ fprintf(fp, "\n");
+ fflush(fp);
+ return 0;
+}
+
+
+/* note: for presets it would be better to externalize them in a file.
+ suggestion: lame --preset <file-name> ...
+ or: lame --preset my-setting ... and my-setting is defined in lame.ini
+ */
+
+/*
+Note from GB on 08/25/2002:
+I am merging --presets and --alt-presets. Old presets are now aliases for
+corresponding abr values from old alt-presets. This way we now have a
+unified preset system, and I hope than more people will use the new tuned
+presets instead of the old unmaintained ones.
+*/
+
+
+
+/************************************************************************
+*
+* usage
+*
+* PURPOSE: Writes presetting info to #stdout#
+*
+************************************************************************/
+
+
+static void
+presets_longinfo_dm(FILE * msgfp)
+{
+ fprintf(msgfp,
+ "\n"
+ "The --preset switches are aliases over LAME settings.\n"
+ "\n" "\n");
+ fprintf(msgfp,
+ "To activate these presets:\n"
+ "\n" " For VBR modes (generally highest quality):\n" "\n");
+ fprintf(msgfp,
+ " \"--preset medium\" This preset should provide near transparency\n"
+ " to most people on most music.\n"
+ "\n"
+ " \"--preset standard\" This preset should generally be transparent\n"
+ " to most people on most music and is already\n"
+ " quite high in quality.\n" "\n");
+ fprintf(msgfp,
+ " \"--preset extreme\" If you have extremely good hearing and similar\n"
+ " equipment, this preset will generally provide\n"
+ " slightly higher quality than the \"standard\"\n"
+ " mode.\n" "\n");
+ fprintf(msgfp,
+ " For CBR 320kbps (highest quality possible from the --preset switches):\n"
+ "\n"
+ " \"--preset insane\" This preset will usually be overkill for most\n"
+ " people and most situations, but if you must\n"
+ " have the absolute highest quality with no\n"
+ " regard to filesize, this is the way to go.\n" "\n");
+ fprintf(msgfp,
+ " For ABR modes (high quality per given bitrate but not as high as VBR):\n"
+ "\n"
+ " \"--preset <kbps>\" Using this preset will usually give you good\n"
+ " quality at a specified bitrate. Depending on the\n"
+ " bitrate entered, this preset will determine the\n");
+ fprintf(msgfp,
+ " optimal settings for that particular situation.\n"
+ " While this approach works, it is not nearly as\n"
+ " flexible as VBR, and usually will not attain the\n"
+ " same level of quality as VBR at higher bitrates.\n" "\n");
+ fprintf(msgfp,
+ "The following options are also available for the corresponding profiles:\n"
+ "\n"
+ " <fast> standard\n"
+ " <fast> extreme\n"
+ " insane\n"
+ " <cbr> (ABR Mode) - The ABR Mode is implied. To use it,\n"
+ " simply specify a bitrate. For example:\n"
+ " \"--preset 185\" activates this\n"
+ " preset and uses 185 as an average kbps.\n" "\n");
+ fprintf(msgfp,
+ " \"fast\" - Enables the fast VBR mode for a particular profile.\n" "\n");
+ fprintf(msgfp,
+ " \"cbr\" - If you use the ABR mode (read above) with a significant\n"
+ " bitrate such as 80, 96, 112, 128, 160, 192, 224, 256, 320,\n"
+ " you can use the \"cbr\" option to force CBR mode encoding\n"
+ " instead of the standard abr mode. ABR does provide higher\n"
+ " quality but CBR may be useful in situations such as when\n"
+ " streaming an mp3 over the internet may be important.\n" "\n");
+ fprintf(msgfp,
+ " For example:\n"
+ "\n"
+ " \"--preset fast standard <input file> <output file>\"\n"
+ " or \"--preset cbr 192 <input file> <output file>\"\n"
+ " or \"--preset 172 <input file> <output file>\"\n"
+ " or \"--preset extreme <input file> <output file>\"\n" "\n" "\n");
+ fprintf(msgfp,
+ "A few aliases are also available for ABR mode:\n"
+ "phone => 16kbps/mono phon+/lw/mw-eu/sw => 24kbps/mono\n"
+ "mw-us => 40kbps/mono voice => 56kbps/mono\n"
+ "fm/radio/tape => 112kbps hifi => 160kbps\n"
+ "cd => 192kbps studio => 256kbps\n");
+}
+
+
+extern void lame_set_msfix(lame_t gfp, double msfix);
+
+
+
+static int
+presets_set(lame_t gfp, int fast, int cbr, const char *preset_name, const char *ProgramName)
+{
+ int mono = 0;
+
+ if ((strcmp(preset_name, "help") == 0) && (fast < 1)
+ && (cbr < 1)) {
+ lame_version_print(stdout);
+ presets_longinfo_dm(stdout);
+ return -1;
+ }
+
+
+
+ /*aliases for compatibility with old presets */
+
+ if (strcmp(preset_name, "phone") == 0) {
+ preset_name = "16";
+ mono = 1;
+ }
+ if ((strcmp(preset_name, "phon+") == 0) ||
+ (strcmp(preset_name, "lw") == 0) ||
+ (strcmp(preset_name, "mw-eu") == 0) || (strcmp(preset_name, "sw") == 0)) {
+ preset_name = "24";
+ mono = 1;
+ }
+ if (strcmp(preset_name, "mw-us") == 0) {
+ preset_name = "40";
+ mono = 1;
+ }
+ if (strcmp(preset_name, "voice") == 0) {
+ preset_name = "56";
+ mono = 1;
+ }
+ if (strcmp(preset_name, "fm") == 0) {
+ preset_name = "112";
+ }
+ if ((strcmp(preset_name, "radio") == 0) || (strcmp(preset_name, "tape") == 0)) {
+ preset_name = "112";
+ }
+ if (strcmp(preset_name, "hifi") == 0) {
+ preset_name = "160";
+ }
+ if (strcmp(preset_name, "cd") == 0) {
+ preset_name = "192";
+ }
+ if (strcmp(preset_name, "studio") == 0) {
+ preset_name = "256";
+ }
+
+ if (strcmp(preset_name, "medium") == 0) {
+ lame_set_VBR_q(gfp, 4);
+ if (fast > 0) {
+ lame_set_VBR(gfp, vbr_mtrh);
+ }
+ else {
+ lame_set_VBR(gfp, vbr_rh);
+ }
+ return 0;
+ }
+
+ if (strcmp(preset_name, "standard") == 0) {
+ lame_set_VBR_q(gfp, 2);
+ if (fast > 0) {
+ lame_set_VBR(gfp, vbr_mtrh);
+ }
+ else {
+ lame_set_VBR(gfp, vbr_rh);
+ }
+ return 0;
+ }
+
+ else if (strcmp(preset_name, "extreme") == 0) {
+ lame_set_VBR_q(gfp, 0);
+ if (fast > 0) {
+ lame_set_VBR(gfp, vbr_mtrh);
+ }
+ else {
+ lame_set_VBR(gfp, vbr_rh);
+ }
+ return 0;
+ }
+
+ else if ((strcmp(preset_name, "insane") == 0) && (fast < 1)) {
+
+ lame_set_preset(gfp, INSANE);
+
+ return 0;
+ }
+
+ /* Generic ABR Preset */
+ if (((atoi(preset_name)) > 0) && (fast < 1)) {
+ if ((atoi(preset_name)) >= 8 && (atoi(preset_name)) <= 320) {
+ lame_set_preset(gfp, atoi(preset_name));
+
+ if (cbr == 1)
+ lame_set_VBR(gfp, vbr_off);
+
+ if (mono == 1) {
+ lame_set_mode(gfp, MONO);
+ }
+
+ return 0;
+
+ }
+ else {
+ lame_version_print(Console_IO.Error_fp);
+ error_printf("Error: The bitrate specified is out of the valid range for this preset\n"
+ "\n"
+ "When using this mode you must enter a value between \"32\" and \"320\"\n"
+ "\n" "For further information try: \"%s --preset help\"\n", ProgramName);
+ return -1;
+ }
+ }
+
+ lame_version_print(Console_IO.Error_fp);
+ error_printf("Error: You did not enter a valid profile and/or options with --preset\n"
+ "\n"
+ "Available profiles are:\n"
+ "\n"
+ " <fast> medium\n"
+ " <fast> standard\n"
+ " <fast> extreme\n"
+ " insane\n"
+ " <cbr> (ABR Mode) - The ABR Mode is implied. To use it,\n"
+ " simply specify a bitrate. For example:\n"
+ " \"--preset 185\" activates this\n"
+ " preset and uses 185 as an average kbps.\n" "\n");
+ error_printf(" Some examples:\n"
+ "\n"
+ " or \"%s --preset fast standard <input file> <output file>\"\n"
+ " or \"%s --preset cbr 192 <input file> <output file>\"\n"
+ " or \"%s --preset 172 <input file> <output file>\"\n"
+ " or \"%s --preset extreme <input file> <output file>\"\n"
+ "\n"
+ "For further information try: \"%s --preset help\"\n", ProgramName, ProgramName,
+ ProgramName, ProgramName, ProgramName);
+ return -1;
+}
+
+static void
+genre_list_handler(int num, const char *name, void *cookie)
+{
+ (void) cookie;
+ console_printf("%3d %s\n", num, name);
+}
+
+
+/************************************************************************
+*
+* parse_args
+*
+* PURPOSE: Sets encoding parameters to the specifications of the
+* command line. Default settings are used for parameters
+* not specified in the command line.
+*
+* If the input file is in WAVE or AIFF format, the sampling frequency is read
+* from the AIFF header.
+*
+* The input and output filenames are read into #inpath# and #outpath#.
+*
+************************************************************************/
+
+/* would use real "strcasecmp" but it isn't portable */
+static int
+local_strcasecmp(const char *s1, const char *s2)
+{
+ unsigned char c1;
+ unsigned char c2;
+
+ do {
+ c1 = tolower(*s1);
+ c2 = tolower(*s2);
+ if (!c1) {
+ break;
+ }
+ ++s1;
+ ++s2;
+ } while (c1 == c2);
+ return c1 - c2;
+}
+
+
+
+/* LAME is a simple frontend which just uses the file extension */
+/* to determine the file type. Trying to analyze the file */
+/* contents is well beyond the scope of LAME and should not be added. */
+static int
+filename_to_type(const char *FileName)
+{
+ size_t len = strlen(FileName);
+
+ if (len < 4)
+ return sf_unknown;
+
+ FileName += len - 4;
+ if (0 == local_strcasecmp(FileName, ".mpg"))
+ return sf_mp123;
+ if (0 == local_strcasecmp(FileName, ".mp1"))
+ return sf_mp123;
+ if (0 == local_strcasecmp(FileName, ".mp2"))
+ return sf_mp123;
+ if (0 == local_strcasecmp(FileName, ".mp3"))
+ return sf_mp123;
+ if (0 == local_strcasecmp(FileName, ".wav"))
+ return sf_wave;
+ if (0 == local_strcasecmp(FileName, ".aif"))
+ return sf_aiff;
+ if (0 == local_strcasecmp(FileName, ".raw"))
+ return sf_raw;
+ if (0 == local_strcasecmp(FileName, ".ogg"))
+ return sf_ogg;
+ return sf_unknown;
+}
+
+static int
+resample_rate(double freq)
+{
+ if (freq >= 1.e3)
+ freq *= 1.e-3;
+
+ switch ((int) freq) {
+ case 8:
+ return 8000;
+ case 11:
+ return 11025;
+ case 12:
+ return 12000;
+ case 16:
+ return 16000;
+ case 22:
+ return 22050;
+ case 24:
+ return 24000;
+ case 32:
+ return 32000;
+ case 44:
+ return 44100;
+ case 48:
+ return 48000;
+ default:
+ error_printf("Illegal resample frequency: %.3f kHz\n", freq);
+ return 0;
+ }
+}
+
+
+static int
+set_id3_albumart(lame_t gfp, char const* file_name)
+{
+ int ret = -1;
+ FILE *fpi = 0;
+ char *albumart = 0;
+
+ if (file_name == 0) {
+ return 0;
+ }
+ fpi = fopen(file_name, "rb");
+ if (!fpi) {
+ ret = 1;
+ }
+ else {
+ size_t size;
+
+ fseek(fpi, 0, SEEK_END);
+ size = ftell(fpi);
+ fseek(fpi, 0, SEEK_SET);
+ albumart = (char *)malloc(size);
+ if (!albumart) {
+ ret = 2;
+ }
+ else {
+ if (fread(albumart, 1, size, fpi) != size) {
+ ret = 3;
+ }
+ else {
+ ret = id3tag_set_albumart(gfp, albumart, size) ? 4 : 0;
+ }
+ free(albumart);
+ }
+ fclose(fpi);
+ }
+ switch (ret) {
+ case 1: error_printf("Could not find: '%s'.\n", file_name); break;
+ case 2: error_printf("Insufficient memory for reading the albumart.\n"); break;
+ case 3: error_printf("Read error: '%s'.\n", file_name); break;
+ case 4: error_printf("Unsupported image: '%s'.\nSpecify JPEG/PNG/GIF image (128KB maximum)\n", file_name); break;
+ default: break;
+ }
+ return ret;
+}
+
+
+enum ID3TAG_MODE
+{ ID3TAG_MODE_DEFAULT
+, ID3TAG_MODE_V1_ONLY
+, ID3TAG_MODE_V2_ONLY
+};
+
+/* Ugly, NOT final version */
+
+#define T_IF(str) if ( 0 == local_strcasecmp (token,str) ) {
+#define T_ELIF(str) } else if ( 0 == local_strcasecmp (token,str) ) {
+#define T_ELIF_INTERNAL(str) } else if (INTERNAL_OPTS && (0 == local_strcasecmp (token,str)) ) {
+#define T_ELIF2(str1,str2) } else if ( 0 == local_strcasecmp (token,str1) || 0 == local_strcasecmp (token,str2) ) {
+#define T_ELSE } else {
+#define T_END }
+
+int
+parse_args(lame_global_flags * gfp, int argc, char **argv,
+ char *const inPath, char *const outPath, char **nogap_inPath, int *num_nogap)
+{
+ int input_file = 0; /* set to 1 if we parse an input file name */
+ int i;
+ int autoconvert = 0;
+ double val;
+ int nogap = 0;
+ int nogap_tags = 0; /* set to 1 to use VBR tags in NOGAP mode */
+ const char *ProgramName = argv[0];
+ int count_nogap = 0;
+ int noreplaygain = 0; /* is RG explicitly disabled by the user */
+ int id3tag_mode = ID3TAG_MODE_DEFAULT;
+
+ inPath[0] = '\0';
+ outPath[0] = '\0';
+ /* turn on display options. user settings may turn them off below */
+ silent = 0;
+ ignore_tag_errors = 0;
+ brhist = 1;
+ mp3_delay = 0;
+ mp3_delay_set = 0;
+ print_clipping_info = 0;
+ disable_wav_header = 0;
+ id3tag_init(gfp);
+
+ /* process args */
+ for (i = 0; ++i < argc;) {
+ char c;
+ char *token;
+ char *arg;
+ char *nextArg;
+ int argUsed;
+
+ token = argv[i];
+ if (*token++ == '-') {
+ argUsed = 0;
+ nextArg = i + 1 < argc ? argv[i + 1] : "";
+
+ if (!*token) { /* The user wants to use stdin and/or stdout. */
+ input_file = 1;
+ if (inPath[0] == '\0')
+ strncpy(inPath, argv[i], PATH_MAX + 1);
+ else if (outPath[0] == '\0')
+ strncpy(outPath, argv[i], PATH_MAX + 1);
+ }
+ if (*token == '-') { /* GNU style */
+ token++;
+
+ T_IF("resample")
+ argUsed = 1;
+ (void) lame_set_out_samplerate(gfp, resample_rate(atof(nextArg)));
+
+ T_ELIF("vbr-old")
+ lame_set_VBR(gfp, vbr_rh);
+
+ T_ELIF("vbr-new")
+ lame_set_VBR(gfp, vbr_mtrh);
+
+ T_ELIF("vbr-mtrh")
+ lame_set_VBR(gfp, vbr_mtrh);
+
+ T_ELIF("cbr")
+ lame_set_VBR(gfp, vbr_off);
+
+ T_ELIF("abr")
+ argUsed = 1;
+ lame_set_VBR(gfp, vbr_abr);
+ lame_set_VBR_mean_bitrate_kbps(gfp, atoi(nextArg));
+ /* values larger than 8000 are bps (like Fraunhofer), so it's strange to get 320000 bps MP3 when specifying 8000 bps MP3 */
+ if (lame_get_VBR_mean_bitrate_kbps(gfp) >= 8000)
+ lame_set_VBR_mean_bitrate_kbps(gfp,
+ (lame_get_VBR_mean_bitrate_kbps(gfp) +
+ 500) / 1000);
+
+ lame_set_VBR_mean_bitrate_kbps(gfp, Min(lame_get_VBR_mean_bitrate_kbps(gfp), 320));
+ lame_set_VBR_mean_bitrate_kbps(gfp, Max(lame_get_VBR_mean_bitrate_kbps(gfp), 8));
+
+ T_ELIF("r3mix")
+ lame_set_preset(gfp, R3MIX);
+
+ T_ELIF("bitwidth")
+ argUsed = 1;
+ in_bitwidth = atoi(nextArg);
+
+ T_ELIF("signed")
+ in_signed = 1;
+
+ T_ELIF("unsigned")
+ in_signed = 0;
+
+ T_ELIF("little-endian")
+ in_endian = ByteOrderLittleEndian;
+
+ T_ELIF("big-endian")
+ in_endian = ByteOrderBigEndian;
+
+ T_ELIF("mp1input")
+ input_format = sf_mp1;
+
+ T_ELIF("mp2input")
+ input_format = sf_mp2;
+
+ T_ELIF("mp3input")
+ input_format = sf_mp3;
+
+ T_ELIF("ogginput")
+ error_printf("sorry, vorbis support in LAME is deprecated.\n");
+ return -1;
+
+ T_ELIF("phone")
+ if (presets_set(gfp, 0, 0, token, ProgramName) < 0)
+ return -1;
+ error_printf("Warning: --phone is deprecated, use --preset phone instead!");
+
+ T_ELIF("voice")
+ if (presets_set(gfp, 0, 0, token, ProgramName) < 0)
+ return -1;
+ error_printf("Warning: --voice is deprecated, use --preset voice instead!");
+
+ T_ELIF_INTERNAL("noshort")
+ (void) lame_set_no_short_blocks(gfp, 1);
+
+ T_ELIF_INTERNAL("short")
+ (void) lame_set_no_short_blocks(gfp, 0);
+
+ T_ELIF_INTERNAL("allshort")
+ (void) lame_set_force_short_blocks(gfp, 1);
+
+
+ T_ELIF("decode")
+ (void) lame_set_decode_only(gfp, 1);
+
+ T_ELIF("flush")
+ flush_write = 1;
+
+ T_ELIF("decode-mp3delay")
+ mp3_delay = atoi(nextArg);
+ mp3_delay_set = 1;
+ argUsed = 1;
+
+ T_ELIF("nores")
+ lame_set_disable_reservoir(gfp, 1);
+
+ T_ELIF("strictly-enforce-ISO")
+ lame_set_strict_ISO(gfp, 1);
+
+ T_ELIF("scale")
+ argUsed = 1;
+ (void) lame_set_scale(gfp, (float) atof(nextArg));
+
+ T_ELIF("scale-l")
+ argUsed = 1;
+ (void) lame_set_scale_left(gfp, (float) atof(nextArg));
+
+ T_ELIF("scale-r")
+ argUsed = 1;
+ (void) lame_set_scale_right(gfp, (float) atof(nextArg));
+
+ T_ELIF("noasm")
+ argUsed = 1;
+ if (!strcmp(nextArg, "mmx"))
+ (void) lame_set_asm_optimizations(gfp, MMX, 0);
+ if (!strcmp(nextArg, "3dnow"))
+ (void) lame_set_asm_optimizations(gfp, AMD_3DNOW, 0);
+ if (!strcmp(nextArg, "sse"))
+ (void) lame_set_asm_optimizations(gfp, SSE, 0);
+
+ T_ELIF("freeformat")
+ lame_set_free_format(gfp, 1);
+
+ T_ELIF("replaygain-fast")
+ lame_set_findReplayGain(gfp, 1);
+
+#ifdef DECODE_ON_THE_FLY
+ T_ELIF("replaygain-accurate")
+ lame_set_decode_on_the_fly(gfp, 1);
+ lame_set_findReplayGain(gfp, 1);
+#endif
+
+ T_ELIF("noreplaygain")
+ noreplaygain = 1;
+ lame_set_findReplayGain(gfp, 0);
+
+
+#ifdef DECODE_ON_THE_FLY
+ T_ELIF("clipdetect")
+ print_clipping_info = 1;
+ lame_set_decode_on_the_fly(gfp, 1);
+#endif
+
+ T_ELIF("nohist")
+ brhist = 0;
+
+#if defined(__OS2__) || defined(WIN32)
+ T_ELIF("priority")
+ char *endptr;
+ int priority = (int) strtol(nextArg, &endptr, 10);
+ if (endptr != nextArg) {
+ argUsed = 1;
+ }
+# if defined(__OS2__)
+ setOS2Priority(gfp, priority);
+# else /* WIN32 */
+ setWin32Priority(gfp, priority);
+# endif
+#endif
+
+ /* options for ID3 tag */
+ T_ELIF("tt")
+ argUsed = 1;
+ id3_tag(gfp, 't', TENC_RAW, nextArg);
+
+ T_ELIF("ta")
+ argUsed = 1;
+ id3_tag(gfp, 'a', TENC_RAW, nextArg);
+
+ T_ELIF("tl")
+ argUsed = 1;
+ id3_tag(gfp, 'l', TENC_RAW, nextArg);
+
+ T_ELIF("ty")
+ argUsed = 1;
+ id3_tag(gfp, 'y', TENC_RAW, nextArg);
+
+ T_ELIF("tc")
+ argUsed = 1;
+ id3_tag(gfp, 'c', TENC_RAW, nextArg);
+
+ T_ELIF("tn")
+ int ret = id3_tag(gfp, 'n', TENC_RAW, nextArg);
+ argUsed = 1;
+ if (ret != 0) {
+ if (0 == ignore_tag_errors) {
+ if (id3tag_mode == ID3TAG_MODE_V1_ONLY) {
+ error_printf("The track number has to be between 1 and 255 for ID3v1.\n");
+ return -1;
+ }
+ else if (id3tag_mode == ID3TAG_MODE_V2_ONLY) {
+ /* track will be stored as-is in ID3v2 case, so no problem here */
+ }
+ else {
+ if (silent < 10) {
+ error_printf("The track number has to be between 1 and 255 for ID3v1, ignored for ID3v1.\n");
+ }
+ }
+ }
+ }
+
+ T_ELIF("tg")
+ int ret = id3_tag(gfp, 'g', TENC_RAW, nextArg);
+ argUsed = 1;
+ if (ret != 0) {
+ if (0 == ignore_tag_errors) {
+ if (ret == -1) {
+ error_printf("Unknown ID3v1 genre number: '%s'.\n", nextArg);
+ return -1;
+ }
+ else if (ret == -2) {
+ if (id3tag_mode == ID3TAG_MODE_V1_ONLY) {
+ error_printf("Unknown ID3v1 genre: '%s'.\n", nextArg);
+ return -1;
+ }
+ else if (id3tag_mode == ID3TAG_MODE_V2_ONLY) {
+ /* genre will be stored as-is in ID3v2 case, so no problem here */
+ }
+ else {
+ if (silent < 10) {
+ error_printf("Unknown ID3v1 genre: '%s'. Setting ID3v1 genre to 'Other'\n", nextArg);
+ }
+ }
+ }
+ else {
+ error_printf("Internal error.\n");
+ return -1;
+ }
+ }
+ }
+
+ T_ELIF("tv")
+ argUsed = 1;
+ if (id3_tag(gfp, 'v', TENC_RAW, nextArg)) {
+ if (silent < 10) {
+ error_printf("Invalid field value: '%s'. Ignored\n", nextArg);
+ }
+ }
+
+ T_ELIF("ti")
+ argUsed = 1;
+ if (set_id3_albumart(gfp, nextArg) != 0) {
+ if (! ignore_tag_errors) {
+ return -1;
+ }
+ }
+
+ T_ELIF("ignore-tag-errors")
+ ignore_tag_errors = 1;
+
+ T_ELIF("add-id3v2")
+ id3tag_add_v2(gfp);
+
+ T_ELIF("id3v1-only")
+ id3tag_v1_only(gfp);
+ id3tag_mode = ID3TAG_MODE_V1_ONLY;
+
+ T_ELIF("id3v2-only")
+ id3tag_v2_only(gfp);
+ id3tag_mode = ID3TAG_MODE_V2_ONLY;
+
+ T_ELIF("space-id3v1")
+ id3tag_space_v1(gfp);
+
+ T_ELIF("pad-id3v2")
+ id3tag_pad_v2(gfp);
+
+ T_ELIF("pad-id3v2-size")
+ int n = atoi(nextArg);
+ n = n <= 128000 ? n : 128000;
+ n = n >= 0 ? n : 0;
+ id3tag_set_pad(gfp, n);
+ argUsed = 1;
+
+
+ T_ELIF("genre-list")
+ id3tag_genre_list(genre_list_handler, NULL);
+ return -2;
+
+#ifdef HAVE_ICONV
+ /* some experimental switches for setting ID3 tags
+ * with proper character encodings
+ */
+ T_ELIF("lTitle") argUsed = 1; id3_tag(gfp, 't', TENC_LATIN1, nextArg);
+ T_ELIF("lArtist") argUsed = 1; id3_tag(gfp, 'a', TENC_LATIN1, nextArg);
+ T_ELIF("lAlbum") argUsed = 1; id3_tag(gfp, 'l', TENC_LATIN1, nextArg);
+ T_ELIF("lGenre") argUsed = 1; id3_tag(gfp, 'g', TENC_LATIN1, nextArg);
+ T_ELIF("lComment")argUsed = 1; id3_tag(gfp, 'c', TENC_LATIN1, nextArg);
+ T_ELIF("lFieldvalue")
+ argUsed = 1;
+ if (id3_tag(gfp, 'v', TENC_LATIN1, nextArg)) {
+ if (silent < 10) {
+ error_printf("Invalid field value: '%s'. Ignored\n", nextArg);
+ }
+ }
+
+ T_ELIF("uTitle") argUsed = 1; id3_tag(gfp, 't', TENC_UCS2, nextArg);
+ T_ELIF("uArtist") argUsed = 1; id3_tag(gfp, 'a', TENC_UCS2, nextArg);
+ T_ELIF("uAlbum") argUsed = 1; id3_tag(gfp, 'l', TENC_UCS2, nextArg);
+ T_ELIF("uGenre") argUsed = 1; id3_tag(gfp, 'g', TENC_UCS2, nextArg);
+ T_ELIF("uComment")argUsed = 1; id3_tag(gfp, 'c', TENC_UCS2, nextArg);
+ /*
+ T_ELIF("uFieldvalue")
+ argUsed = 1;
+ if (id3_tag(gfp, 'v', TENC_UCS2, nextArg)) {
+ if (silent < 10) {
+ error_printf("Invalid field value: '%s'. Ignored\n", nextArg);
+ }
+ }
+ */
+#endif
+
+ T_ELIF("lowpass")
+ val = atof(nextArg);
+ argUsed = 1;
+ if (val < 0) {
+ lame_set_lowpassfreq(gfp, -1);
+ }
+ else {
+ /* useful are 0.001 kHz...50 kHz, 50 Hz...50000 Hz */
+ if (val < 0.001 || val > 50000.) {
+ error_printf("Must specify lowpass with --lowpass freq, freq >= 0.001 kHz\n");
+ return -1;
+ }
+ lame_set_lowpassfreq(gfp, (int) (val * (val < 50. ? 1.e3 : 1.e0) + 0.5));
+ }
+
+ T_ELIF("lowpass-width")
+ val = atof(nextArg);
+ argUsed = 1;
+ /* useful are 0.001 kHz...16 kHz, 16 Hz...50000 Hz */
+ if (val < 0.001 || val > 50000.) {
+ error_printf
+ ("Must specify lowpass width with --lowpass-width freq, freq >= 0.001 kHz\n");
+ return -1;
+ }
+ lame_set_lowpasswidth(gfp, (int) (val * (val < 16. ? 1.e3 : 1.e0) + 0.5));
+
+ T_ELIF("highpass")
+ val = atof(nextArg);
+ argUsed = 1;
+ if (val < 0.0) {
+ lame_set_highpassfreq(gfp, -1);
+ }
+ else {
+ /* useful are 0.001 kHz...16 kHz, 16 Hz...50000 Hz */
+ if (val < 0.001 || val > 50000.) {
+ error_printf("Must specify highpass with --highpass freq, freq >= 0.001 kHz\n");
+ return -1;
+ }
+ lame_set_highpassfreq(gfp, (int) (val * (val < 16. ? 1.e3 : 1.e0) + 0.5));
+ }
+
+ T_ELIF("highpass-width")
+ val = atof(nextArg);
+ argUsed = 1;
+ /* useful are 0.001 kHz...16 kHz, 16 Hz...50000 Hz */
+ if (val < 0.001 || val > 50000.) {
+ error_printf
+ ("Must specify highpass width with --highpass-width freq, freq >= 0.001 kHz\n");
+ return -1;
+ }
+ lame_set_highpasswidth(gfp, (int) val);
+
+ T_ELIF("comp")
+ argUsed = 1;
+ val = atof(nextArg);
+ if (val < 1.0) {
+ error_printf("Must specify compression ratio >= 1.0\n");
+ return -1;
+ }
+ lame_set_compression_ratio(gfp, (float) val);
+
+ T_ELIF("notemp")
+ (void) lame_set_useTemporal(gfp, 0);
+
+ T_ELIF("interch")
+ argUsed = 1;
+ (void) lame_set_interChRatio(gfp, (float) atof(nextArg));
+
+ T_ELIF("temporal-masking")
+ argUsed = 1;
+ (void) lame_set_useTemporal(gfp, atoi(nextArg) ? 1 : 0);
+
+ T_ELIF("nspsytune")
+ ;
+
+ T_ELIF("nssafejoint")
+ lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2);
+
+ T_ELIF("nsmsfix")
+ argUsed = 1;
+ (void) lame_set_msfix(gfp, atof(nextArg));
+
+ T_ELIF("ns-bass")
+ argUsed = 1;
+ {
+ double d;
+ int k;
+ d = atof(nextArg);
+ k = (int) (d * 4);
+ if (k < -32)
+ k = -32;
+ if (k > 31)
+ k = 31;
+ if (k < 0)
+ k += 64;
+ lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 2));
+ }
+
+ T_ELIF("ns-alto")
+ argUsed = 1;
+ {
+ double d;
+ int k;
+ d = atof(nextArg);
+ k = (int) (d * 4);
+ if (k < -32)
+ k = -32;
+ if (k > 31)
+ k = 31;
+ if (k < 0)
+ k += 64;
+ lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 8));
+ }
+
+ T_ELIF("ns-treble")
+ argUsed = 1;
+ {
+ double d;
+ int k;
+ d = atof(nextArg);
+ k = (int) (d * 4);
+ if (k < -32)
+ k = -32;
+ if (k > 31)
+ k = 31;
+ if (k < 0)
+ k += 64;
+ lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 14));
+ }
+
+ T_ELIF("ns-sfb21")
+ /* to be compatible with Naoki's original code,
+ * ns-sfb21 specifies how to change ns-treble for sfb21 */
+ argUsed = 1;
+ {
+ double d;
+ int k;
+ d = atof(nextArg);
+ k = (int) (d * 4);
+ if (k < -32)
+ k = -32;
+ if (k > 31)
+ k = 31;
+ if (k < 0)
+ k += 64;
+ lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 20));
+ }
+
+ T_ELIF("nspsytune2") {
+ }
+
+ /* some more GNU-ish options could be added
+ * brief => few messages on screen (name, status report)
+ * o/output file => specifies output filename
+ * O => stdout
+ * i/input file => specifies input filename
+ * I => stdin
+ */
+ T_ELIF2("quiet", "silent")
+ silent = 10; /* on a scale from 1 to 10 be very silent */
+
+ T_ELIF("brief")
+ silent = -5; /* print few info on screen */
+
+ T_ELIF("verbose")
+ silent = -10; /* print a lot on screen */
+
+ T_ELIF2("version", "license")
+ print_license(stdout);
+ return -2;
+
+ T_ELIF2("help", "usage")
+ short_help(gfp, stdout, ProgramName);
+ return -2;
+
+ T_ELIF("longhelp")
+ long_help(gfp, stdout, ProgramName, 0 /* lessmode=NO */ );
+ return -2;
+
+ T_ELIF("?")
+#ifdef __unix__
+ FILE *fp = popen("less -Mqc", "w");
+ long_help(gfp, fp, ProgramName, 0 /* lessmode=NO */ );
+ pclose(fp);
+#else
+ long_help(gfp, stdout, ProgramName, 1 /* lessmode=YES */ );
+#endif
+ return -2;
+
+ T_ELIF2("preset", "alt-preset")
+ argUsed = 1;
+ {
+ int fast = 0, cbr = 0;
+
+ while ((strcmp(nextArg, "fast") == 0) || (strcmp(nextArg, "cbr") == 0)) {
+
+ if ((strcmp(nextArg, "fast") == 0) && (fast < 1))
+ fast = 1;
+ if ((strcmp(nextArg, "cbr") == 0) && (cbr < 1))
+ cbr = 1;
+
+ argUsed++;
+ nextArg = i + argUsed < argc ? argv[i + argUsed] : "";
+ }
+
+ if (presets_set(gfp, fast, cbr, nextArg, ProgramName) < 0)
+ return -1;
+ }
+
+ T_ELIF("disptime")
+ argUsed = 1;
+ update_interval = (float) atof(nextArg);
+
+ T_ELIF("nogaptags")
+ nogap_tags = 1;
+
+ T_ELIF("nogapout")
+ strcpy(outPath, nextArg);
+ argUsed = 1;
+
+ T_ELIF("nogap")
+ nogap = 1;
+
+
+ T_ELIF_INTERNAL("tune") /*without helptext */
+ argUsed = 1;
+ {
+ extern void lame_set_tune(lame_t, float);
+ lame_set_tune(gfp, (float) atof(nextArg));
+ }
+
+ T_ELIF_INTERNAL("shortthreshold") {
+ float x, y;
+ int n = sscanf(nextArg, "%f,%f", &x, &y);
+ if (n == 1) {
+ y = x;
+ }
+ argUsed = 1;
+ (void) lame_set_short_threshold(gfp, x, y);
+ }
+
+ T_ELIF_INTERNAL("maskingadjust") /*without helptext */
+ argUsed = 1;
+ (void) lame_set_maskingadjust(gfp, (float) atof(nextArg));
+
+ T_ELIF_INTERNAL("maskingadjustshort") /*without helptext */
+ argUsed = 1;
+ (void) lame_set_maskingadjust_short(gfp, (float) atof(nextArg));
+
+ T_ELIF_INTERNAL("athcurve") /*without helptext */
+ argUsed = 1;
+ (void) lame_set_ATHcurve(gfp, (float) atof(nextArg));
+
+ T_ELIF_INTERNAL("no-preset-tune") /*without helptext */
+ (void) lame_set_preset_notune(gfp, 0);
+
+ T_ELIF_INTERNAL("substep")
+ argUsed = 1;
+ (void) lame_set_substep(gfp, atoi(nextArg));
+
+ T_ELIF_INTERNAL("sbgain") /*without helptext */
+ argUsed = 1;
+ (void) lame_set_subblock_gain(gfp, atoi(nextArg));
+
+ T_ELIF_INTERNAL("sfscale") /*without helptext */
+ (void) lame_set_sfscale(gfp, 1);
+
+ T_ELIF_INTERNAL("noath")
+ (void) lame_set_noATH(gfp, 1);
+
+ T_ELIF_INTERNAL("athonly")
+ (void) lame_set_ATHonly(gfp, 1);
+
+ T_ELIF_INTERNAL("athshort")
+ (void) lame_set_ATHshort(gfp, 1);
+
+ T_ELIF_INTERNAL("athlower")
+ argUsed = 1;
+ (void) lame_set_ATHlower(gfp, (float) atof(nextArg));
+
+ T_ELIF_INTERNAL("athtype")
+ argUsed = 1;
+ (void) lame_set_ATHtype(gfp, atoi(nextArg));
+
+ T_ELIF_INTERNAL("athaa-type") /* switch for developing, no DOCU */
+ argUsed = 1; /* once was 1:Gaby, 2:Robert, 3:Jon, else:off */
+ lame_set_athaa_type(gfp, atoi(nextArg)); /* now: 0:off else:Jon */
+
+ T_ELIF ("athaa-sensitivity")
+ argUsed=1;
+ lame_set_athaa_sensitivity(gfp, (float) atof(nextArg));
+
+ T_ELIF_INTERNAL("debug-file") /* switch for developing, no DOCU */
+ argUsed = 1; /* file name to print debug info into */
+ {
+ set_debug_file(nextArg);
+ }
+
+ T_ELSE {
+ error_printf("%s: unrecognized option --%s\n", ProgramName, token);
+ return -1;
+ }
+ T_END i += argUsed;
+
+ }
+ else {
+ while ((c = *token++) != '\0') {
+ arg = *token ? token : nextArg;
+ switch (c) {
+ case 'm':
+ argUsed = 1;
+
+ switch (*arg) {
+ case 's':
+ (void) lame_set_mode(gfp, STEREO);
+ break;
+ case 'd':
+ (void) lame_set_mode(gfp, DUAL_CHANNEL);
+ break;
+ case 'f':
+ lame_set_force_ms(gfp, 1);
+ /* FALLTHROUGH */
+ case 'j':
+ (void) lame_set_mode(gfp, JOINT_STEREO);
+ break;
+ case 'm':
+ (void) lame_set_mode(gfp, MONO);
+ break;
+ case 'a':
+ (void) lame_set_mode(gfp, JOINT_STEREO);
+ break;
+ default:
+ error_printf("%s: -m mode must be s/d/j/f/m not %s\n", ProgramName,
+ arg);
+ return -1;
+ }
+ break;
+
+ case 'V':
+ argUsed = 1;
+ /* to change VBR default look in lame.h */
+ if (lame_get_VBR(gfp) == vbr_off)
+ lame_set_VBR(gfp, vbr_default);
+ lame_set_VBR_quality(gfp, (float)atof(arg));
+ break;
+ case 'v':
+ /* to change VBR default look in lame.h */
+ if (lame_get_VBR(gfp) == vbr_off)
+ lame_set_VBR(gfp, vbr_default);
+ break;
+
+ case 'q':
+ argUsed = 1;
+ {
+ int tmp_quality = atoi(arg);
+
+ /* XXX should we move this into lame_set_quality()? */
+ if (tmp_quality < 0)
+ tmp_quality = 0;
+ if (tmp_quality > 9)
+ tmp_quality = 9;
+
+ (void) lame_set_quality(gfp, tmp_quality);
+ }
+ break;
+ case 'f':
+ (void) lame_set_quality(gfp, 7);
+ break;
+ case 'h':
+ (void) lame_set_quality(gfp, 2);
+ break;
+
+ case 's':
+ argUsed = 1;
+ val = atof(arg);
+ (void) lame_set_in_samplerate(gfp,
+ (int) (val * (val <= 192 ? 1.e3 : 1.e0) +
+ 0.5));
+ break;
+ case 'b':
+ argUsed = 1;
+ lame_set_brate(gfp, atoi(arg));
+ lame_set_VBR_min_bitrate_kbps(gfp, lame_get_brate(gfp));
+ break;
+ case 'B':
+ argUsed = 1;
+ lame_set_VBR_max_bitrate_kbps(gfp, atoi(arg));
+ break;
+ case 'F':
+ lame_set_VBR_hard_min(gfp, 1);
+ break;
+ case 't': /* dont write VBR tag */
+ (void) lame_set_bWriteVbrTag(gfp, 0);
+ disable_wav_header = 1;
+ break;
+ case 'T': /* do write VBR tag */
+ (void) lame_set_bWriteVbrTag(gfp, 1);
+ nogap_tags = 1;
+ disable_wav_header = 0;
+ break;
+ case 'r': /* force raw pcm input file */
+#if defined(LIBSNDFILE)
+ error_printf
+ ("WARNING: libsndfile may ignore -r and perform fseek's on the input.\n"
+ "Compile without libsndfile if this is a problem.\n");
+#endif
+ input_format = sf_raw;
+ break;
+ case 'x': /* force byte swapping */
+ swapbytes = 1;
+ break;
+ case 'p': /* (jo) error_protection: add crc16 information to stream */
+ lame_set_error_protection(gfp, 1);
+ break;
+ case 'a': /* autoconvert input file from stereo to mono - for mono mp3 encoding */
+ autoconvert = 1;
+ (void) lame_set_mode(gfp, MONO);
+ break;
+ case 'd': /*(void) lame_set_allow_diff_short( gfp, 1 ); */
+ case 'k': /*lame_set_lowpassfreq(gfp, -1);
+ lame_set_highpassfreq(gfp, -1); */
+ error_printf("WARNING: -%c is obsolete.\n", c);
+ break;
+ case 'S':
+ silent = 10;
+ break;
+ case 'X':
+ /* experimental switch -X:
+ the differnt types of quant compare are tough
+ to communicate to endusers, so they shouldn't
+ bother to toy around with them
+ */
+ {
+ int x, y;
+ int n = sscanf(arg, "%d,%d", &x, &y);
+ if (n == 1) {
+ y = x;
+ }
+ argUsed = 1;
+ if (INTERNAL_OPTS) {
+ lame_set_quant_comp(gfp, x);
+ lame_set_quant_comp_short(gfp, y);
+ }
+ }
+ break;
+ case 'Y':
+ lame_set_experimentalY(gfp, 1);
+ break;
+ case 'Z':
+ /* experimental switch -Z:
+ this switch is obsolete
+ */
+ {
+ int n = 1;
+ argUsed = sscanf(arg, "%d", &n);
+ if (INTERNAL_OPTS) {
+ lame_set_experimentalZ(gfp, n);
+ }
+ }
+ break;
+ case 'e':
+ argUsed = 1;
+
+ switch (*arg) {
+ case 'n':
+ lame_set_emphasis(gfp, 0);
+ break;
+ case '5':
+ lame_set_emphasis(gfp, 1);
+ break;
+ case 'c':
+ lame_set_emphasis(gfp, 3);
+ break;
+ default:
+ error_printf("%s: -e emp must be n/5/c not %s\n", ProgramName, arg);
+ return -1;
+ }
+ break;
+ case 'c':
+ lame_set_copyright(gfp, 1);
+ break;
+ case 'o':
+ lame_set_original(gfp, 0);
+ break;
+
+ case '?':
+ long_help(gfp, stdout, ProgramName, 0 /* LESSMODE=NO */ );
+ return -1;
+
+ default:
+ error_printf("%s: unrecognized option -%c\n", ProgramName, c);
+ return -1;
+ }
+ if (argUsed) {
+ if (arg == token)
+ token = ""; /* no more from token */
+ else
+ ++i; /* skip arg we used */
+ arg = "";
+ argUsed = 0;
+ }
+ }
+ }
+ }
+ else {
+ if (nogap) {
+ if ((num_nogap != NULL) && (count_nogap < *num_nogap)) {
+ strncpy(nogap_inPath[count_nogap++], argv[i], PATH_MAX + 1);
+ input_file = 1;
+ }
+ else {
+ /* sorry, calling program did not allocate enough space */
+ error_printf
+ ("Error: 'nogap option'. Calling program does not allow nogap option, or\n"
+ "you have exceeded maximum number of input files for the nogap option\n");
+ *num_nogap = -1;
+ return -1;
+ }
+ }
+ else {
+ /* normal options: inputfile [outputfile], and
+ either one can be a '-' for stdin/stdout */
+ if (inPath[0] == '\0') {
+ strncpy(inPath, argv[i], PATH_MAX + 1);
+ input_file = 1;
+ }
+ else {
+ if (outPath[0] == '\0')
+ strncpy(outPath, argv[i], PATH_MAX + 1);
+ else {
+ error_printf("%s: excess arg %s\n", ProgramName, argv[i]);
+ return -1;
+ }
+ }
+ }
+ }
+ } /* loop over args */
+
+ if (!input_file) {
+ usage(Console_IO.Console_fp, ProgramName);
+ return -1;
+ }
+
+ if (inPath[0] == '-')
+ silent = (silent <= 1 ? 1 : silent);
+#ifdef WIN32
+ else
+ dosToLongFileName(inPath);
+#endif
+
+ if (outPath[0] == '\0' && count_nogap == 0) {
+ if (inPath[0] == '-') {
+ /* if input is stdin, default output is stdout */
+ strcpy(outPath, "-");
+ }
+ else {
+ strncpy(outPath, inPath, PATH_MAX + 1 - 4);
+ if (lame_get_decode_only(gfp)) {
+ strncat(outPath, ".wav", 4);
+ }
+ else {
+ strncat(outPath, ".mp3", 4);
+ }
+ }
+ }
+
+ /* RG is enabled by default */
+ if (!noreplaygain)
+ lame_set_findReplayGain(gfp, 1);
+
+ /* disable VBR tags with nogap unless the VBR tags are forced */
+ if (nogap && lame_get_bWriteVbrTag(gfp) && nogap_tags == 0) {
+ console_printf("Note: Disabling VBR Xing/Info tag since it interferes with --nogap\n");
+ lame_set_bWriteVbrTag(gfp, 0);
+ }
+
+ /* some file options not allowed with stdout */
+ if (outPath[0] == '-') {
+ (void) lame_set_bWriteVbrTag(gfp, 0); /* turn off VBR tag */
+ }
+
+ /* if user did not explicitly specify input is mp3, check file name */
+ if (input_format == sf_unknown)
+ input_format = filename_to_type(inPath);
+
+#if !(defined HAVE_MPGLIB || defined AMIGA_MPEGA)
+ if (is_mpeg_file_format(input_format)) {
+ error_printf("Error: libmp3lame not compiled with mpg123 *decoding* support \n");
+ return -1;
+ }
+#endif
+
+
+ if (input_format == sf_ogg) {
+ error_printf("sorry, vorbis support in LAME is deprecated.\n");
+ return -1;
+ }
+ /* default guess for number of channels */
+ if (autoconvert)
+ (void) lame_set_num_channels(gfp, 2);
+ else if (MONO == lame_get_mode(gfp))
+ (void) lame_set_num_channels(gfp, 1);
+ else
+ (void) lame_set_num_channels(gfp, 2);
+
+ if (lame_get_free_format(gfp)) {
+ if (lame_get_brate(gfp) < 8 || lame_get_brate(gfp) > 640) {
+ error_printf("For free format, specify a bitrate between 8 and 640 kbps\n");
+ error_printf("with the -b <bitrate> option\n");
+ return -1;
+ }
+ }
+ if (num_nogap != NULL)
+ *num_nogap = count_nogap;
+ return 0;
+}
+
+
+/* end of parse.c */
diff --git a/lib/liblame/frontend/parse.h b/lib/liblame/frontend/parse.h
new file mode 100644
index 0000000000..cde45532ca
--- /dev/null
+++ b/lib/liblame/frontend/parse.h
@@ -0,0 +1,13 @@
+
+int usage(FILE * const fp, const char *ProgramName);
+int short_help(const lame_global_flags * gfp, FILE * const fp, const char *ProgramName);
+int long_help(const lame_global_flags * gfp, FILE * const fp, const char *ProgramName,
+ int lessmode);
+int display_bitrates(FILE * const fp);
+
+int parse_args(lame_global_flags * gfp, int argc, char **argv, char *const inPath,
+ char *const outPath, char **nogap_inPath, int *max_nogap);
+
+void parse_close();
+
+/* end of parse.h */
diff --git a/lib/liblame/frontend/portableio.c b/lib/liblame/frontend/portableio.c
new file mode 100644
index 0000000000..61c1d30d59
--- /dev/null
+++ b/lib/liblame/frontend/portableio.c
@@ -0,0 +1,490 @@
+/* Copyright (C) 1988-1991 Apple Computer, Inc.
+ * All Rights Reserved.
+ *
+ * Warranty Information
+ * Even though Apple has reviewed this software, Apple makes no warranty
+ * or representation, either express or implied, with respect to this
+ * software, its quality, accuracy, merchantability, or fitness for a
+ * particular purpose. As a result, this software is provided "as is,"
+ * and you, its user, are assuming the entire risk as to its quality
+ * and accuracy.
+ *
+ * This code may be used and freely distributed as long as it includes
+ * this copyright notice and the warranty information.
+ *
+ *
+ * Motorola processors (Macintosh, Sun, Sparc, MIPS, etc)
+ * pack bytes from high to low (they are big-endian).
+ * Use the HighLow routines to match the native format
+ * of these machines.
+ *
+ * Intel-like machines (PCs, Sequent)
+ * pack bytes from low to high (the are little-endian).
+ * Use the LowHigh routines to match the native format
+ * of these machines.
+ *
+ * These routines have been tested on the following machines:
+ * Apple Macintosh, MPW 3.1 C compiler
+ * Apple Macintosh, THINK C compiler
+ * Silicon Graphics IRIS, MIPS compiler
+ * Cray X/MP and Y/MP
+ * Digital Equipment VAX
+ *
+ *
+ * Implemented by Malcolm Slaney and Ken Turkowski.
+ *
+ * Malcolm Slaney contributions during 1988-1990 include big- and little-
+ * endian file I/O, conversion to and from Motorola's extended 80-bit
+ * floating-point format, and conversions to and from IEEE single-
+ * precision floating-point format.
+ *
+ * In 1991, Ken Turkowski implemented the conversions to and from
+ * IEEE double-precision format, added more precision to the extended
+ * conversions, and accommodated conversions involving +/- infinity,
+ * NaN's, and denormalized numbers.
+ *
+ * $Id: portableio.c,v 1.13 2007/10/14 19:54:32 robert Exp $
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#if defined(__riscos__) && defined(FPA10)
+#include "ymath.h"
+#else
+#include <math.h>
+#endif
+#include "portableio.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+/****************************************************************
+ * Big/little-endian independent I/O routines.
+ ****************************************************************/
+
+/*
+ * It is a hoax to call this code portable-IO:
+ *
+ * - It doesn't work on machines with CHAR_BIT != 8
+ * - it also don't test this error condition
+ * - otherwise it tries to handle CHAR_BIT != 8 by things like
+ * masking 'putc(i&0xff,fp)'
+ * - It doesn't handle EOF in any way
+ * - it only works with ints with 32 or more bits
+ * - It is a collection of initial buggy code with patching the known errors
+ * instead of CORRECTING them!
+ * For that see comments on the old Read16BitsHighLow()
+ */
+
+#ifdef KLEMM_36
+
+signed int
+ReadByte(FILE * fp)
+{
+ int result = getc(fp);
+ return result == EOF ? 0 : (signed char) (result & 0xFF);
+}
+
+unsigned int
+ReadByteUnsigned(FILE * fp)
+{
+ int result = getc(fp);
+ return result == EOF ? 0 : (unsigned char) (result & 0xFF);
+}
+
+#else
+
+int
+ReadByte(FILE * fp)
+{
+ int result;
+
+ result = getc(fp) & 0xff;
+ if (result & 0x80)
+ result = result - 0x100;
+ return result;
+}
+
+#endif
+
+#ifdef KLEMM_36
+
+int
+Read16BitsLowHigh(FILE * fp)
+{
+ int low = ReadByteUnsigned(fp);
+ int high = ReadByte(fp);
+
+ return (high << 8) | low;
+}
+
+#else
+int
+Read16BitsLowHigh(FILE * fp)
+{
+ int first, second, result;
+
+ first = 0xff & getc(fp);
+ second = 0xff & getc(fp);
+
+ result = (second << 8) + first;
+#ifndef THINK_C42
+ if (result & 0x8000)
+ result = result - 0x10000;
+#endif /* THINK_C */
+ return (result);
+}
+#endif
+
+
+#ifdef KLEMM_36
+
+int
+Read16BitsHighLow(FILE * fp)
+{
+ int high = ReadByte(fp);
+ int low = ReadByteUnsigned(fp);
+
+ return (high << 8) | low;
+}
+
+#else
+int
+Read16BitsHighLow(FILE * fp)
+{
+ int first, second, result;
+
+ /* Reads the High bits, the value is -128...127
+ * (which gave after upscaling the -32768...+32512
+ * Why this value is not converted to signed char?
+ */
+ first = 0xff & getc(fp);
+ /* Reads the Lows bits, the value is 0...255
+ * This is correct. This value gives an additional offset
+ * for the High bits
+ */
+ second = 0xff & getc(fp);
+
+ /* This is right */
+ result = (first << 8) + second;
+
+ /* Now we are starting to correct the nasty bug of the first instruction
+ * The value of the high bits is wrong. Always. So we must correct this
+ * value. This seems to be not necessary for THINK_C42. This is either
+ * a 16 bit compiler with 16 bit ints (where this bug is hidden and 0x10000
+ * is not in the scope of an int) or it is not a C compiler, but only a
+ * C like compiler. In the first case the '#ifndef THINK_C42' is wrong
+ * because it's not a property of the THINK_C42 compiler, but of all compilers
+ * with sizeof(int)*CHAR_BIT < 18.
+ * Another nasty thing is that the rest of the code doesn't work for 16 bit ints,
+ * so this patch don't solve the 16 bit problem.
+ */
+#ifndef THINK_C42
+ if (result & 0x8000)
+ result = result - 0x10000;
+#endif /* THINK_C */
+ return (result);
+}
+#endif
+
+void
+Write8Bits(FILE * fp, int i)
+{
+ putc(i & 0xff, fp);
+}
+
+
+void
+Write16BitsLowHigh(FILE * fp, int i)
+{
+ putc(i & 0xff, fp);
+ putc((i >> 8) & 0xff, fp);
+}
+
+
+void
+Write16BitsHighLow(FILE * fp, int i)
+{
+ putc((i >> 8) & 0xff, fp);
+ putc(i & 0xff, fp);
+}
+
+#ifdef KLEMM_36
+
+int
+Read24BitsHighLow(FILE * fp)
+{
+ int high = ReadByte(fp);
+ int med = ReadByteUnsigned(fp);
+ int low = ReadByteUnsigned(fp);
+
+ return (high << 16) | (med << 8) | low;
+}
+
+#else
+int
+Read24BitsHighLow(FILE * fp)
+{
+ int first, second, third;
+ int result;
+
+ first = 0xff & getc(fp);
+ second = 0xff & getc(fp);
+ third = 0xff & getc(fp);
+
+ result = (first << 16) + (second << 8) + third;
+ if (result & 0x800000)
+ result = result - 0x1000000;
+ return (result);
+}
+#endif
+
+#define Read32BitsLowHigh(f) Read32Bits(f)
+
+#ifdef KLEMM_36
+
+int
+Read32Bits(FILE * fp)
+{
+ int low = ReadByteUnsigned(fp);
+ int medl = ReadByteUnsigned(fp);
+ int medh = ReadByteUnsigned(fp);
+ int high = ReadByte(fp);
+
+ return (high << 24) | (medh << 16) | (medl << 8) | low;
+}
+
+#else
+
+int
+Read32Bits(FILE * fp)
+{
+ int first, second, result;
+
+ first = 0xffff & Read16BitsLowHigh(fp);
+ second = 0xffff & Read16BitsLowHigh(fp);
+
+ result = (second << 16) + first;
+#ifdef CRAY
+ if (result & 0x80000000)
+ result = result - 0x100000000;
+#endif /* CRAY */
+ return (result);
+}
+#endif
+
+
+#ifdef KLEMM_36
+
+int
+Read32BitsHighLow(FILE * fp)
+{
+ int high = ReadByte(fp);
+ int medh = ReadByteUnsigned(fp);
+ int medl = ReadByteUnsigned(fp);
+ int low = ReadByteUnsigned(fp);
+
+ return (high << 24) | (medh << 16) | (medl << 8) | low;
+}
+
+#else
+
+int
+Read32BitsHighLow(FILE * fp)
+{
+ int first, second, result;
+
+ first = 0xffff & Read16BitsHighLow(fp);
+ second = 0xffff & Read16BitsHighLow(fp);
+
+ result = (first << 16) + second;
+#ifdef CRAY
+ if (result & 0x80000000)
+ result = result - 0x100000000;
+#endif
+ return (result);
+}
+
+#endif
+
+void
+Write32Bits(FILE * fp, int i)
+{
+ Write16BitsLowHigh(fp, (int) (i & 0xffffL));
+ Write16BitsLowHigh(fp, (int) ((i >> 16) & 0xffffL));
+}
+
+
+void
+Write32BitsLowHigh(FILE * fp, int i)
+{
+ Write16BitsLowHigh(fp, (int) (i & 0xffffL));
+ Write16BitsLowHigh(fp, (int) ((i >> 16) & 0xffffL));
+}
+
+
+void
+Write32BitsHighLow(FILE * fp, int i)
+{
+ Write16BitsHighLow(fp, (int) ((i >> 16) & 0xffffL));
+ Write16BitsHighLow(fp, (int) (i & 0xffffL));
+}
+
+#ifdef KLEMM_36
+void
+ReadBytes(FILE * fp, char *p, int n)
+{
+ memset(p, 0, n);
+ fread(p, 1, n, fp);
+}
+#else
+void
+ReadBytes(FILE * fp, char *p, int n)
+{
+ /* What about fread? */
+
+ while (!feof(fp) & (n-- > 0))
+ *p++ = getc(fp);
+}
+#endif
+
+void
+ReadBytesSwapped(FILE * fp, char *p, int n)
+{
+ register char *q = p;
+
+ /* What about fread? */
+
+ while (!feof(fp) & (n-- > 0))
+ *q++ = getc(fp);
+
+ /* If not all bytes could be read, the resorting is different
+ * from the normal resorting. Is this intention or another bug?
+ */
+ for (q--; p < q; p++, q--) {
+ n = *p;
+ *p = *q;
+ *q = n;
+ }
+}
+
+#ifdef KLEMM_36
+void
+WriteBytes(FILE * fp, char *p, int n)
+{
+ /* return n == */
+ fwrite(p, 1, n, fp);
+}
+#else
+void
+WriteBytes(FILE * fp, char *p, int n)
+{
+ /* No error condition checking */
+ while (n-- > 0)
+ putc(*p++, fp);
+}
+#endif
+#ifdef KLEMM_36
+void
+WriteBytesSwapped(FILE * fp, char *p, int n)
+{
+ p += n;
+ while (n-- > 0)
+ putc(*--p, fp);
+}
+#else
+void
+WriteBytesSwapped(FILE * fp, char *p, int n)
+{
+ p += n - 1;
+ while (n-- > 0)
+ putc(*p--, fp);
+}
+#endif
+
+
+
+/****************************************************************
+ * The following two routines make up for deficiencies in many
+ * compilers to convert properly between unsigned integers and
+ * floating-point. Some compilers which have this bug are the
+ * THINK_C compiler for the Macintosh and the C compiler for the
+ * Silicon Graphics MIPS-based Iris.
+ ****************************************************************/
+
+#ifdef applec /* The Apple C compiler works */
+# define FloatToUnsigned(f) ((unsigned long)(f))
+# define UnsignedToFloat(u) ((double)(u))
+#else /* applec */
+# define FloatToUnsigned(f) ((unsigned long)(((long)((f) - 2147483648.0)) + 2147483647L + 1))
+# define UnsignedToFloat(u) (((double)((long)((u) - 2147483647L - 1))) + 2147483648.0)
+#endif /* applec */
+/****************************************************************
+ * Extended precision IEEE floating-point conversion routines
+ ****************************************************************/
+
+static double
+ConvertFromIeeeExtended(char *bytes)
+{
+ double f;
+ long expon;
+ unsigned long hiMant, loMant;
+
+#ifdef TEST
+ printf("ConvertFromIEEEExtended(%lx,%lx,%lx,%lx,%lx,%lx,%lx,%lx,%lx,%lx\r",
+ (long) bytes[0], (long) bytes[1], (long) bytes[2], (long) bytes[3],
+ (long) bytes[4], (long) bytes[5], (long) bytes[6],
+ (long) bytes[7], (long) bytes[8], (long) bytes[9]);
+#endif
+
+ expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
+ hiMant = ((unsigned long) (bytes[2] & 0xFF) << 24)
+ | ((unsigned long) (bytes[3] & 0xFF) << 16)
+ | ((unsigned long) (bytes[4] & 0xFF) << 8)
+ | ((unsigned long) (bytes[5] & 0xFF));
+ loMant = ((unsigned long) (bytes[6] & 0xFF) << 24)
+ | ((unsigned long) (bytes[7] & 0xFF) << 16)
+ | ((unsigned long) (bytes[8] & 0xFF) << 8)
+ | ((unsigned long) (bytes[9] & 0xFF));
+
+ /* This case should also be called if the number is below the smallest
+ * positive double variable */
+ if (expon == 0 && hiMant == 0 && loMant == 0) {
+ f = 0;
+ }
+ else {
+ /* This case should also be called if the number is too large to fit into
+ * a double variable */
+
+ if (expon == 0x7FFF) { /* Infinity or NaN */
+ f = HUGE_VAL;
+ }
+ else {
+ expon -= 16383;
+ f = ldexp(UnsignedToFloat(hiMant), (int) (expon -= 31));
+ f += ldexp(UnsignedToFloat(loMant), (int) (expon -= 32));
+ }
+ }
+
+ if (bytes[0] & 0x80)
+ return -f;
+ else
+ return f;
+}
+
+
+
+
+
+double
+ReadIeeeExtendedHighLow(FILE * fp)
+{
+ char bytes[10];
+
+ ReadBytes(fp, bytes, 10);
+ return ConvertFromIeeeExtended(bytes);
+}
diff --git a/lib/liblame/frontend/portableio.h b/lib/liblame/frontend/portableio.h
new file mode 100644
index 0000000000..c24abc6e2c
--- /dev/null
+++ b/lib/liblame/frontend/portableio.h
@@ -0,0 +1,91 @@
+#ifndef LAME_PORTABLEIO_H
+#define LAME_PORTABLEIO_H
+/* Copyright (C) 1988-1991 Apple Computer, Inc.
+ * All Rights Reserved.
+ *
+ * Warranty Information
+ * Even though Apple has reviewed this software, Apple makes no warranty
+ * or representation, either express or implied, with respect to this
+ * software, its quality, accuracy, merchantability, or fitness for a
+ * particular purpose. As a result, this software is provided "as is,"
+ * and you, its user, are assuming the entire risk as to its quality
+ * and accuracy.
+ *
+ * This code may be used and freely distributed as long as it includes
+ * this copyright notice and the warranty information.
+ *
+ * Machine-independent I/O routines for 8-, 16-, 24-, and 32-bit integers.
+ *
+ * Motorola processors (Macintosh, Sun, Sparc, MIPS, etc)
+ * pack bytes from high to low (they are big-endian).
+ * Use the HighLow routines to match the native format
+ * of these machines.
+ *
+ * Intel-like machines (PCs, Sequent)
+ * pack bytes from low to high (the are little-endian).
+ * Use the LowHigh routines to match the native format
+ * of these machines.
+ *
+ * These routines have been tested on the following machines:
+ * Apple Macintosh, MPW 3.1 C compiler
+ * Apple Macintosh, THINK C compiler
+ * Silicon Graphics IRIS, MIPS compiler
+ * Cray X/MP and Y/MP
+ * Digital Equipment VAX
+ *
+ *
+ * Implemented by Malcolm Slaney and Ken Turkowski.
+ *
+ * Malcolm Slaney contributions during 1988-1990 include big- and little-
+ * endian file I/O, conversion to and from Motorola's extended 80-bit
+ * floating-point format, and conversions to and from IEEE single-
+ * precision floating-point format.
+ *
+ * In 1991, Ken Turkowski implemented the conversions to and from
+ * IEEE double-precision format, added more precision to the extended
+ * conversions, and accommodated conversions involving +/- infinity,
+ * NaN's, and denormalized numbers.
+ *
+ * $Id: portableio.h,v 1.4 2005/11/01 13:01:57 robert Exp $
+ */
+
+#include <stdio.h>
+
+#ifndef __cplusplus
+# define CLINK
+#else
+# define CLINK "C"
+#endif
+
+extern CLINK int ReadByte(FILE * fp);
+extern CLINK int Read16BitsLowHigh(FILE * fp);
+extern CLINK int Read16BitsHighLow(FILE * fp);
+extern CLINK void Write8Bits(FILE * fp, int i);
+extern CLINK void Write16BitsLowHigh(FILE * fp, int i);
+extern CLINK void Write16BitsHighLow(FILE * fp, int i);
+extern CLINK int Read24BitsHighLow(FILE * fp);
+extern CLINK int Read32Bits(FILE * fp);
+extern CLINK int Read32BitsHighLow(FILE * fp);
+extern CLINK void Write32Bits(FILE * fp, int i);
+extern CLINK void Write32BitsLowHigh(FILE * fp, int i);
+extern CLINK void Write32BitsHighLow(FILE * fp, int i);
+extern CLINK void ReadBytes(FILE * fp, char *p, int n);
+extern CLINK void ReadBytesSwapped(FILE * fp, char *p, int n);
+extern CLINK void WriteBytes(FILE * fp, char *p, int n);
+extern CLINK void WriteBytesSwapped(FILE * fp, char *p, int n);
+extern CLINK double ReadIeeeFloatHighLow(FILE * fp);
+extern CLINK double ReadIeeeFloatLowHigh(FILE * fp);
+extern CLINK double ReadIeeeDoubleHighLow(FILE * fp);
+extern CLINK double ReadIeeeDoubleLowHigh(FILE * fp);
+extern CLINK double ReadIeeeExtendedHighLow(FILE * fp);
+extern CLINK double ReadIeeeExtendedLowHigh(FILE * fp);
+extern CLINK void WriteIeeeFloatLowHigh(FILE * fp, double num);
+extern CLINK void WriteIeeeFloatHighLow(FILE * fp, double num);
+extern CLINK void WriteIeeeDoubleLowHigh(FILE * fp, double num);
+extern CLINK void WriteIeeeDoubleHighLow(FILE * fp, double num);
+extern CLINK void WriteIeeeExtendedLowHigh(FILE * fp, double num);
+extern CLINK void WriteIeeeExtendedHighLow(FILE * fp, double num);
+
+#define Read32BitsLowHigh(f) Read32Bits(f)
+#define WriteString(f,s) fwrite(s,strlen(s),sizeof(char),f)
+#endif
diff --git a/lib/liblame/frontend/rtp.c b/lib/liblame/frontend/rtp.c
new file mode 100644
index 0000000000..b914a63eb2
--- /dev/null
+++ b/lib/liblame/frontend/rtp.c
@@ -0,0 +1,385 @@
+/* $Id: rtp.c,v 1.16.8.1 2008/08/05 14:16:06 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#ifndef __GNUC__
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+#pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca();
+# endif
+# endif
+# endif
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else
+# ifndef HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+char *strchr(), *strrchr();
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# define memmove(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "console.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+struct rtpbits {
+ int sequence:16; /* sequence number: random */
+ int pt:7; /* payload type: 14 for MPEG audio */
+ int m:1; /* marker: 0 */
+ int cc:4; /* number of CSRC identifiers: 0 */
+ int x:1; /* number of extension headers: 0 */
+ int p:1; /* is there padding appended: 0 */
+ int v:2; /* version: 2 */
+};
+
+struct rtpheader { /* in network byte order */
+ struct rtpbits b;
+ int timestamp; /* start: random */
+ int ssrc; /* random */
+ int iAudioHeader; /* =0?! */
+};
+
+void
+initrtp(struct rtpheader *foo)
+{
+ foo->b.v = 2;
+ foo->b.p = 0;
+ foo->b.x = 0;
+ foo->b.cc = 0;
+ foo->b.m = 0;
+ foo->b.pt = 14; /* MPEG Audio */
+#ifdef FEFE
+ foo->b.sequence = 42;
+ foo->timestamp = 0;
+#else
+ foo->b.sequence = rand() & 65535;
+ foo->timestamp = rand();
+#endif
+ foo->ssrc = rand();
+ foo->iAudioHeader = 0;
+}
+
+int
+sendrtp(int fd, struct sockaddr_in *sSockAddr, struct rtpheader *foo, const void *data, int len)
+{
+ char *buf = alloca(len + sizeof(struct rtpheader));
+ int *cast = (int *) foo;
+ int *outcast = (int *) buf;
+ outcast[0] = htonl(cast[0]);
+ outcast[1] = htonl(cast[1]);
+ outcast[2] = htonl(cast[2]);
+ outcast[3] = htonl(cast[3]);
+ memmove(buf + sizeof(struct rtpheader), data, len);
+ return sendto(fd, buf, len + sizeof(*foo), 0,
+ (struct sockaddr *) sSockAddr, sizeof(*sSockAddr));
+/* return write(fd,buf,len+sizeof(*foo))==len+sizeof(*foo); */
+}
+
+/* create a sender socket. */
+int
+makesocket(char *szAddr, unsigned short port, unsigned char TTL, struct sockaddr_in *sSockAddr)
+{
+ int iRet, iLoop = 1;
+ struct sockaddr_in sin;
+ unsigned char cTtl = TTL;
+ char cLoop = 0;
+ unsigned int tempaddr;
+
+ int iSocket = socket(AF_INET, SOCK_DGRAM, 0);
+ if (iSocket < 0) {
+ error_printf("socket() failed.\n");
+ exit(1);
+ }
+
+ tempaddr = inet_addr(szAddr);
+ sSockAddr->sin_family = sin.sin_family = AF_INET;
+ sSockAddr->sin_port = sin.sin_port = htons(port);
+ sSockAddr->sin_addr.s_addr = tempaddr;
+
+ iRet = setsockopt(iSocket, SOL_SOCKET, SO_REUSEADDR, &iLoop, sizeof(int));
+ if (iRet < 0) {
+ error_printf("setsockopt SO_REUSEADDR failed\n");
+ exit(1);
+ }
+
+ if ((ntohl(tempaddr) >> 28) == 0xe) {
+ /* only set multicast parameters for multicast destination IPs */
+ iRet = setsockopt(iSocket, IPPROTO_IP, IP_MULTICAST_TTL, &cTtl, sizeof(char));
+ if (iRet < 0) {
+ error_printf("setsockopt IP_MULTICAST_TTL failed. multicast in kernel?\n");
+ exit(1);
+ }
+
+ cLoop = 1; /* !? */
+ iRet = setsockopt(iSocket, IPPROTO_IP, IP_MULTICAST_LOOP, &cLoop, sizeof(char));
+ if (iRet < 0) {
+ error_printf("setsockopt IP_MULTICAST_LOOP failed. multicast in kernel?\n");
+ exit(1);
+ }
+ }
+
+ return iSocket;
+}
+
+
+
+
+#if 0
+/* */
+/* code contributed by Anonymous source. Supposed to be much better */
+/* then original code, but only seems to run on windows with MSVC. */
+/* and I cannot test it */
+/* */
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+struct rtpbits {
+ int sequence:16; /* sequence number: random */
+ int pt:7; /* payload type: 14 for MPEG audio */
+ int m:1; /* marker: 0 */
+ int cc:4; /* number of CSRC identifiers: 0 */
+ int x:1; /* number of extension headers: 0 */
+ int p:1; /* is there padding appended: 0 */
+ int v:2; /* version: 2 */
+};
+
+struct rtpheader { /* in network byte order */
+ struct rtpbits b;
+ int timestamp; /* start: random */
+ int ssrc; /* random */
+ int iAudioHeader; /* =0?! */
+};
+
+void
+rtp_initialization(struct rtpheader *foo)
+{
+ foo->b.v = 2;
+ foo->b.p = 0;
+ foo->b.x = 0;
+ foo->b.cc = 0;
+ foo->b.m = 0;
+ foo->b.pt = 14; /* MPEG Audio */
+#ifdef FEFE
+ foo->b.sequence = 42;
+ foo->timestamp = 0;
+#else
+ foo->b.sequence = rand() & 65535;
+ foo->timestamp = rand();
+#endif
+ foo->ssrc = rand();
+ foo->iAudioHeader = 0;
+}
+
+int
+rtp_send(SOCKET s, struct rtpheader *foo, void *data, int len)
+{
+ char *buffer = malloc(len + sizeof(struct rtpheader));
+ int *cast = (int *) foo;
+ int *outcast = (int *) buffer;
+ int count, size;
+
+ outcast[0] = htonl(cast[0]);
+ outcast[1] = htonl(cast[1]);
+ outcast[2] = htonl(cast[2]);
+ outcast[3] = htonl(cast[3]);
+ memmove(buffer + sizeof(struct rtpheader), data, len);
+/* return sendto (fd,buf,len+sizeof(*foo),0,(struct sockaddr *)sSockAddr,sizeof(*sSockAddr)); */
+/* return write(fd,buf,len+sizeof(*foo))==len+sizeof(*foo); */
+ size = len + sizeof(*foo);
+ count = send(s, buffer, size, 0);
+ free(buffer);
+
+ return count != size;
+}
+
+/* create a sender socket. */
+int
+rtp_socket(SOCKET * ps, char *address, unsigned short port, int TTL)
+{
+/* int iRet ; */
+ int iLoop = 1;
+/* struct sockaddr_in sin ; */
+ char cTTL = (char) TTL;
+ char cLoop = 0;
+/* unsigned int tempaddr ; */
+ BOOL True = TRUE;
+ INT error;
+ char *c = "";
+ UINT ip;
+ PHOSTENT host;
+ SOCKET s;
+ SOCKADDR_IN source, dest;
+#if 0
+ int s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0) {
+ error_printf("socket() failed.\n");
+ exit(1);
+ }
+
+ tempaddr = inet_addr(address);
+ sSockAddr->sin_family = sin.sin_family = AF_INET;
+ sSockAddr->sin_port = sin.sin_port = htons(port);
+ sSockAddr->sin_addr.s_addr = tempaddr;
+
+ iRet = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &iLoop, sizeof(int));
+ if (iRet < 0) {
+ error_printf("setsockopt SO_REUSEADDR failed\n");
+ exit(1);
+ }
+
+ if ((ntohl(tempaddr) >> 28) == 0xe) {
+ /* only set multicast parameters for multicast destination IPs */
+ iRet = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &cTTL, sizeof(char));
+ if (iRet < 0) {
+ error_printf("setsockopt IP_MULTICAST_TTL failed. multicast in kernel?\n");
+ exit(1);
+ }
+
+ cLoop = 1; /* !? */
+ iRet = setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, &cLoop, sizeof(char));
+ if (iRet < 0) {
+ error_printf("setsockopt IP_MULTICAST_LOOP failed. multicast in kernel?\n");
+ exit(1);
+ }
+ }
+#endif
+ source.sin_family = AF_INET;
+ source.sin_addr.s_addr = htonl(INADDR_ANY);
+ source.sin_port = htons(0);
+
+ dest.sin_family = AF_INET;
+ dest.sin_addr.s_addr = inet_addr(address);
+
+ if (!strcmp(address, "255.255.255.255")) {
+ }
+ else if (dest.sin_addr.s_addr == INADDR_NONE) {
+ host = gethostbyname(address);
+
+ if (host) {
+ dest.sin_addr = *(PIN_ADDR) host->h_addr;
+ }
+ else {
+ printf("Unknown host %s\r\n", address);
+ return 1;
+ }
+ }
+
+ dest.sin_port = htons((u_short) port);
+
+ ip = ntohl(dest.sin_addr.s_addr);
+
+ if (IN_CLASSA(ip))
+ c = "class A";
+ if (IN_CLASSB(ip))
+ c = "class B";
+ if (IN_CLASSC(ip))
+ c = "class C";
+ if (IN_CLASSD(ip))
+ c = "class D";
+ if (ip == INADDR_LOOPBACK)
+ c = "loopback";
+ if (ip == INADDR_BROADCAST)
+ c = "broadcast";
+
+ s = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC);
+
+ if (s == INVALID_SOCKET) {
+ error = WSAGetLastError();
+ printf("socket () error %d\r\n", error);
+ return error;
+ }
+
+ error = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &True, sizeof(BOOL));
+
+ error = bind(s, (struct sockaddr *) &source, sizeof(source));
+
+ if (error == SOCKET_ERROR) {
+ error = WSAGetLastError();
+ printf("bind () error %d\r\n", error);
+ closesocket(s);
+ return error;
+ }
+
+ if (ip == INADDR_BROADCAST) {
+ printf("broadcast %s:%u %s\r\n", inet_ntoa(dest.sin_addr), ntohs(dest.sin_port), c);
+
+ error = setsockopt(s, SOL_SOCKET, SO_BROADCAST, (const char *)
+ &True, sizeof(BOOL));
+
+ if (error == SOCKET_ERROR) {
+ error = WSAGetLastError();
+ printf("setsockopt (%u, SOL_SOCKET, SO_BROADCAST, ...) error %d\r\n", s, error);
+ closesocket(s);
+ return error;
+ }
+ }
+
+ if (IN_CLASSD(ip)) {
+ printf("multicast %s:%u %s\r\n", inet_ntoa(dest.sin_addr), ntohs(dest.sin_port), c);
+
+/* error = setsockopt (s, IPPROTO_IP, IP_MULTICAST_TTL, (const char *) &TTL, sizeof (int)) ; */
+ error = setsockopt(s, IPPROTO_IP, 3, (const char *) &TTL, sizeof(int));
+
+ if (error == SOCKET_ERROR) {
+ error = WSAGetLastError();
+ printf("setsockopt (%u, IPPROTO_IP, IP_MULTICAST_TTL, ...) error %d\r\n", s, error);
+ closesocket(s);
+ return error;
+ }
+ }
+
+ error = connect(s, (PSOCKADDR) & dest, sizeof(SOCKADDR_IN));
+
+ if (error == SOCKET_ERROR) {
+ printf("connect: error %d\n", WSAGetLastError());
+ closesocket(s);
+ return error;
+ }
+
+ *ps = s;
+
+ return 0;
+}
+
+
+
+#endif
diff --git a/lib/liblame/frontend/rtp.h b/lib/liblame/frontend/rtp.h
new file mode 100644
index 0000000000..ce641b74d4
--- /dev/null
+++ b/lib/liblame/frontend/rtp.h
@@ -0,0 +1,38 @@
+#ifndef LAME_RTP_H
+#define LAME_RTP_H
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+struct rtpbits {
+ int sequence:16; /* sequence number: random */
+ int pt:7; /* payload type: 14 for MPEG audio */
+ int m:1; /* marker: 0 */
+ int cc:4; /* number of CSRC identifiers: 0 */
+ int x:1; /* number of extension headers: 0 */
+ int p:1; /* is there padding appended: 0 */
+ int v:2; /* version: 2 */
+};
+
+struct rtpheader { /* in network byte order */
+ struct rtpbits b;
+ int timestamp; /* start: random */
+ int ssrc; /* random */
+ int iAudioHeader; /* =0?! */
+};
+
+void initrtp(struct rtpheader *foo);
+int sendrtp(int fd, struct sockaddr_in *sSockAddr, struct rtpheader *foo, const void *data,
+ int len);
+int makesocket(char *szAddr, unsigned short port, unsigned char TTL,
+ struct sockaddr_in *sSockAddr);
+void rtp_output(const char *mp3buffer, int mp3size);
+
+#if 0
+int rtp_send(SOCKET s, struct rtpheader *foo, void *data, int len);
+
+int rtp_socket(SOCKET * ps, char *Address, unsigned short port, int TTL);
+#endif
+
+
+#endif
diff --git a/lib/liblame/frontend/timestatus.c b/lib/liblame/frontend/timestatus.c
new file mode 100644
index 0000000000..8152381b37
--- /dev/null
+++ b/lib/liblame/frontend/timestatus.c
@@ -0,0 +1,348 @@
+/*
+ * time status related function source file
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: timestatus.c,v 1.46 2008/04/12 18:18:06 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+
+/* Hope it works now, otherwise complain or flame ;-)
+ */
+
+
+#if 1
+# define SPEED_CHAR "x" /* character x */
+# define SPEED_MULT 1.
+#else
+# define SPEED_CHAR "%%"
+# define SPEED_MULT 100.
+#endif
+
+#include <assert.h>
+#include <time.h>
+#include <string.h>
+
+#include "lame.h"
+#include "main.h"
+#include "lametime.h"
+#include "timestatus.h"
+
+#if defined(BRHIST)
+# include "brhist.h"
+#endif
+#include "console.h"
+
+#ifdef WITH_DMALLOC
+#include <dmalloc.h>
+#endif
+
+typedef struct {
+ double last_time; /* result of last call to clock */
+ double elapsed_time; /* total time */
+ double estimated_time; /* estimated total duration time [s] */
+ double speed_index; /* speed relative to realtime coding [100%] */
+} timestatus_t;
+
+/*
+ * Calculates from the input (see below) the following values:
+ * - total estimated time
+ * - a speed index
+ */
+
+static void
+ts_calc_times(timestatus_t * const tstime, /* tstime->elapsed_time: elapsed time */
+ const int sample_freq, /* sample frequency [Hz/kHz] */
+ const int frameNum, /* Number of the current Frame */
+ const int totalframes, /* total umber of Frames */
+ const int framesize)
+{ /* Size of a frame [bps/kbps] */
+ assert(sample_freq >= 8000 && sample_freq <= 48000);
+
+ if (frameNum > 0 && tstime->elapsed_time > 0) {
+ tstime->estimated_time = tstime->elapsed_time * totalframes / frameNum;
+ tstime->speed_index = framesize * frameNum / (sample_freq * tstime->elapsed_time);
+ }
+ else {
+ tstime->estimated_time = 0.;
+ tstime->speed_index = 0.;
+ }
+}
+
+/* Decomposes a given number of seconds into a easy to read hh:mm:ss format
+ * padded with an additional character
+ */
+
+static void
+ts_time_decompose(const unsigned long time_in_sec, const char padded_char)
+{
+ const unsigned long hour = time_in_sec / 3600;
+ const unsigned int min = time_in_sec / 60 % 60;
+ const unsigned int sec = time_in_sec % 60;
+
+ if (hour == 0)
+ console_printf(" %2u:%02u%c", min, sec, padded_char);
+ else if (hour < 100)
+ console_printf("%2lu:%02u:%02u%c", hour, min, sec, padded_char);
+ else
+ console_printf("%6lu h%c", hour, padded_char);
+}
+
+static void
+timestatus(const lame_global_flags * const gfp)
+{
+ static timestatus_t real_time;
+ static timestatus_t proc_time;
+ int percent;
+ static int init = 0; /* What happens here? A work around instead of a bug fix ??? */
+ double tmx, delta;
+ int samp_rate = lame_get_out_samplerate(gfp)
+ , frameNum = lame_get_frameNum(gfp)
+ , totalframes = lame_get_totalframes(gfp)
+ , framesize = lame_get_framesize(gfp)
+ ;
+
+ if (totalframes < frameNum) {
+ totalframes = frameNum;
+ }
+ if (frameNum == 0) {
+ real_time.last_time = GetRealTime();
+ proc_time.last_time = GetCPUTime();
+ real_time.elapsed_time = 0;
+ proc_time.elapsed_time = 0;
+ }
+
+ /* we need rollover protection for GetCPUTime, and maybe GetRealTime(): */
+ tmx = GetRealTime();
+ delta = tmx - real_time.last_time;
+ if (delta < 0)
+ delta = 0; /* ignore, clock has rolled over */
+ real_time.elapsed_time += delta;
+ real_time.last_time = tmx;
+
+
+ tmx = GetCPUTime();
+ delta = tmx - proc_time.last_time;
+ if (delta < 0)
+ delta = 0; /* ignore, clock has rolled over */
+ proc_time.elapsed_time += delta;
+ proc_time.last_time = tmx;
+
+ if (frameNum == 0 && init == 0) {
+ console_printf("\r"
+ " Frame | CPU time/estim | REAL time/estim | play/CPU | ETA \n"
+ " 0/ ( 0%%)| 0:00/ : | 0:00/ : | "
+ SPEED_CHAR "| : \r"
+ /* , Console_IO.str_clreoln, Console_IO.str_clreoln */ );
+ init = 1;
+ return;
+ }
+ /* reset init counter for next time we are called with frameNum==0 */
+ if (frameNum > 0)
+ init = 0;
+
+ ts_calc_times(&real_time, samp_rate, frameNum, totalframes, framesize);
+ ts_calc_times(&proc_time, samp_rate, frameNum, totalframes, framesize);
+
+ if (frameNum < totalframes) {
+ percent = (int) (100. * frameNum / totalframes + 0.5);
+ }
+ else {
+ percent = 100;
+ }
+
+ console_printf("\r%6i/%-6i", frameNum, totalframes);
+ console_printf(percent < 100 ? " (%2d%%)|" : "(%3.3d%%)|", percent);
+ ts_time_decompose((unsigned long) proc_time.elapsed_time, '/');
+ ts_time_decompose((unsigned long) proc_time.estimated_time, '|');
+ ts_time_decompose((unsigned long) real_time.elapsed_time, '/');
+ ts_time_decompose((unsigned long) real_time.estimated_time, '|');
+ console_printf(proc_time.speed_index <= 1. ?
+ "%9.4f" SPEED_CHAR "|" : "%#9.5g" SPEED_CHAR "|",
+ SPEED_MULT * proc_time.speed_index);
+ ts_time_decompose((unsigned long) (real_time.estimated_time - real_time.elapsed_time), ' ');
+}
+
+static void
+timestatus_finish(void)
+{
+ console_printf("\n");
+}
+
+
+void
+encoder_progress_begin( lame_global_flags const* gf
+ , char const* inPath
+ , char const* outPath
+ )
+{
+ if (silent < 10) {
+ lame_print_config(gf); /* print useful information about options being used */
+
+ console_printf("Encoding %s%s to %s\n",
+ strcmp(inPath, "-") ? inPath : "<stdin>",
+ strlen(inPath) + strlen(outPath) < 66 ? "" : "\n ",
+ strcmp(outPath, "-") ? outPath : "<stdout>");
+
+ console_printf("Encoding as %g kHz ", 1.e-3 * lame_get_out_samplerate(gf));
+
+ {
+ static const char *mode_names[2][4] = {
+ {"stereo", "j-stereo", "dual-ch", "single-ch"},
+ {"stereo", "force-ms", "dual-ch", "single-ch"}
+ };
+ switch (lame_get_VBR(gf)) {
+ case vbr_rh:
+ console_printf("%s MPEG-%u%s Layer III VBR(q=%g) qval=%i\n",
+ mode_names[lame_get_force_ms(gf)][lame_get_mode(gf)],
+ 2 - lame_get_version(gf),
+ lame_get_out_samplerate(gf) < 16000 ? ".5" : "",
+ lame_get_VBR_quality(gf),
+ lame_get_quality(gf));
+ break;
+ case vbr_mt:
+ case vbr_mtrh:
+ console_printf("%s MPEG-%u%s Layer III VBR(q=%g)\n",
+ mode_names[lame_get_force_ms(gf)][lame_get_mode(gf)],
+ 2 - lame_get_version(gf),
+ lame_get_out_samplerate(gf) < 16000 ? ".5" : "",
+ lame_get_VBR_quality(gf));
+ break;
+ case vbr_abr:
+ console_printf("%s MPEG-%u%s Layer III (%gx) average %d kbps qval=%i\n",
+ mode_names[lame_get_force_ms(gf)][lame_get_mode(gf)],
+ 2 - lame_get_version(gf),
+ lame_get_out_samplerate(gf) < 16000 ? ".5" : "",
+ 0.1 * (int) (10. * lame_get_compression_ratio(gf) + 0.5),
+ lame_get_VBR_mean_bitrate_kbps(gf),
+ lame_get_quality(gf));
+ break;
+ default:
+ console_printf("%s MPEG-%u%s Layer III (%gx) %3d kbps qval=%i\n",
+ mode_names[lame_get_force_ms(gf)][lame_get_mode(gf)],
+ 2 - lame_get_version(gf),
+ lame_get_out_samplerate(gf) < 16000 ? ".5" : "",
+ 0.1 * (int) (10. * lame_get_compression_ratio(gf) + 0.5),
+ lame_get_brate(gf),
+ lame_get_quality(gf));
+ break;
+ }
+ }
+
+ if (silent <= -10) {
+ lame_print_internals(gf);
+ }
+ }
+}
+
+void
+encoder_progress( lame_global_flags const* gf )
+{
+ if (silent <= 0) {
+ int const frames = lame_get_frameNum(gf);
+ if (update_interval <= 0) { /* most likely --disptime x not used */
+ if ((frames % 100) != 0) { /* true, most of the time */
+ return;
+ }
+ }
+ else {
+ static double last_time = 0.0;
+ if (frames != 0 && frames != 9) {
+ double const act = GetRealTime();
+ double const dif = act - last_time;
+ if (dif >= 0 && dif < update_interval) {
+ return;
+ }
+ }
+ last_time = GetRealTime(); /* from now! disp_time seconds */
+ }
+#ifdef BRHIST
+ if (brhist) {
+ brhist_jump_back();
+ }
+#endif
+ timestatus(gf);
+#ifdef BRHIST
+ if (brhist) {
+ brhist_disp(gf);
+ }
+#endif
+ console_flush();
+ }
+}
+
+void
+encoder_progress_end( lame_global_flags const* gf )
+{
+ if (silent <= 0) {
+#ifdef BRHIST
+ if (brhist) {
+ brhist_jump_back();
+ }
+#endif
+ timestatus(gf);
+#ifdef BRHIST
+ if (brhist) {
+ brhist_disp(gf);
+ }
+#endif
+ timestatus_finish();
+ }
+}
+
+
+/* these functions are used in get_audio.c */
+
+void
+decoder_progress(const mp3data_struct * const mp3data)
+{
+ static int last;
+ console_printf("\rFrame#%6i/%-6i %3i kbps",
+ mp3data->framenum, mp3data->totalframes, mp3data->bitrate);
+
+ /* Programmed with a single frame hold delay */
+ /* Attention: static data */
+
+ /* MP2 Playback is still buggy. */
+ /* "'00' subbands 4-31 in intensity_stereo, bound==4" */
+ /* is this really intensity_stereo or is it MS stereo? */
+
+ if (mp3data->mode == JOINT_STEREO) {
+ int curr = mp3data->mode_ext;
+ console_printf(" %s %c",
+ curr & 2 ? last & 2 ? " MS " : "LMSR" : last & 2 ? "LMSR" : "L R",
+ curr & 1 ? last & 1 ? 'I' : 'i' : last & 1 ? 'i' : ' ');
+ last = curr;
+ }
+ else {
+ console_printf(" ");
+ last = 0;
+ }
+/* console_printf ("%s", Console_IO.str_clreoln ); */
+ console_printf(" \b\b\b\b\b\b\b\b");
+}
+
+void
+decoder_progress_finish()
+{
+ console_printf("\n");
+}
diff --git a/lib/liblame/frontend/timestatus.h b/lib/liblame/frontend/timestatus.h
new file mode 100644
index 0000000000..30cc59b224
--- /dev/null
+++ b/lib/liblame/frontend/timestatus.h
@@ -0,0 +1,34 @@
+/*
+ * time status related function include file
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_TIMESTATUS_H
+#define LAME_TIMESTATUS_H
+
+void encoder_progress_begin( lame_global_flags const* gfp
+ , char const* inpath
+ , char const* outpath );
+void encoder_progress( lame_global_flags const* gfp );
+void encoder_progress_end(lame_global_flags const* gfp);
+
+void decoder_progress(const mp3data_struct * const);
+void decoder_progress_finish();
+
+#endif /* LAME_TIMESTATUS_H */