diff options
Diffstat (limited to 'lib/liblame/frontend')
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 */ |