diff options
Diffstat (limited to 'misc')
-rw-r--r-- | misc/.indent.pro | 32 | ||||
-rw-r--r-- | misc/Lame.vbs | 158 | ||||
-rw-r--r-- | misc/Makefile.am | 27 | ||||
-rw-r--r-- | misc/Makefile.in | 503 | ||||
-rw-r--r-- | misc/abx.c | 1323 | ||||
-rw-r--r-- | misc/ath.c | 839 | ||||
-rwxr-xr-x | misc/auenc | 39 | ||||
-rwxr-xr-x | misc/depcomp | 530 | ||||
-rw-r--r-- | misc/lame4dos.bat | 41 | ||||
-rw-r--r-- | misc/lameGUI.html | 403 | ||||
-rw-r--r-- | misc/lameid3.pl | 55 | ||||
-rwxr-xr-x | misc/mlame | 195 | ||||
-rw-r--r-- | misc/mlame_corr.c | 220 | ||||
-rwxr-xr-x | misc/mugeco.sh | 137 | ||||
-rw-r--r-- | misc/scalartest.c | 166 |
15 files changed, 4668 insertions, 0 deletions
diff --git a/misc/.indent.pro b/misc/.indent.pro new file mode 100644 index 0000000..51639a1 --- /dev/null +++ b/misc/.indent.pro @@ -0,0 +1,32 @@ +// INDENT setup file: +// basically the GNU-style of coding +// +--no-blank-lines-after-declarations +--blank-lines-after-procedures +--no-blank-lines-after-commas +--break-before-boolean-operator +--braces-on-if-line // after +--brace-indent2 // 2 <- +--braces-on-struct-decl-line // +--comment-indentation25 // 32 +--declaration-comment-column30 // 1? +--no-comment-delimiters-on-blank-lines +--dont-cuddle-else +--else-endif-column1 +--space-after-cast +--declaration-indentation8 // 2 +-ndj // what does this mean? +--dont-format-first-column-comments +--dont-format-comments +--honour-newlines +--indent-level4 // 2 +--parameter-indentation6 // 5 +--continue-at-parentheses +--space-after-procedure-calls +--procnames-start-lines +--dont-star-comments +--leave-optional-blank-lines + + +--tab-size0 +--line-length80 diff --git a/misc/Lame.vbs b/misc/Lame.vbs new file mode 100644 index 0000000..4e42002 --- /dev/null +++ b/misc/Lame.vbs @@ -0,0 +1,158 @@ +' lame.vbs WindowsScript wrapper v0.5, 06/15/2001 +' $id$ +' +' *Purpose* +' Use this WindowsScript to encode WAVs using drag&drop: +' 0. make sure you have windows script host v5.1 on your system +' (enter 'cscript' in a DOS-Box and compare version number) +' 1. adjust the path settings below to fit your needs +' 2a. put this file somewhere on the desktop +' 3a. drag one or more wav-files on the icon and watch them being lamed. +' +' 2b. start->execute, enter "sendto", drag the script or a link to it in +' sendto window (adjust names and icon as you like) +' 3b. select wave-file(s) and send it via the send-to menu to LAME! +' +' You may wish to create copies of this file with different options set. +' +' If you would like a GUI: try to enable the HTML UI (see below) +' +' Ralf Kempkens, ralf.kempkens@epost.de +' +' +' *History* +' V0.5 * lame.vbs will automatically decode if the file has a .mp3 extension +' * now explicitly refuses to accept folders +' V0.4 * creates single .mp3 extensions, now ID3 options in HTML interface +' V0.3 * fixed bug that prevented lame.exe to be located in a path that +' contained a space +' * experimental HTML UI support (disabled by default) +' V0.2 added multiple file support +' V0.1 initial release + +' *** change path to your needs *** + path = "D:\Audio\Lame\Lame386\" '!!! must end with a backslash !!! + lame = "lame.exe" + +' *** change default options to your needs *** + opts = "--preset hifi" + +' *** HTML GUI (experimental) *** + useGUI = False +' it set to True, opens file lameGUI.html residing in the same path as lame.exe +' to choose options. Please look at the example HTML-file for further information. + +' no changes needed below this line +' ########################################################################## +Dim wsh, args, infile, fs +title="LAME Script" + +' get input files +Set wsh = WScript.CreateObject("WScript.Shell") +Set args = WScript.Arguments +If args.Count = 0 Then + MsgBox "LAME mp3 encoder/decoder frontend script." & vbCR & _ + "Please use drag & drop to specify input files.", vbInformation, title + WScript.Quit +End If + +' check path +Set fso = CreateObject("Scripting.FileSystemObject") +If Not fso.FileExists(path & lame) Then + MsgBox "Could not find LAME!" & vbCR & "(looked for '" & path & lame & "')", vbCritical, title + WScript.Quit +End If + +' start GUI +if useGUI Then + set ie=WScript.CreateObject("InternetExplorer.Application", "ie_") + ie.navigate(path & "lameGUI.html") + do + WScript.Sleep 100 + loop until ie.ReadyState=4 'wait for GUI + + ie.Width=640 + ie.Height=600 + ie.Toolbar=false + ie.Statusbar=false + ie.visible=true + + 'link to GUI + set document=ie.document + document.forms.lameform.okbutton.onClick=GetRef("okbutton") + + 'wait for user pressing ok... + do + WScript.Sleep 300 + loop until process +end if + +'process files +For i = 0 To args.Count-1 + infile = args(i) + ' check input file + If fso.FolderExists(infile) Then + MsgBox "'" & infile & "' is a folder!" & vbCR & _ + title & " only handles proper files.", vbInformation, title + Else + If Not fso.FileExists(infile) Then + MsgBox "Error opening input-file" & vbCR & "'" & infile & "'", vbCritical , title + Else + ' run lame + If(LCase(getExtension(infile))="mp3") Then 'decode + ret = wsh.Run(Chr(34) & path & lame & CHR(34) & " --decode " & _ + Chr(34) & infile & Chr(34) & Chr(32) & Chr(34) & _ + getBasename(infile) & ".wav" & Chr(34), 1, True) + Else ' encode + ret = wsh.Run(Chr(34) & path & lame & CHR(34) & Chr(32) & opts & Chr(32) & _ + Chr(34) & infile & Chr(34) & Chr(32) & Chr(34) & _ + getBasename(infile) & ".mp3" & Chr(34), 1, True) + End If + ' diagnostics + Select Case ret + Case (0) 'okeydokey + Case (-1) + MsgBox "LAME aborted by user!", vbExclamation, title + Case (1) + MsgBox "Error returned by LAME!" & vbCR & "(Check LAME options and input file formats.)" & vbCR & "Used Options: " & opts, vbCritical, title + Case Else + MsgBox "Received unknown LAME return-code: " & ret, vbCritical, title + End Select + End If + End If +Next + +WScript.Quit +' ******************************************************************* +' utility functions + +Function getBasename(filespec) + Dim fso + Set fso = CreateObject("Scripting.FileSystemObject") + Set f = fso.GetFile(filespec) + + getBasename = f.ParentFolder & "\" & fso.GetBaseName(filespec) +End Function + +Function getExtension(filespec) + Dim fso + Set fso = CreateObject("Scripting.FileSystemObject") + Set f = fso.GetFile(filespec) + + getExtension = fso.GetExtensionName(filespec) +End Function + +' ******************************************************************* +' manage link to IE HTML-interface + +sub okbutton + 'process inputs + opts=document.all.lameoptions.Value + ie.Quit + MsgBox "LAME options:" & vbCR & opts, vbInformation, title +end sub + +sub ie_onQuit + process=True +end sub +'eof diff --git a/misc/Makefile.am b/misc/Makefile.am new file mode 100644 index 0000000..fc13a49 --- /dev/null +++ b/misc/Makefile.am @@ -0,0 +1,27 @@ +## $Id: Makefile.am,v 1.10 2002/01/25 11:23:23 aleidinger Exp $ + +include $(top_srcdir)/Makefile.am.global + +EXTRA_PROGRAMS = abx ath scalartest + +CLEANFILES = $(EXTRA_PROGRAMS) + +EXTRA_SCRIPTS = \ + auenc \ + lameid3.pl \ + mugeco.sh \ + mlame + +EXTRA_DIST = \ + $(EXTRA_SCRIPTS) \ + Lame.vbs \ + lameGUI.html \ + lame4dos.bat \ + mlame_corr.c + +abx_SOURCES = abx.c + +ath_SOURCES = ath.c + +scalartest_SOURCES = scalartest.c + diff --git a/misc/Makefile.in b/misc/Makefile.in new file mode 100644 index 0000000..8727ac0 --- /dev/null +++ b/misc/Makefile.in @@ -0,0 +1,503 @@ +# 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 = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/Makefile.am.global depcomp +EXTRA_PROGRAMS = abx$(EXEEXT) ath$(EXEEXT) scalartest$(EXEEXT) +subdir = misc +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_abx_OBJECTS = abx$U.$(OBJEXT) +abx_OBJECTS = $(am_abx_OBJECTS) +abx_LDADD = $(LDADD) +abx_DEPENDENCIES = +am_ath_OBJECTS = ath$U.$(OBJEXT) +ath_OBJECTS = $(am_ath_OBJECTS) +ath_LDADD = $(LDADD) +ath_DEPENDENCIES = +am_scalartest_OBJECTS = scalartest$U.$(OBJEXT) +scalartest_OBJECTS = $(am_scalartest_OBJECTS) +scalartest_LDADD = $(LDADD) +scalartest_DEPENDENCIES = +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 = $(abx_SOURCES) $(ath_SOURCES) $(scalartest_SOURCES) +DIST_SOURCES = $(abx_SOURCES) $(ath_SOURCES) $(scalartest_SOURCES) +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@ +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@ +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 = @INCLUDES@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDADD = @LDADD@ +LDFLAGS = @LDFLAGS@ +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 +CLEANFILES = $(EXTRA_PROGRAMS) +EXTRA_SCRIPTS = \ + auenc \ + lameid3.pl \ + mugeco.sh \ + mlame + +EXTRA_DIST = \ + $(EXTRA_SCRIPTS) \ + Lame.vbs \ + lameGUI.html \ + lame4dos.bat \ + mlame_corr.c + +abx_SOURCES = abx.c +ath_SOURCES = ath.c +scalartest_SOURCES = scalartest.c +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 misc/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign misc/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 +abx$(EXEEXT): $(abx_OBJECTS) $(abx_DEPENDENCIES) + @rm -f abx$(EXEEXT) + $(LINK) $(abx_OBJECTS) $(abx_LDADD) $(LIBS) +ath$(EXEEXT): $(ath_OBJECTS) $(ath_DEPENDENCIES) + @rm -f ath$(EXEEXT) + $(LINK) $(ath_OBJECTS) $(ath_LDADD) $(LIBS) +scalartest$(EXEEXT): $(scalartest_OBJECTS) $(scalartest_DEPENDENCIES) + @rm -f scalartest$(EXEEXT) + $(LINK) $(scalartest_OBJECTS) $(scalartest_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)/abx$U.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ath$U.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scalartest$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 $@ $< +abx_.c: abx.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/abx.c; then echo $(srcdir)/abx.c; else echo abx.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@ +ath_.c: ath.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/ath.c; then echo $(srcdir)/ath.c; else echo ath.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@ +scalartest_.c: scalartest.c $(ANSI2KNR) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/scalartest.c; then echo $(srcdir)/scalartest.c; else echo scalartest.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@ +abx_.$(OBJEXT) abx_.lo ath_.$(OBJEXT) ath_.lo scalartest_.$(OBJEXT) \ +scalartest_.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 +installdirs: +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-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-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: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean 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-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 + + +# end global section +# 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/misc/abx.c b/misc/abx.c new file mode 100644 index 0000000..c06364d --- /dev/null +++ b/misc/abx.c @@ -0,0 +1,1323 @@ +/* + * Usage: abx original_file test_file + * + * Ask you as long as the probability is below the given percentage that + * you recognize differences + * + * Example: abx music.wav music.mp3 + * abx music.wav music.mp3 --help + * + * Note: several 'decoding' utilites must be on the 'right' place + * + * Bugs: + * fix path of decoding utilities + * only 16 bit support + * only support of the same sample frequency + * no exact WAV file header analysis + * no mouse or joystick support + * don't uses functionality of ath.c + * only 2 files are comparable + * worse user interface + * quick & dirty hack + * wastes memory + * compile time warnings + * buffer overruns possible + * no dithering if recalcs are necessary + * correlation only done with one channel (2 channels, sum, what is better?) + * lowpass+highpass filtering (300 Hz+2*5 kHz) before delay+amplitude corr + * cross fade at start/stop + * non portable keyboard + * fade out on quit, fade in on start + * level/delay ajustment should be switchable + * pause key missing + * problems with digital silence files (division by 0) + * Gr��e cross corr fenster 2^16...18 + * Stellensuche, ab 0*len oder 0.1*len oder 0.25*len, nach Effektiv oder Spitzenwert + * Absturz bei LPAC feeding, warum? + * Als 'B' beim Ratespiel sollte auch '0'...'9' verwendbar sein + * Oder mit einem Filter 300 Hz...3 kHz vorher filtern? + * Multiple encoded differenziertes Signal + * Amplitudenanpassung schaltbar machen? + * Direkt auf der Kommandozeile kodieren: + * abx "test.wav" "!lame -b128 test.wav -" + */ + +// If the program should increase it priority while playing define USE_NICE. +// Program must be installed SUID root. Decompressing phase is using NORMAL priority +#define USE_NICE + +// Not only increase priority but change to relatime scheduling. Program must be installed SUID root +#define USE_REALTIME + +// Path of the programs: mpg123, mppdec, faad, ac3dec, ogg123, lpac, shorten, MAC, flac +//#define PATH_OF_EXTERNAL_TOOLS_FOR_UNCOMPRESSING "/usr/local/bin/" +#define PATH_OF_EXTERNAL_TOOLS_FOR_UNCOMPRESSING "" + + +#if defined HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <ctype.h> +#include <fcntl.h> +#include <limits.h> +#include <math.h> +#include <memory.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <time.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/types.h> + +#define MAX (1<<17) + +#if defined HAVE_SYS_SOUNDCARD_H +# include <sys/soundcard.h> +#elif defined HAVE_LINUX_SOUNDCARD_H +# include <linux/soundcard.h> +#else +# include <linux/soundcard.h> /* stand alone compilable for my tests */ +#endif + +#if defined USE_NICE +# include <sys/resource.h> +#endif +#if defined USE_REALTIME +# include <sched.h> +#endif + +#define BF ((freq)/25) +#define MAX_LEN (210 * 44100) +#define DMA_SAMPLES 512 /* My Linux driver uses a DMA buffer of 65536*16 bit, which is 32768 samples in 16 bit stereo mode */ + +void Set_Realtime ( void ) +{ +#if defined USE_REALTIME + struct sched_param sp; + int ret; + + memset ( &sp, 0, sizeof(sp) ); + seteuid ( 0 ); + sp.sched_priority = sched_get_priority_min ( SCHED_FIFO ); + ret = sched_setscheduler ( 0, SCHED_RR, &sp ); + seteuid ( getuid() ); +#endif + +#if defined USE_NICE + seteuid ( 0 ); + setpriority ( PRIO_PROCESS, getpid(), -20 ); + seteuid ( getuid() ); +#endif +} + +int verbose = 0; + +static struct termios stored_settings; + + +void reset ( void ) +{ + tcsetattr ( 0, TCSANOW, &stored_settings ); +} + + +void set ( void ) +{ + struct termios new_settings; + + tcgetattr ( 0, &stored_settings ); + new_settings = stored_settings; + + new_settings.c_lflag &= ~ECHO; + /* Disable canonical mode, and set buffer size to 1 byte */ + new_settings.c_lflag &= ~ICANON; + new_settings.c_cc[VTIME] = 0; + new_settings.c_cc[VMIN] = 1; + + tcsetattr(0,TCSANOW,&new_settings); + return; +} + + +int sel ( void ) +{ + struct timeval t; + fd_set fd [1]; + int ret; + unsigned char c; + + FD_SET (0, fd); + t.tv_sec = 0; + t.tv_usec = 0; + + ret = select ( 1, fd, NULL, NULL, &t ); + + switch ( ret ) { + case 0: + return -1; + case 1: + ret = read (0, &c, 1); + return ret == 1 ? c : -1; + default: + return -2; + } +} + +#define FFT_ERR_OK 0 // no error +#define FFT_ERR_LD 1 // len is not a power of 2 +#define FFT_ERR_MAX 2 // len too large + +typedef float f_t; +typedef f_t compl [2]; +compl root [MAX >> 1]; // Sinus-/Kosinustabelle +size_t shuffle [MAX >> 1] [2]; // Shuffle-Tabelle +size_t shuffle_len; + +// Bitinversion + +size_t swap ( size_t number, int bits ) +{ + size_t ret; + for ( ret = 0; bits--; number >>= 1 ) { + ret = ret + ret + (number & 1); + } + return ret; +} + +// Bestimmen des Logarithmus dualis + +int ld ( size_t number ) +{ + size_t i; + for ( i = 0; i < sizeof(size_t)*CHAR_BIT; i++ ) + if ( ((size_t)1 << i) == number ) + return i; + return -1; +} + +// Die eigentliche FFT + +int fft ( compl* fn, const size_t newlen ) +{ + static size_t len = 0; + static int bits = 0; + size_t i; + size_t j; + size_t k; + size_t p; + + /* Tabellen initialisieren */ + + if ( newlen != len ) { + len = newlen; + + if ( (bits=ld(len)) == -1 ) + return FFT_ERR_LD; + + for ( i = 0; i < len; i++ ) { + j = swap ( i, bits ); + if ( i < j ) { + shuffle [shuffle_len] [0] = i; + shuffle [shuffle_len] [1] = j; + shuffle_len++; + } + } + for ( i = 0; i < (len>>1); i++ ) { + double x = (double) swap ( i+i, bits ) * 2*M_PI/len; + root [i] [0] = cos (x); + root [i] [1] = sin (x); + } + } + + /* Eigentliche Transformation */ + + p = len >> 1; + do { + f_t* bp = (f_t*) root; + f_t* si = (f_t*) fn; + f_t* di = (f_t*) fn+p+p; + + do { + k = p; + do { + f_t mulr = bp[0]*di[0] - bp[1]*di[1]; + f_t muli = bp[1]*di[0] + bp[0]*di[1]; + + di[0] = si[0] - mulr; + di[1] = si[1] - muli; + si[0] += mulr; + si[1] += muli; + + si += 2, di += 2; + } while ( --k ); + si += p+p, di += p+p, bp += 2; + } while ( si < &fn[len][0] ); + } while (p >>= 1); + + /* Bitinversion */ + + for ( k = 0; k < shuffle_len; k++ ) { + f_t tmp; + i = shuffle [k] [0]; + j = shuffle [k] [1]; + tmp = fn [i][0]; fn [i][0] = fn [j][0]; fn [j][0] = tmp; + tmp = fn [i][1]; fn [i][1] = fn [j][1]; fn [j][1] = tmp; + } + + return FFT_ERR_OK; +} + +void printnumber ( long double x ) +{ + unsigned exp = 0; + + if ( x < 9.999995 ) fprintf ( stderr, "%7.5f", (double)x ); + else if ( x < 99.99995 ) fprintf ( stderr, "%7.4f", (double)x ); + else if ( x < 999.9995 ) fprintf ( stderr, "%7.3f", (double)x ); + else if ( x < 9999.995 ) fprintf ( stderr, "%7.2f", (double)x ); + else if ( x < 99999.95 ) fprintf ( stderr, "%7.1f", (double)x ); + else if ( x < 999999.5 ) fprintf ( stderr, "%6.0f.", (double)x ); + else if ( x < 9999999.5 ) fprintf ( stderr, "%7.0f", (double)x ); + else if ( x < 9.9995e9 ) { + while ( x >= 9.9995 ) exp++ , x /= 10; + fprintf ( stderr, "%5.3fe%01u", (double)x, exp ); + } else if ( x < 9.995e99 ) { + while ( x >= 9.5e6 ) exp+=6 , x /= 1.e6; + while ( x >= 9.995 ) exp++ , x /= 10; + fprintf ( stderr, "%4.2fe%02u", (double)x, exp ); + } else if ( x < 9.95e999L ) { + while ( x >= 9.5e18 ) exp+=18, x /= 1.e18; + while ( x >= 9.95 ) exp++ , x /= 10; + fprintf ( stderr, "%3.1fe%03u", (double)x, exp ); + } else { + while ( x >= 9.5e48 ) exp+=48, x /= 1.e48; + while ( x >= 9.5 ) exp++ , x /= 10; + fprintf ( stderr, "%1.0f.e%04u", (double)x, exp ); + } +} + +double logdual ( long double x ) +{ + unsigned exp = 0; + + while ( x >= 18446744073709551616. ) + x /= 18446744073709551616., exp += 64; + while ( x >= 256. ) + x /= 256., exp += 8; + while ( x >= 2. ) + x /= 2., exp += 1; + return exp + log (x)/log(2); +} + +int random_number ( void ) +{ + struct timeval t; + unsigned long val; + + gettimeofday ( &t, NULL ); + + val = t.tv_sec ^ t.tv_usec ^ rand(); + val ^= val >> 16; + val ^= val >> 8; + val ^= val >> 4; + val ^= val >> 2; + val ^= val >> 1; + + return val & 1; +} + +long double prob ( int last, int total ) +{ + long double sum = 0.; + long double tmp = 1.; + int i; + int j = total; + + if ( 2*last == total ) + return 1.; + if ( 2*last > total ) + last = total - last; + + for ( i = 0; i <= last; i++ ) { + sum += tmp; + tmp = tmp * (total-i) / (1+i); + while ( j > 0 && tmp > 1 ) + j--, sum *= 0.5, tmp *= 0.5; + } + while ( j > 0 ) + j--, sum *= 0.5; + + return 2.*sum; +} + + +void eval ( int right ) +{ + static int count = 0; + static int okay = 0; + long double val; + + count ++; + okay += right; + + val = 1.L / prob ( okay, count ); + + fprintf (stderr, " %s %5u/%-5u ", right ? "OK" : "- " , okay, count ); + printnumber (val); + if ( count > 1 ) + fprintf (stderr, " %4.2f bit", 0.01 * (int)(logdual(val) / (count-1) * 100.) ); + fprintf ( stderr, "\n" ); +} + + +typedef signed short sample_t; +typedef sample_t mono_t [1]; +typedef sample_t stereo_t [2]; +typedef struct { + unsigned long n; + long double x; + long double x2; + long double y; + long double y2; + long double xy; +} korr_t; + + +void analyze_stereo ( const stereo_t* p1, const stereo_t* p2, size_t len, korr_t* const k ) +{ + long double _x = 0, _x2 = 0, _y = 0, _y2 = 0, _xy = 0; + double t1; + double t2; + + k -> n += 2*len; + + for ( ; len--; p1++, p2++ ) { + _x += (t1 = (*p1)[0]); _x2 += t1 * t1; + _y += (t2 = (*p2)[0]); _y2 += t2 * t2; + _xy += t1 * t2; + _x += (t1 = (*p1)[1]); _x2 += t1 * t1; + _y += (t2 = (*p2)[1]); _y2 += t2 * t2; + _xy += t1 * t2; + } + + k -> x += _x ; + k -> x2 += _x2; + k -> y += _y ; + k -> y2 += _y2; + k -> xy += _xy; +} + +int sgn ( double x ) +{ + if ( x == 0 ) return 0; + if ( x < 0 ) return -1; + return +1; +} + +long double report ( const korr_t* const k ) +{ + long double r; + long double sx; + long double sy; + long double x; + long double y; + long double b; + + r = (k->x2*k->n - k->x*k->x) * (k->y2*k->n - k->y*k->y); + r = r > 0.l ? (k->xy*k->n - k->x*k->y) / sqrt (r) : 1.l; + sx = k->n > 1 ? sqrt ( (k->x2 - k->x*k->x/k->n) / (k->n - 1) ) : 0.l; + sy = k->n > 1 ? sqrt ( (k->y2 - k->y*k->y/k->n) / (k->n - 1) ) : 0.l; + x = k->n > 0 ? k->x/k->n : 0.l; + y = k->n > 0 ? k->y/k->n : 0.l; + + b = sx != 0 ? sy/sx * sgn(r) : 0.l; + if (verbose) + fprintf ( stderr, "r=%Lf sx=%Lf sy=%Lf x=%Lf y=%Lf b=%Lf\n", r, sx, sy, x, y, b ); + return b; +} + + +/* Input: an unsigned short n. + * Output: the swapped bytes of n if the arch is big-endian or n itself + * if the arch is little-endian. + * Comment: should be replaced latter with a better solution than this + * home-brewed hack (rbrito). The name should be better also. + */ +inline unsigned short be16_le(unsigned short n) +{ +#ifdef _WORDS_BIGENDIAN + return (n << 8) | (n >> 8); +#else + return n; +#endif +} + + +int feed ( int fd, const stereo_t* p, int len ) +{ + int i; + stereo_t tmp[30000]; /* An arbitrary size--to be changed latter */ + + if (len > sizeof(tmp)/sizeof(*tmp)) + len = sizeof(tmp)/sizeof(*tmp); + + for (i = 0; i < len; i++) { + tmp[i][0] = be16_le(p[i][0]); + tmp[i][1] = be16_le(p[i][1]); + } + + write ( fd, tmp, sizeof(stereo_t) * len ); + return len; +} + + +short round ( double f ) +{ + long x = (long) floor ( f + 0.5 ); + return x == (short)x ? (short)x : (short) ((x >> 31) ^ 0x7FFF); +} + + +int feed2 ( int fd, const stereo_t* p1, const stereo_t* p2, int len ) +{ + stereo_t tmp [30000]; /* An arbitrary size, hope that no overruns occure */ + int i; + + if (len > sizeof(tmp)/sizeof(*tmp)) + len = sizeof(tmp)/sizeof(*tmp); + for ( i = 0; i < len; i++ ) { + double f = cos ( M_PI/2*i/len ); + f *= f; + tmp [i] [0] = be16_le(round ( p1 [i] [0] * f + p2 [i] [0] * (1. - f) )); + tmp [i] [1] = be16_le(round ( p1 [i] [1] * f + p2 [i] [1] * (1. - f) )); + } + + write ( fd, tmp, sizeof(stereo_t) * len ); + return len; +} + + +int feedfac ( int fd, const stereo_t* p1, const stereo_t* p2, int len, double fac1, double fac2 ) +{ + stereo_t tmp [30000]; /* An arbitrary size, hope that no overruns occure */ + int i; + + if (len > sizeof(tmp)/sizeof(*tmp)) + len = sizeof(tmp)/sizeof(*tmp); + for ( i = 0; i < len; i++ ) { + tmp [i] [0] = be16_le(round ( p1 [i] [0] * fac1 + p2 [i] [0] * fac2 )); + tmp [i] [1] = be16_le(round ( p1 [i] [1] * fac1 + p2 [i] [1] * fac2 )); + } + + write ( fd, tmp, sizeof(stereo_t) * len ); + return len; +} + + +void setup ( int fdd, int samples, long freq ) +{ + int status, org, arg; + + // Nach vorn verschoben + if ( -1 == (status = ioctl (fdd, SOUND_PCM_SYNC, 0)) ) + perror ("SOUND_PCM_SYNC ioctl failed"); + + org = arg = 2; + if ( -1 == (status = ioctl (fdd, SOUND_PCM_WRITE_CHANNELS, &arg)) ) + perror ("SOUND_PCM_WRITE_CHANNELS ioctl failed"); + if (arg != org) + perror ("unable to set number of channels"); + fprintf (stderr, "%1u*", arg); + + org = arg = AFMT_S16_LE; + if ( -1 == ioctl (fdd, SNDCTL_DSP_SETFMT, &arg) ) + perror ("SNDCTL_DSP_SETFMT ioctl failed"); + if ((arg & org) == 0) + perror ("unable to set data format"); + + org = arg = freq; + if ( -1 == (status = ioctl (fdd, SNDCTL_DSP_SPEED, &arg)) ) + perror ("SNDCTL_DSP_SPEED ioctl failed"); + fprintf (stderr, "%5u Hz*%.3f sec\n", arg, (double)samples/arg ); + +} + + +void Message ( const char* s, size_t index, long freq, size_t start, size_t stop ) +{ + unsigned long norm_index = 100lu * index / freq; + unsigned long norm_start = 100lu * start / freq; + unsigned long norm_stop = 100lu * stop / freq; + + fprintf ( stderr, "\rListening %s %2lu:%02lu.%02lu (%1lu:%02lu.%02lu...%1lu:%02lu.%02lu)%*.*s\rListening %s", + s, + norm_index / 6000, norm_index / 100 % 60, norm_index % 100, + norm_start / 6000, norm_start / 100 % 60, norm_start % 100, + norm_stop / 6000, norm_stop / 100 % 60, norm_stop % 100, + 36 - (int)strlen(s), 36 - (int)strlen(s), "", + s ); + + fflush ( stderr ); +} + + +size_t calc_true_index ( size_t index, size_t start, size_t stop ) +{ + if ( start >= stop ) + return start; + while ( index - start < DMA_SAMPLES ) + index += stop - start; + return index - DMA_SAMPLES; +} + + +void testing ( const stereo_t* A, const stereo_t* B, size_t len, long freq ) +{ + int c; + int fd = open ( "/dev/dsp", O_WRONLY ); + int rnd = random_number (); /* Auswahl von X */ + int state = 0; /* derzeitiger F�ttungsmodus */ + float fac1 = 0.5; + float fac2 = 0.5; + size_t start = 0; + size_t stop = len; + size_t index = start; /* derzeitiger Offset auf den Audiostr�men */ + char message [80] = "A "; + + setup ( fd, len, freq ); + + while ( 1 ) { + c = sel (); + if ( c == 27 ) + c = sel () + 0x100; + + switch ( c ) { + case 'A' : + case 'a' : + strcpy ( message, "A " ); + if ( state != 0 ) + state = 2; + break; + + case 0x100+'0' : + case '0' : + case 'B' : + case 'b' : + strcpy ( message, " B" ); + if ( state != 1 ) + state = 3; + break; + + case 'X' : + case 'x' : + strcpy ( message, " X " ); + if ( state != rnd ) + state = rnd + 2; + break; + + case 'm' : + state = 8; + break; + + case 'M' : + state = (state & 1) + 4; + break; + + case 'x'&0x1F: + state = (state & 1) + 6; + break; + + case ' ': + start = 0; + stop = len; + break; + + case 'o' : + start = calc_true_index ( index, start, stop); + break; + case 'p' : + stop = calc_true_index ( index, start, stop); + break; + case 'h' : + if ( start > freq/100 ) + start -= freq/100; + else + start = 0; + index = start; + continue; + case 'j' : + if ( start < stop-freq/100 ) + start += freq/100; + else + start = stop; + index = start; + continue; + case 'k' : + if ( stop > start+freq/100 ) + stop -= freq/100; + else + stop = start; + continue; + case 'l' : + if ( stop < len-freq/100 ) + stop += freq/100; + else + stop = len; + continue; + case '\n': + index = start; + continue; + + case 'D'+0x100: + strcpy ( message, "Difference (+40 dB)" ); + state = 9; + fac1 = -100.; + fac2 = +100.; + break; + + case 'd'+0x100: + strcpy ( message, "Difference (+30 dB)" ); + state = 9; + fac1 = -32.; + fac2 = +32.; + break; + + case 'D' & 0x1F : + strcpy ( message, "Difference (+20 dB)" ); + state = 9; + fac1 = -10.; + fac2 = +10.; + break; + + case 'D' : + strcpy ( message, "Difference (+10 dB)" ); + state = 9; + fac1 = -3.; + fac2 = +3.; + break; + + case 'd' : + strcpy ( message, "Difference ( 0 dB)" ); + state = 9; + fac1 = -1.; + fac2 = +1.; + break; + + case 0x100+'1' : + case 0x100+'2' : + case 0x100+'3' : + case 0x100+'4' : + case 0x100+'5' : + case 0x100+'6' : + case 0x100+'7' : + case 0x100+'8' : + case 0x100+'9' : + sprintf ( message, " B (Errors -%c dB)", (char)c ); + state = 9; + fac2 = pow (10., -0.05*(c-0x100-'0') ); + fac1 = 1. - fac2; + break; + + case '1' : + case '2' : + case '3' : + case '4' : + case '5' : + case '6' : + case '7' : + case '8' : + case '9' : + sprintf ( message, " B (Errors +%c dB)", c ); + state = 9; + fac2 = pow (10., 0.05*(c-'0') ); + fac1 = 1. - fac2; + break; + + case 'A' & 0x1F: + fprintf (stderr, " Vote for X:=A" ); + eval ( rnd == 0 ); + rnd = random_number (); + if ( state == 6 && state == 7 ) + state = 6 + rnd; + else if ( state != rnd ) + state = rnd + 2; + strcpy ( message," X " ); + break; + + case 'B' & 0x1F: + fprintf (stderr, " Vote for X:=B" ); + eval ( rnd == 1 ); + rnd = random_number (); + if ( state == 6 && state == 7 ) + state = 6 + rnd; + else if ( state != rnd ) + state = rnd + 2; + strcpy ( message," X " ); + break; + + case -1: + break; + + default: + fprintf (stderr, "\a" ); + break; + + case 'Q': + case 'q': + fprintf ( stderr, "\n%-79.79s\r", "Quit program" ); + close (fd); + fprintf ( stderr, "\n\n"); + return; + } + + switch (state) { + case 0: /* A */ + if ( index + BF >= stop ) + index += feed (fd, A+index, stop-index ); + else + index += feed (fd, A+index, BF ); + break; + + case 1: /* B */ + if ( index + BF >= stop ) + index += feed (fd, B+index, stop-index ); + else + index += feed (fd, B+index, BF ); + break; + + case 2: /* B => A */ + if ( index + BF >= stop ) + index += feed2 (fd, B+index, A+index, stop-index ); + else + index += feed2 (fd, B+index, A+index, BF ); + state = 0; + break; + + case 3: /* A => B */ + if ( index + BF >= stop ) + index += feed2 (fd, A+index, B+index, stop-index ); + else + index += feed2 (fd, A+index, B+index, BF ); + state = 1; + break; + + case 4: /* A */ + strcpy ( message, "A " ); + if ( index + BF >= stop ) + index += feed (fd, A+index, stop-index ), + state++; + else + index += feed (fd, A+index, BF ); + break; + + case 5: /* B */ + strcpy ( message, " B" ); + if ( index + BF >= stop ) + index += feed (fd, B+index, stop-index ), + state--; + else + index += feed (fd, B+index, BF ); + break; + + case 6: /* X */ + strcpy ( message, " X " ); + if ( index + BF >= stop ) + index += feed (fd, (rnd ? B : A)+index, stop-index ), + state++; + else + index += feed (fd, (rnd ? B : A)+index, BF ); + break; + + case 7: /* !X */ + strcpy ( message, "!X " ); + if ( index + BF >= stop ) + index += feed (fd, (rnd ? A : B)+index, stop-index ), + state--; + else + index += feed (fd, (rnd ? A : B)+index, BF ); + break; + + case 8: + if ( index + BF/2 >= stop ) + index += feed2 (fd, A+index, B+index, stop-index ); + else + index += feed2 (fd, A+index, B+index, BF/2 ); + Message ( " B", index, freq, start, stop ); + if ( index + BF >= stop ) + index += feed (fd, B+index, stop-index ); + else + index += feed (fd, B+index, BF ); + if ( index + BF/2 >= stop ) + index += feed2 (fd, B+index, A+index, stop-index ); + else + index += feed2 (fd, B+index, A+index, BF/2 ); + Message ( "A ", index, freq, start, stop ); + if ( index + BF >= stop ) + index += feed (fd, A+index, stop-index ); + else + index += feed (fd, A+index, BF ); + break; + + case 9: /* Liko */ + if ( index + BF >= stop ) + index += feedfac (fd, A+index, B+index, stop-index, fac1, fac2 ); + else + index += feedfac (fd, A+index, B+index, BF , fac1, fac2 ); + break; + + default: + assert (0); + } + + if (index >= stop) + index = start; + Message ( message, calc_true_index ( index, start, stop), freq, start, stop ); + } +} + + +int has_ext ( const char* name, const char* ext ) +{ + if ( strlen (name) < strlen (ext) ) + return 0; + name += strlen (name) - strlen (ext); + return strcasecmp (name, ext) ? 0 : 1; +} + + +typedef struct { + const char* const extention; + const char* const command; +} decoder_t; + + +#define REDIR " 2> /dev/null" +#define STDOUT "/dev/fd/1" +#define PATH PATH_OF_EXTERNAL_TOOLS_FOR_UNCOMPRESSING + +const decoder_t decoder [] = { + { ".mp1" , PATH"mpg123 -w - %s" REDIR }, // MPEG Layer I : www.iis.fhg.de, www.mpeg.org + { ".mp2" , PATH"mpg123 -w - %s" REDIR }, // MPEG Layer II : www.iis.fhg.de, www.uq.net.au/~zzmcheng, www.mpeg.org + { ".mp3" , PATH"mpg123 -w - %s" REDIR }, // MPEG Layer III : www.iis.fhg.de, www.mp3dev.org, www.mpeg.org + { ".mp3pro" , PATH"mpg123 -w - %s" REDIR }, // MPEG Layer III : www.iis.fhg.de, www.mp3dev.org, www.mpeg.org + { ".mpt" , PATH"mpg123 -w - %s" REDIR }, // MPEG Layer III : www.iis.fhg.de, www.mp3dev.org, www.mpeg.org + { ".mpp" , PATH"mppdec %s -" REDIR }, // MPEGplus : www.stud.uni-hannover.de/user/73884 + { ".mpc" , PATH"mppdec %s -" REDIR }, // MPEGplus : www.stud.uni-hannover.de/user/73884 + { ".mp+" , PATH"mppdec %s -" REDIR }, // MPEGplus : www.stud.uni-hannover.de/user/73884 + { ".aac" , PATH"faad -t.wav -w %s" REDIR }, // Advanced Audio Coding: psytel.hypermart.net, www.aac-tech.com, sourceforge.net/projects/faac, www.aac-audio.com, www.mpeg.org + { "aac.lqt" , PATH"faad -t.wav -w %s" REDIR }, // Advanced Audio Coding: psytel.hypermart.net, www.aac-tech.com, sourceforge.net/projects/faac, www.aac-audio.com, www.mpeg.org + { ".ac3" , PATH"ac3dec %s" REDIR }, // Dolby AC3 : www.att.com + { "ac3.lqt" , PATH"ac3dec %s" REDIR }, // Dolby AC3 : www.att.com + { ".ogg" , PATH"ogg123 -d wav -o file:"STDOUT" %s" REDIR }, // Ogg Vorbis : www.xiph.org/ogg/vorbis/index.html + { ".pac" , PATH"lpac -x %s "STDOUT REDIR }, // Lossless predictive Audio Compression: www-ft.ee.tu-berlin.de/~liebchen/lpac.html (liebchen@ft.ee.tu-berlin.de) + { ".shn" , PATH"shorten -x < %s" REDIR }, // Shorten : shnutils.freeshell.org, www.softsound.com/Shorten.html (shnutils@freeshell.org, shorten@softsound.com) + { ".wav.gz" , PATH"gzip -d < %s | sox -twav - -twav -sw -"REDIR }, // gziped WAV + { ".wav.sz" , PATH"szip -d < %s | sox -twav - -twav -sw -"REDIR }, // sziped WAV + { ".wav.sz2", PATH"szip2 -d < %s | sox -twav - -twav -sw -"REDIR }, // sziped WAV + { ".raw" , PATH"sox -r44100 -sw -c2 -traw %s -twav -sw -"REDIR }, // raw files are treated as CD like audio + { ".cdr" , PATH"sox -r44100 -sw -c2 -traw %s -twav -sw -"REDIR }, // CD-DA files are treated as CD like audio, no preemphasis info available + { ".rm" , "echo %s '???'" REDIR }, // Real Audio : www.real.com + { ".epc" , "echo %s '???'" REDIR }, // ePAC : www.audioveda.com, www.lucent.com/ldr + { ".mov" , "echo %s '???'" REDIR }, // QDesign Music 2 : www.qdesign.com + { ".vqf" , "echo %s '???'" REDIR }, // TwinVQ : www.yamaha-xg.com/english/xg/SoundVQ, www.vqf.com, sound.splab.ecl.ntt.co.jp/twinvq-e + { ".wma" , "echo %s '???'" REDIR }, // Microsoft Media Audio: www.windowsmedia.com, www.microsoft.com/windows/windowsmedia + { ".flac" , PATH"flac -c -d %s" REDIR }, // Free Lossless Audio Coder: flac.sourceforge.net/ + { ".fla" , PATH"flac -c -d %s" REDIR }, // Free Lossless Audio Coder: flac.sourceforge.net/ + { ".ape" , "( "PATH"MAC %s _._.wav -d > /dev/null; cat _._.wav; rm _._.wav )" REDIR }, // Monkey's Audio Codec : www.monkeysaudio.com (email@monkeysaudio.com) + { ".rka" , "( "PATH"rkau %s _._.wav > /dev/null; cat _._.wav; rm _._.wav )" REDIR }, // RK Audio: + { ".rkau" , "( "PATH"rkau %s _._.wav > /dev/null; cat _._.wav; rm _._.wav )" REDIR }, // RK Audio: + { ".mod" , PATH"xmp -b16 -c -f44100 --stereo -o- %s | sox -r44100 -sw -c2 -traw - -twav -sw -" + REDIR }, // Amiga's Music on Disk: + { "" , PATH"sox %s -twav -sw -" REDIR }, // Rest, may be sox can handle it +}; + +#undef REDIR +#undef STDOUT +#undef PATH + + +int readwave ( stereo_t* buff, size_t maxlen, const char* name, size_t* len ) +{ + char* command = malloc (2*strlen(name) + 512); + char* name_q = malloc (2*strlen(name) + 128); + unsigned short header [22]; + FILE* fp; + size_t i; + size_t j; + + // The *nice* shell quoting + i = j = 0; + if ( name[i] == '-' ) + name_q[j++] = '.', + name_q[j++] = '/'; + + while (name[i]) { + if ( !isalnum (name[i]) && name[i]!='-' && name[i]!='_' && name[i]!='.' ) + name_q[j++] = '\\'; + name_q[j++] = name[i++]; + } + name_q[j] = '\0'; + + fprintf (stderr, "Reading %s", name ); + for ( i = 0; i < sizeof(decoder)/sizeof(*decoder); i++ ) + if ( has_ext (name, decoder[i].extention) ) { + sprintf ( command, decoder[i].command, name_q ); + break; + } + + free (name_q); + if ( (fp = popen (command, "r")) == NULL ) { + fprintf (stderr, "Can't exec:\n%s\n", command ); + exit (1); + } + free (command); + + fprintf (stderr, " ..." ); + fread ( header, sizeof(*header), sizeof(header)/sizeof(*header), fp ); + + switch (be16_le(header[11])) { + case 2: + *len = fread ( buff, sizeof(stereo_t), maxlen, fp ); + for (i = 0; i < *len; i ++) { + buff[i][0] = be16_le(buff[i][0]); + buff[i][1] = be16_le(buff[i][1]); + } + break; + case 1: + *len = fread ( buff, sizeof(sample_t), maxlen, fp ); + for ( i = *len; i-- > 0; ) + buff[i][0] = buff[i][1] = ((sample_t*)buff) [i]; + break; + case 0: + fprintf (stderr, "\b\b\b\b, Standard Open Source Bug detected, try murksaround ..." ); + *len = fread ( buff, sizeof(stereo_t), maxlen, fp ); + header[11] = 2; + header[12] = 65534; /* use that of the other channel */ + break; + default: + fprintf (stderr, "Only 1 or 2 channels are supported, not %u\n", header[11] ); + pclose (fp); + return -1; + } + pclose ( fp ); + fprintf (stderr, "\n" ); + return be16_le(header[12]) ? be16_le(header[12]) : 65534; +} + + +double cross_analyze ( const stereo_t* p1, const stereo_t *p2, size_t len ) +{ + float P1 [MAX] [2]; + float P2 [MAX] [2]; + int i; + int maxindex; + double sum1; + double sum2; + double max; + double y1; + double y2; + double y3; + double yo; + double xo; + double tmp; + double tmp1; + double tmp2; + int ret = 0; + int cnt = 5; + + // Calculating effective voltage + sum1 = sum2 = 0.; + for ( i = 0; i < len; i++ ) { + sum1 += (double)p1[i][0] * p1[i][0]; + sum2 += (double)p2[i][0] * p2[i][0]; + } + sum1 = sqrt ( sum1/len ); + sum2 = sqrt ( sum2/len ); + + // Searching beginning of signal (not stable for pathological signals) + for ( i = 0; i < len; i++ ) + if ( abs (p1[i][0]) >= sum1 && abs (p2[i][0]) >= sum2 ) + break; + p1 += i; + p2 += i; + len -= i; + + if ( len <= MAX ) + return 0; + + // Filling arrays for FFT + do { + sum1 = sum2 = 0.; + for ( i = 0; i < MAX; i++ ) { +#ifdef USEDIFF + tmp1 = p1 [i][0] - p1 [i+1][0]; + tmp2 = p2 [i+ret][0] - p2 [i+ret+1][0]; +#else + tmp1 = p1 [i][0]; + tmp2 = p2 [i+ret][0]; +#endif + sum1 += tmp1*tmp1; + sum2 += tmp2*tmp2; + P1 [i][0] = tmp1; + P2 [i][0] = tmp2; + P1 [i][1] = 0.; + P2 [i][1] = 0.; + } + + fft (P1, MAX); + fft (P2, MAX); + + for ( i = 0; i < MAX; i++ ) { + double a0 = P1 [i][0]; + double a1 = P1 [i][1]; + double b0 = P2 [(MAX-i)&(MAX-1)][0]; + double b1 = P2 [(MAX-i)&(MAX-1)][1]; + P1 [i][0] = a0*b0 - a1*b1; + P1 [i][1] = a0*b1 + a1*b0; + } + + fft (P1, MAX); + + max = P1 [maxindex = 0][0]; + for ( i = 1; i < MAX; i++ ) + if ( P1[i][0] > max ) + max = P1 [maxindex = i][0]; + + y2 = P1 [ maxindex ][0]; + y1 = P1 [(maxindex-1)&(MAX-1)][0] - y2; + y3 = P1 [(maxindex+1)&(MAX-1)][0] - y2; + + xo = 0.5 * (y1-y3) / (y1+y3); + yo = 0.5 * ( (y1+y3)*xo + (y3-y1) ) * xo; + + if (maxindex > MAX/2 ) + maxindex -= MAX; + + ret += maxindex; + tmp = 100./MAX/sqrt(sum1*sum2); + if (verbose) + printf ( "[%5d]%8.4f [%5d]%8.4f [%5d]%8.4f [%10.4f]%8.4f\n", + ret- 1, (y1+y2)*tmp, + ret , y2 *tmp, + ret+ 1, (y3+y2)*tmp, + ret+xo, (yo+y2)*tmp ); + + } while ( maxindex && cnt-- ); + + return ret + xo; +} + + +short to_short ( int x ) +{ + return x == (short)x ? (short)x : (short) ((x >> 31) ^ 0x7FFF); +} + + +void DC_cancel ( stereo_t* p, size_t len ) +{ + double sum1 = 0; + double sum2 = 0; + size_t i; + int diff1; + int diff2; + + for (i = 0; i < len; i++ ) { + sum1 += p[i][0]; + sum2 += p[i][1]; + } + if ( fabs(sum1) < len && fabs(sum2) < len ) + return; + + diff1 = round ( sum1 / len ); + diff2 = round ( sum2 / len ); + if (verbose) + fprintf (stderr, "Removing DC (left=%d, right=%d)\n", diff1, diff2 ); + + for (i = 0; i < len; i++ ) { + p[i][0] = to_short ( p[i][0] - diff1); + p[i][1] = to_short ( p[i][1] - diff2); + } +} + +void multiply ( char c, stereo_t* p, size_t len, double fact ) +{ + size_t i; + + if ( fact == 1. ) + return; + if (verbose) + fprintf (stderr, "Multiplying %c by %7.5f\n", c, fact ); + + for (i = 0; i < len; i++ ) { + p[i][0] = to_short ( p[i][0] * fact ); + p[i][1] = to_short ( p[i][1] * fact ); + } +} + + +int maximum ( stereo_t* p, size_t len ) +{ + int max = 0; + size_t i; + + for (i = 0; i < len; i++ ) { + if (abs(p[i][0]) > max) max = abs(p[i][0]); + if (abs(p[i][1]) > max) max = abs(p[i][1]); + } + return max; +} + + +void usage ( void ) +{ + fprintf ( stderr, + "usage: abx [-v] File_A File_B\n" + "\n" + "File_A and File_B loaded and played. File_A should be the better/reference\n" + "file, File_B the other. You can press the following keys:\n" + "\n" + " a/A: Listen to File A\n" + " b/B: Listen to File B\n" + " x/X: Listen to the randomly selected File X, which is A or B\n" + " Ctrl-A: You vote for X=A\n" + " Ctrl-B: You vote for X=B\n" + " m: Alternating playing A and B. Fast switching\n" + " M: Alternating playing A and B. Slow switching\n" + " d/D/Ctrl-D/Alt-d/Alt-D:\n" + " Listen to the difference A-B (+0 dB...+40 dB)\n" + " o/p: Chunk select\n" + " hjkl: Chunk fine adjust (hj: start, kl: stop)\n" + " Space: Chunk deselect\n" + " 0...9: Listen to B, but difference A-B is amplified by 0-9 dB\n" + " Q: Quit the program\n" + "\n" + ); +} + + +int main ( int argc, char** argv ) +{ + stereo_t* _A = calloc ( MAX_LEN, sizeof(stereo_t) ); + stereo_t* _B = calloc ( MAX_LEN, sizeof(stereo_t) ); + stereo_t* A = _A; + stereo_t* B = _B; + size_t len_A; + size_t len_B; + size_t len; + int max_A; + int max_B; + int max; + long freq1; + long freq2; + int shift; + double fshift; + double ampl; + int ampl_X; + korr_t k; + + if (argc > 1 && 0 == strcmp (argv[1], "-v") ) { + verbose = 1; + argc--; + argv++; + } + + switch ( argc ) { + case 0: + case 1: + case 2: + default: + usage (); + return 1; + case 3: + usage(); + break; + } + + freq1 = readwave ( A, MAX_LEN, argv[1], &len_A ); + DC_cancel ( A, len_A ); + freq2 = readwave ( B, MAX_LEN, argv[2], &len_B ); + DC_cancel ( B, len_B ); + + if ( freq1 == 65534 && freq2 != 65534 ) + freq1 = freq2; + else if ( freq2 == 65534 && freq1 != 65534 ) + freq2 = freq1; + else if ( freq1 == 65534 && freq2 == 65534 ) + freq1 = freq2 = 44100; + + if ( freq1 != freq2 ) { + fprintf ( stderr, "Different sample frequencies currently not supported\n"); + fprintf ( stderr, "A: %ld, B: %ld\n", freq1, freq2 ); + return 2; + } + + len = len_A < len_B ? len_A : len_B; + fshift = cross_analyze ( A, B, len ); + shift = floor ( fshift + 0.5 ); + + if ( verbose ) { + fprintf ( stderr, "Delay Ch1 is %.4f samples\n", fshift ); + fprintf ( stderr, "Delay Ch2 is %.4f samples\n", + cross_analyze ( (stereo_t*)(((sample_t*)A)+1), (stereo_t*)(((sample_t*)B)+1), len ) ); + } + + if (shift > 0) { + if (verbose) + fprintf ( stderr, "Delaying A by %d samples\n", +shift); + B += shift; + len_B -= shift; + } + if (shift < 0) { + if (verbose) + fprintf ( stderr, "Delaying B by %d samples\n", -shift); + A -= shift; + len_A += shift; + } + + len = len_A < len_B ? len_A : len_B; + memset ( &k, 0, sizeof(k) ); + analyze_stereo ( A, B, len, &k ); + ampl = report (&k); + max_A = maximum ( A, len ); + max_B = maximum ( B, len ); + + if ( ampl <= 0.98855 ) { /* < -0.05 dB */ + max = max_A*ampl < max_B ? max_B : max_A*ampl; + ampl_X = (int)(29203 / max); + if ( ampl_X < 2 ) ampl_X = 1; + multiply ( 'A', A, len, ampl*ampl_X ); + multiply ( 'B', B, len, ampl_X ); + } else if ( ampl >= 1.01158 ) { /* > +0.05 dB */ + max = max_A < max_B/ampl ? max_B/ampl : max_A; + ampl_X = (int)(29203 / max); + if ( ampl_X < 2 ) ampl_X = 1; + multiply ( 'A', A, len, ampl_X ); + multiply ( 'B', B, len, 1./ampl*ampl_X ); + } else { + max = max_A < max_B ? max_B : max_A; + ampl_X = (int)(29203 / max); + if ( ampl_X < 2 ) ampl_X = 1; + multiply ( 'A', A, len, ampl_X ); + multiply ( 'B', B, len, ampl_X ); + } + + set (); + Set_Realtime (); + testing ( A, B, len, freq1 ); + reset (); + + free (_A); + free (_B); + return 0; +} + +/* end of abx.c */ diff --git a/misc/ath.c b/misc/ath.c new file mode 100644 index 0000000..ee6cfda --- /dev/null +++ b/misc/ath.c @@ -0,0 +1,839 @@ +/* $Id: ath.c,v 1.12 2000/12/05 15:37:26 aleidinger Exp $ */ +/* + * Known bugs (sorted by importance): + * - human delay (ca. 200 ms or more???) and buffering delay (341 ms @48 kHz/64 KByte) + * should be subtracted + * - error handling + * - cos slope on direction changes + * - calibration file of soundcard/amplifier/head phone + * - worse handling + * - +/- handling via mouse (do you have code?) in a dark room + * - ENTER as direction change + * - finer precalculated ATH for pre-emphasis + */ + +/* + * Suggested level ranges: + * 180 Hz...13.5 kHz: 50...70 dB + * 100 Hz...15.0 kHz: 40...70 dB + * 70 Hz...16.0 kHz: 30...70 dB + * 45 Hz...16.5 kHz: 20...70 dB + * 30 Hz...17.5 kHz: 10...70 dB + * 25 Hz...18.0 kHz: 5...75 dB + * 20 Hz...19.0 kHz: 0...80 dB + * 16 Hz...20.0 kHz: -10...80 dB + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <limits.h> +#include <termios.h> +#include <math.h> +#include <time.h> +#include <signal.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/stat.h> +#ifdef HAVE_SYS_SOUNDCARD_H +# include <sys/soundcard.h> +#elif defined(HAVE_LINUX_SOUNDCARD_H) +# include <linux/soundcard.h> +#else +# error no soundcard include +#endif + + + +#define AUDIO_DEVICE "/dev/dsp" +//#define COOLEDIT_FILE "/mnt/dosd/cooledit.wav" +#define DELAY_UNTIL_XCHG 2.5 +#define TURN_STEPS 2400 + +/****************************************************************************************************** + * soundcard stuff + ******************************************************************************************************/ + +const double dither_coeff [] [16] = { + { /* 48 kHz */ 3.35185352775391591311, 4.24914379295482032978, 1.78042251729150153086, -0.92601381419186201184, -1.37308596104182343645, -1.85951915999247704829, -3.28074437872632330526, -3.05496670185702990882, -1.22855462839450528837, -0.30291531959171267015, -0.18598486195652600770, 0.42010512205702003790, 0.92278786111368653452, 0.62102380451771775193, 0.14312897206650044828, -0.00454721508203927746 }, + { /* 56 kHz */ 3.86404134982280628749, 6.67195592701613291071, 5.90576195467245802046, 1.57589705921487261981, -2.10618201389737372178, -2.74191788822507184395, -2.62175070636849999396, -3.78505226463032808863, -4.45698848578010438284, -2.76825966243460536110, -0.26509931375584007312, 0.67853812028968716799, 0.17633528441477021892, -0.28511417191837823770, -0.21866605100975608470, -0.04751674094456833719 }, + { /* 64 kHz */ 4.09276938880098092172, 8.27424044674659812937, 10.11503162292146762880, 7.19159801569544317353, 1.39770070291739556523, -2.86595901981244688601, -3.76567274050094691362, -3.58051445684472378298, -4.78262917738758022539, -6.53075750894777650899, -6.31330514306857055627, -3.69971382767763534195, -0.78125094191744878298, 0.59027508113837267217, 0.53500264009607367648, 0.14860043567206217506 }, + { /* 72 kHz */ 4.13833553801985235465, 9.02461778089340082437, 12.93090366932740510782, 12.66372285767699051948, 7.76122176702274149630, 1.30617257555732278296, -2.92859120887121285358, -4.02438598495837830627, -4.16673068132491936262, -5.55618065300129916574, -7.82657788611231653103, -8.83055904466106668035, -7.34884789347713815672, -4.33977664906048314891, -1.67711310288611975398, -0.33086687044710235420 }, + { /* 80 kHz */ 4.22135293342667005517, 9.76639846582539722375, 15.46562682418357478290, 17.54378549927855248346, 13.29112084313158963396, 3.51512441998252657470, -7.51025671462502577300,-14.84164320864536219368,-16.10306907358826504148,-12.54775907691866414402, -7.40560667268782655149, -3.34708029482052565732, -1.19572214872925790860, -0.39582185216275086786, -0.14803160816846603424, -0.04292818488627011881 }, + { /* 88 kHz */ 4.18521467865996935325, 9.96765821475909556942, 16.91905760389390617551, 21.74016824668913557689, 20.96457146354060682367, 13.28640453421253890542, 0.85116933842171101587,-11.66054516261007127469,-19.62750656985581800169,-20.98831962473015904508,-16.95374072505042825458,-10.68848180295390154146, -5.17169792984369678908, -1.79975409439650319129, -0.38057073791415898674, -0.02672653932844656975 }, + { /* 96 kHz */ 4.09418877324899473189, 9.77977364010870211207, 17.10120082680385341159, 23.37356217615995036818, 25.27121942060722374276, 20.64059991613550174190, 9.99721445051475610371, -3.39833000550997938512,-15.03410054392933377278,-21.36704201000683067679,-21.40772859969388741685,-16.79355426136657673808,-10.48570200688141622163, -5.07642951516127438486, -1.75555240936989159436, -0.33817997298586054131 }, +}; + +typedef struct { + const char* device; + int fd; + long double sample_freq; + const double* dither; + int channels; + int bits; +} soundcard_t; + +typedef signed short sample_t; +typedef sample_t stereo_t [2]; + +int open_soundcard ( + soundcard_t* const k, + const char* device, + const int channels, + const int bits, + const long double freq ) +{ + int arg; + int org; + int index; + int status; + + k->device = device; + if ( -1 == (k->fd = open ( k->device, O_WRONLY )) ) { + perror("opening of audio device failed"); + return -1; + } + + if ( -1 == (status = ioctl (k->fd, SOUND_PCM_SYNC, 0))) { + fprintf ( stderr, "%s: SOUND_PCM_SYNC ioctl failed: %s\n", k->device, strerror (errno)); + return -1; + } + + org = arg = channels; + if ( -1 == (status = ioctl (k->fd, SOUND_PCM_WRITE_CHANNELS, &arg)) ) { + fprintf ( stderr, "%s: SOUND_PCM_WRITE_CHANNELS (%d) ioctl failed: %s\n" , k->device, channels, strerror (errno) ); + return -1; + } + if (arg != org) { + fprintf ( stderr, "%s: unable to set number of channels: %d instead of %d\n", k->device, arg, org ); + return -1; + } + k->channels = arg; + + org = arg = bits; + if ( -1 == (status = ioctl (k->fd, SOUND_PCM_WRITE_BITS, &arg)) ) { + fprintf ( stderr, "%s: SOUND_PCM_WRITE_BITS ioctl failed\n", k->device ); + return -1; + } + if (arg != org) { + fprintf ( stderr, "%s: unable to set sample size: %d instead of %d\n", k->device, arg, org ); + return -1; + } + k->bits = arg; + + org = arg = k->bits <= 8 ? AFMT_U8 : AFMT_S16_LE; + if ( -1 == ioctl (k->fd, SNDCTL_DSP_SETFMT, &arg) ) { + fprintf ( stderr, "%s: SNDCTL_DSP_SETFMT ioctl failed\n", k->device ); + return -1; + } + if ((arg & org) == 0) { + fprintf ( stderr, "%s: unable to set data format\n", k->device ); + return -1; + } + + org = arg = (int) floor ( freq + 0.5 ); + if ( -1 == (status = ioctl (k->fd, SOUND_PCM_WRITE_RATE, &arg)) ) { + fprintf ( stderr, "%s: SOUND_PCM_WRITE_WRITE ioctl failed\n", k->device ); + return -1; + } + k->sample_freq = (long double)arg; + index = (arg - 44000) / 8000; + if ( index < 0 ) index = 0; + if ( index >= sizeof(dither_coeff)/sizeof(*dither_coeff) ) index = sizeof(dither_coeff)/sizeof(*dither_coeff) - 1; + k->dither = dither_coeff [ index ]; + return 0; +} + +int play_soundcard ( soundcard_t* const k, stereo_t* samples, size_t length ) +{ + size_t bytes = length * sizeof (*samples); + +#ifdef COOLEDIT_FILE + static int fd = -1; + if ( fd < 0 ) fd = open ( COOLEDIT_FILE, O_WRONLY | O_CREAT ); + write ( fd, samples, bytes ); +#endif + + return write ( k->fd, samples, bytes ) == bytes ? 0 : -1; +} + +int close_soundcard ( soundcard_t* const k ) +{ + return close (k->fd); +} + + +/****************************************************************************************************** + * frequency stuff + ******************************************************************************************************/ + +typedef enum { + linear = 0, + logarithm = 1, + square = 2, + cubic = 3, + erb = 4, + recip = 5 +} genmode_t; + +static long double linear_f ( long double x ) { return x > 0.L ? x : 0.0L; } +static long double logarithm_f ( long double x ) { return x > 0.L ? log10 (x) : -3.5L; } +static long double square_f ( long double x ) { return x > 0.L ? sqrt (x) : 0.0L; } +static long double cubic_f ( long double x ) { return x > 0.L ? pow (x,1/3.) : 0.0L; } +static long double erb_f ( long double x ) { return log (1. + 0.00437*x); } +static long double recip_f ( long double x ) { return x > 1.L ? 1.L/x : 1.0L; } + +static long double inv_linear_f ( long double x ) { return x; } +static long double inv_logarithm_f ( long double x ) { return pow (10., x); } +static long double inv_square_f ( long double x ) { return x*x; } +static long double inv_cubic_f ( long double x ) { return x*x*x; } +static long double inv_erb_f ( long double x ) { return (exp(x) - 1.) * (1./0.00437); } +static long double inv_recip_f ( long double x ) { return x > 1.L ? 1.L/x : 1.0L; } + +typedef long double (*converter_fn_t) ( long double ); + +const converter_fn_t func [] = { linear_f, logarithm_f, square_f, cubic_f , erb_f , recip_f }; +const converter_fn_t inv_func [] = { inv_linear_f, inv_logarithm_f, inv_square_f, inv_cubic_f, inv_erb_f, inv_recip_f }; + +typedef struct { + genmode_t genmode; + long double start_freq; + long double stop_freq; + long double sample_freq; + unsigned long duration; + + long double phase; + long double param1; + long double param2; + unsigned long counter; +} generator_t; + +int open_generator ( + generator_t* const g, + const soundcard_t* const s, + const genmode_t genmode, + const long double duration, + const long double start_freq, + const long double stop_freq ) +{ + g->sample_freq = s->sample_freq; + g->genmode = genmode; + g->start_freq = start_freq; + g->stop_freq = stop_freq; + g->duration = (unsigned long) floor ( duration * g->sample_freq + 0.5 ); + + if ( g->duration < 2 ) + return -1; + + if ( g->genmode >= sizeof (func)/sizeof(*func) ) + return -1; + + g->param1 = func [g->genmode] ( g->start_freq / g->sample_freq ); + g->param2 = ( func [ g->genmode ] ( g->stop_freq / g->sample_freq ) - g->param1 ) + / ( g->duration - 1 ); + g->phase = 0.L; + g->counter= 0; + + return 0; +} + +long double iterate_generator ( generator_t* const g ) +{ + long double freq; + + freq = inv_func [ g->genmode ] ( g->param1 + g->counter++ * g->param2 ); + + g->phase += freq; + if (g->phase > 15.) + g->phase -= 16.; + return sin ( 2.*M_PI * g->phase ); +} + +long double get_sine ( generator_t* const g ) +{ + return sin ( 2.*M_PI * g->phase ); +} + +long double get_cosine ( generator_t* const g ) +{ + return cos ( 2.*M_PI * g->phase ); +} + + +long double frequency ( const generator_t* const g ) +{ + return inv_func [ g->genmode ] ( g->param1 + g->counter * g->param2 ) * g->sample_freq; +} + +int close_generator ( generator_t* const g ) +{ + return 0; +} + +/****************************************************************************************************** + * amplitude stuff + ******************************************************************************************************/ + +typedef enum { + up = 0, + down = 1, + turn_up = 2, + turn_down = 3, + still_up = 4, + still_down = 5, + change = 6 +} direction_t; + + +typedef struct { + long double sample_freq; + direction_t direction; // down, up, still_up, still_down, turn_down, turn_up + int multiplier; // -TURN_STEPS: down, +TURN_STEPS up + long double amplitude; + long double delta_amplitude; + long direction_change; +} amplitude_t; + +int open_amplifier ( + amplitude_t* const a, + const soundcard_t* const s, + const long double start_ampl, + const double dB_per_sec ) +{ + a->sample_freq = s->sample_freq; + a->direction = up; + a->multiplier = +TURN_STEPS; + a->amplitude = start_ampl * 32767.; + a->delta_amplitude = dB_per_sec * 0.1151292546497022842 / s->sample_freq / TURN_STEPS; + a->direction_change = 0; + + srand ( time (NULL) ); + return 0; +} + +long double iterate_amplifier ( amplitude_t* const a ) +{ + switch ( a->direction ) { + case still_up: + assert (a->multiplier == +TURN_STEPS); + if (a->direction_change > 0 ) + a->direction_change--; + else + a->direction = turn_down; + break; + case still_down: + assert (a->multiplier == -TURN_STEPS); + if (a->direction_change > 0 ) + a->direction_change--; + else + a->direction = turn_up; + break; + case turn_up: + assert (a->direction_change == 0); + if ( a->multiplier < +TURN_STEPS ) + a->multiplier++; + else + a->direction = up; + break; + case turn_down: + assert (a->direction_change == 0); + if ( a->multiplier > -TURN_STEPS ) + a->multiplier--; + else + a->direction = down; + break; + case up: + assert (a->multiplier == +TURN_STEPS); + assert (a->direction_change == 0); + break; + case down: + assert (a->multiplier == -TURN_STEPS); + assert (a->direction_change == 0); + break; + default: + fprintf ( stderr, "\n\r*** Bug! ***\n"); + break; + } + + a->amplitude *= 1.L + a->delta_amplitude * a->multiplier; + return a->amplitude; +} + +long double amplitude ( const amplitude_t* const a ) +{ + return a->amplitude / 32767.; +} + +int change_direction ( amplitude_t* const a, direction_t new_direction ) +{ + switch ( new_direction ) { + case up: + if (a->direction == down) { + a->direction = still_down; + } else { + fprintf ( stderr, "Direction not down, so ignored\n" ); + return -1; + } + break; + case down: + if (a->direction == up) { + a->direction = still_up; + } else { + fprintf ( stderr, "Direction not up, so ignored\n" ); + return -1; + } + break; + case change: + switch ( a->direction ) { + case up: + a->direction = still_up; + break; + case down: + a->direction = still_down; + break; + default: + fprintf ( stderr, "Direction still changing, so ignored\n" ); + return -1; + } + break; + + default: + fprintf ( stderr, "Direction unknown, so ignored\n" ); + return -1; + } + + a->direction_change = 1 + rand () * (a->sample_freq * DELAY_UNTIL_XCHG / RAND_MAX); + return 0; +} + +int close_amplifier ( amplitude_t* const a ) +{ + return 0; +} + + +double ATH ( double freq ) +{ + static float tab [] = { + /* 10.0 */ 96.69, 96.69, 96.26, 95.12, + /* 12.6 */ 93.53, 91.13, 88.82, 86.76, + /* 15.8 */ 84.69, 82.43, 79.97, 77.48, + /* 20.0 */ 74.92, 72.39, 70.00, 67.62, + /* 25.1 */ 65.29, 63.02, 60.84, 59.00, + /* 31.6 */ 57.17, 55.34, 53.51, 51.67, + /* 39.8 */ 50.04, 48.12, 46.38, 44.66, + /* 50.1 */ 43.10, 41.73, 40.50, 39.22, + /* 63.1 */ 37.23, 35.77, 34.51, 32.81, + /* 79.4 */ 31.32, 30.36, 29.02, 27.60, + /* 100.0 */ 26.58, 25.91, 24.41, 23.01, + /* 125.9 */ 22.12, 21.25, 20.18, 19.00, + /* 158.5 */ 17.70, 16.82, 15.94, 15.12, + /* 199.5 */ 14.30, 13.41, 12.60, 11.98, + /* 251.2 */ 11.36, 10.57, 9.98, 9.43, + /* 316.2 */ 8.87, 8.46, 7.44, 7.12, + /* 398.1 */ 6.93, 6.68, 6.37, 6.06, + /* 501.2 */ 5.80, 5.55, 5.29, 5.02, + /* 631.0 */ 4.75, 4.48, 4.22, 3.98, + /* 794.3 */ 3.75, 3.51, 3.27, 3.22, + /* 1000.0 */ 3.12, 3.01, 2.91, 2.68, + /* 1258.9 */ 2.46, 2.15, 1.82, 1.46, + /* 1584.9 */ 1.07, 0.61, 0.13, -0.35, + /* 1995.3 */ -0.96, -1.56, -1.79, -2.35, + /* 2511.9 */ -2.95, -3.50, -4.01, -4.21, + /* 3162.3 */ -4.46, -4.99, -5.32, -5.35, + /* 3981.1 */ -5.13, -4.76, -4.31, -3.13, + /* 5011.9 */ -1.79, 0.08, 2.03, 4.03, + /* 6309.6 */ 5.80, 7.36, 8.81, 10.22, + /* 7943.3 */ 11.54, 12.51, 13.48, 14.21, + /* 10000.0 */ 14.79, 13.99, 12.85, 11.93, + /* 12589.3 */ 12.87, 15.19, 19.14, 23.69, + /* 15848.9 */ 33.52, 48.65, 59.42, 61.77, + /* 19952.6 */ 63.85, 66.04, 68.33, 70.09, + /* 25118.9 */ 70.66, 71.27, 71.91, 72.60, + }; + double freq_log; + double dB; + unsigned index; + + if ( freq < 10. ) freq = 10.; + if ( freq > 25000. ) freq = 25000.; + + freq_log = 40. * log10 (0.1 * freq); /* 4 steps per third, starting at 10 Hz */ + index = (unsigned) freq_log; + assert ( index < sizeof(tab)/sizeof(*tab) ); + dB = tab [index] * (1 + index - freq_log) + tab [index+1] * (freq_log - index); + return pow ( 10., 0.05*dB ); +} + +/****************************************************************************************************** + * keyboard stuff + ******************************************************************************************************/ + +typedef struct { + int init; + struct termios stored_setting; + struct termios current_setting; +} keyboard_t; + +static keyboard_t* __k; + +/* Restore term-settings to those saved when term_init was called */ + +static void term_restore (void) +{ + tcsetattr ( 0, TCSANOW, &(__k->stored_setting) ); +} /* term_restore */ + +/* Clean up terminal; called on exit */ + +static void term_exit ( int sig ) +{ + term_restore (); +} /* term_exit */ + +/* Will be called when ctrl-Z is pressed, this correctly handles the terminal */ + +static void term_ctrl_z ( int sig ) +{ + signal ( SIGTSTP, term_ctrl_z ); + term_restore (); + kill ( getpid(), SIGSTOP ); +} /* term_ctrl_z */ + +/* Will be called when application is continued after having been stopped */ + +static void term_cont ( int sig ) +{ + signal ( SIGCONT, term_cont ); + tcsetattr ( 0, TCSANOW, &(__k->current_setting) ); +} /* term_cont() */ + +int open_keyboard ( keyboard_t* const k ) +{ + __k = k; + tcgetattr ( 0, &(k->stored_setting) ); + tcgetattr ( 0, &(k->current_setting) ); + + signal ( SIGINT, term_exit ); /* We _must_ clean up when we exit */ + signal ( SIGQUIT, term_exit ); + signal ( SIGTSTP, term_ctrl_z ); /* Ctrl-Z must also be handled */ + signal ( SIGCONT, term_cont ); +// atexit ( term_exit ); + + /* One or more characters are sufficient to cause a read to return */ + cfmakeraw ( &(k->current_setting) ); + k->current_setting.c_oflag |= ONLCR | OPOST; /* enables NL => CRLF on output */ + + tcsetattr ( 0, TCSANOW, &(k->current_setting) ); + return 0; +} + +int getchar_keyboard ( keyboard_t* const k ) +{ + struct timeval t; + fd_set fd [1]; + int ret; + unsigned char c; + + FD_SET (0, fd); + t.tv_sec = 0; + t.tv_usec = 0; + + ret = select ( 1, fd, NULL, NULL, &t ); + + switch ( ret ) { + case 0: + return -1; + case 1: + ret = read (0, &c, 1); + return ret == 1 ? c : -1; + default: + return -2; + } +} + +int close_keyboard ( keyboard_t* const k ) +{ + term_restore (); + return 0; +} + + +/****************************************************************************************************** + * reporting stuff + ******************************************************************************************************/ + +int report_open ( void ) +{ + static char buff [32767]; + fflush ( stdout ); + setvbuf ( stdout, buff, _IOFBF, sizeof(buff) ); + return 0; +} + +int report ( const generator_t* const g, const amplitude_t* const a ) +{ + static double last_freq = -1.; + static double last_level = -1.; + double freq; + double level; + + freq = frequency (g); + level = 20. * log10 (amplitude (a) * ATH (freq) ) + 80.; + + if ( last_freq >= 0 ) + printf ( "%11.3f %8.2f\n", sqrt (freq*last_freq), 0.5 * (level+last_level) ); + printf ( "# %9.3f %8.2f\n", freq, level ); + + fflush ( stdout ); + + last_freq = freq; + last_level = level; + return 0; +} + +int report_close ( void ) +{ + printf ( "%%%%\n\n" ); + fflush ( stdout ); + close ( dup ( fileno(stdout) ) ); + setvbuf ( stdout, NULL, _IONBF, 0 ); + return 0; +} + + +/****************************************************************************************************** + * main stuff + ******************************************************************************************************/ + +typedef enum { + left = 0, + right = 1, + phase0 = 2, + both = 2, + phase90 = 3, + phase180 = 4, + phasemod = 5 +} earmode_t; + +static long double scalar ( const double* a, const double* b ) +{ + return a[ 0]*b[ 0] + a[ 1]*b[ 1] + a[ 2]*b[ 2] + a[ 3]*b[ 3] + +a[ 4]*b[ 4] + a[ 5]*b[ 5] + a[ 6]*b[ 6] + a[ 7]*b[ 7] + +a[ 8]*b[ 8] + a[ 9]*b[ 9] + a[10]*b[10] + a[11]*b[11] + +a[12]*b[12] + a[13]*b[13] + a[14]*b[14] + a[15]*b[15]; +} + +int experiment ( generator_t* const g, + amplitude_t* const a, + keyboard_t* const k, + soundcard_t* const s, + earmode_t earmode ) +{ + long i; + int j; + stereo_t samples [512]; + static double quant_errors [2] [16]; + long double val; + double ampl; + long ival; + + fprintf ( stderr, "\r+++ up +++" ); + for ( i = 0; i < g->duration; i += sizeof(samples)/sizeof(*samples) ) { + fprintf ( stderr, "%3lu%%\b\b\b\b", i*100lu/g->duration ); + + for (j = 0; j < sizeof(samples)/sizeof(*samples); j++ ) { + ampl = iterate_amplifier (a) * ATH (frequency (g)); + val = ampl * iterate_generator (g); + ival = (long) floor ( val + 0.5 + scalar (quant_errors[0], s->dither) ); + + if ( ival != (sample_t) ival ) { + report (g, a); + fprintf ( stderr, "\rOverrun \n\n" ); + return -1; + } + memmove ( & quant_errors [0] [1], & quant_errors [0] [0], + sizeof(quant_errors[0]) - sizeof(quant_errors[0][0]) ); + quant_errors [0] [0] = val - ival; + switch ( earmode ) { + case both: + samples [j] [0] = samples [j] [1] = ival; + break; + case left: + samples [j] [0] = ival; + samples [j] [1] = 0; + break; + case right: + samples [j] [0] = 0; + samples [j] [1] = ival; + break; + case phase180: + samples [j] [0] = ival == -32768 ? 32767 : -ival; + samples [j] [1] = +ival; + break; + case phase90: + samples [j] [0] = ival; + val = ampl * get_cosine (g); + ival = (long) floor ( val + 0.5 + scalar (quant_errors[1], s->dither) ); + if ( ival != (sample_t) ival ) { + report (g, a); + fprintf ( stderr, "\rOverrun \n\n" ); + return -1; + } + memmove ( & quant_errors [1] [1], & quant_errors [1] [0], + sizeof(quant_errors[1]) - sizeof(quant_errors[1][0]) ); + quant_errors [1] [0] = val - ival; + samples [j] [1] = ival; + break; + default: + assert (0); + return -1; + } + } + play_soundcard ( s, samples, sizeof(samples)/sizeof(*samples) ); + if ( amplitude (a) * ATH (frequency (g)) <= 3.16227766e-6 ) { + report (g, a); + fprintf ( stderr, "\rUnderrun \n\n" ); + return -1; + } + + switch ( getchar_keyboard (k) ) { + case '+': + fprintf ( stderr, "\r+++ up +++" ); + report (g, a); + change_direction ( a, up ); + break; + case '-': + fprintf ( stderr, "\r--- down ---" ); + report (g, a); + change_direction ( a, down ); + break; + case '\r': + case '\n': + fprintf ( stderr, "\r** change **" ); + report (g, a); + change_direction ( a, change ); + break; + case 'C'&0x1F: + case 'q': + case 'Q': + case 'x': + case 'X': + fprintf ( stderr, "\rBreak \n\n" ); + fflush ( stderr ); + return -1; + default: + fprintf ( stderr, "\a" ); + break; + case -1: + break; + } + } + + fprintf ( stderr, "\rReady \n\n" ); + return 0; +} + +static void usage ( void ) +{ + static const char help[] = + "'Absolute Threshold of Hearing' -- Version 0.07 (C) Frank Klemm 2000\n" + "\n" + "usage:\n" + " ath type minfreq maxfreq duration ampl_speed [start_level [earmode] > reportfile\n" + "\n" + " type: linear, logarithm, square, cubic, erb, recip\n" + " minfreq: initial frequency [Hz]\n" + " maxfreq: end frequency [Hz]\n" + " duration: duration of the experiment [s]\n" + " ampl_speed: amplitude slope speed [phon/s]\n" + " start_level: absolute level at startup [0...1]\n" + " earmode: left, right, both, phase90, phase180\n" + "\n" + "example:\n" + " ath erb 700 22000 600 3 0.0001 > result1\n" + " ath erb 1400 16 360 3 0.0001 > result2\n" + "\n" + "handling:\n" + " press '-' once when you start hearing a tone\n" + " press '+' once when you stop hearing a tone\n" + " press 'q' to early leave the program\n" + " on errors the pressed key is ignored\n"; + + fprintf ( stderr, "%s\n", help ); +} + +int main ( int argc, char** argv ) +{ + generator_t g; + amplitude_t a; + soundcard_t s; + keyboard_t k; + genmode_t genmode; + earmode_t earmode; + + if ( argc == 1 ) { + usage (); + system ( "./ath erb 700 22000 600 3 0.0001 > result1" ); + system ( "./ath erb 1400 16 360 3 0.0001 > result2" ); + system ( "xmgr result1 result2 &> /dev/null &" ); + return 0; + } + + if ( argc < 6 ) { + usage (); + return 1; + } + + if ( 0 == strncmp ( argv[1], "li" , 2) ) genmode = linear; + else if ( 0 == strncmp ( argv[1], "lo" , 2) ) genmode = logarithm; + else if ( 0 == strncmp ( argv[1], "sq" , 2) ) genmode = square; + else if ( 0 == strncmp ( argv[1], "cu" , 2) ) genmode = cubic; + else if ( 0 == strncmp ( argv[1], "er" , 2) ) genmode = erb; + else if ( 0 == strncmp ( argv[1], "re" , 2) ) genmode = recip; + else { + usage (); + return 1; + } + + if ( argc < 8 ) earmode = both; + else if ( 0 == strncmp ( argv[7], "le" , 2) ) earmode = left; + else if ( 0 == strncmp ( argv[7], "ri" , 2) ) earmode = right; + else if ( 0 == strncmp ( argv[7], "bo" , 2) ) earmode = both; + else if ( 0 == strncmp ( argv[7], "phase9" , 6) ) earmode = phase90; + else if ( 0 == strncmp ( argv[7], "phase1" , 6) ) earmode = phase180; + else { + usage (); + return 1; + } + + + open_soundcard ( &s, AUDIO_DEVICE, sizeof(stereo_t)/sizeof(sample_t), CHAR_BIT*sizeof(sample_t), 96000.0 ); + open_generator ( &g, &s, genmode, atof (argv[4]), atof (argv[2]), atof (argv[3]) ); + open_amplifier ( &a, &s, argc > 6 ? atof (argv[6]) : 0.0001, atof (argv[5]) ); + open_keyboard ( &k ); + + report_open ( ); + experiment ( &g, &a, &k, &s, earmode ); + report_close ( ); + + close_keyboard ( &k ); + close_amplifier( &a ); + close_generator( &g ); + close_soundcard( &s ); + + return 0; +} + +/* end of ath.c */ + + diff --git a/misc/auenc b/misc/auenc new file mode 100755 index 0000000..50d9c81 --- /dev/null +++ b/misc/auenc @@ -0,0 +1,39 @@ +#!/bin/sh +# +# auenc -- version 0.1 +# +# A wrapper for lame to encode multiple files. By default, a .wav +# extension is removed and replaced by .mp3 . +# +# (C) 1999 Gerhard Wesp <gwesp@cosy.sbg.ac.at> under the GPL. + +# set the variables below according to your taste +LAME=lame +LAME_OPTS="-S -h -v -V 0 -b 256" # high quality, silent operation + +if [ $# -lt 1 ] ; then + exec 1>&2 + cat << _EOF_ +usage: $0 [options] file... +options: + -d --delete: delete original file after successful encoding +_EOF_ + exit 1 +fi + +unset DELETE +case "$1" in + -d | --delete ) DELETE=1 ; shift ;; +esac + +for f +do + $LAME $LAME_OPTS "$f" `basename "$f" .wav`.mp3 || { + exec 1>&2 + echo "encoding of $f failed, aborting..." + exit 1 + } + if [ -n "$DELETE" ] ; then + rm -f "$f" + fi +done diff --git a/misc/depcomp b/misc/depcomp new file mode 100755 index 0000000..04701da --- /dev/null +++ b/misc/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/misc/lame4dos.bat b/misc/lame4dos.bat new file mode 100644 index 0000000..b15cb3e --- /dev/null +++ b/misc/lame4dos.bat @@ -0,0 +1,41 @@ +@echo off
+rem ---------------------------------------------
+rem PURPOSE:
+rem - put this Batch-Command on your Desktop,
+rem so you can drag and drop wave files on it
+rem and LAME will encode them to mp3 format.
+rem - put this Batch-Command in a place mentioned
+rem in your PATH environment, start the DOS-BOX
+rem and change to a directory where your wave
+rem files are located. the following line will
+rem encode all your wave files to mp3
+rem "lame.bat *.wav"
+rem ---------------------------------------------
+rem C2000 Robert Hegemann
+rem ---------------------------------------------
+rem Changes to support long filenames using 4DOS
+rem by Alexander Stumpf <dropdachalupa@gmx.net>
+rem ---------------------------------------------
+rem please set LAME and LAMEOPTS
+rem LAME - where the executeable is
+rem OPTS - options you like LAME to use
+
+ set LAME=c:\progra~1\sound&~1\lame\lame.exe
+ set OPTS=-h --lowpass-width 2 --lowpass 20.5 -b 112 --abr 180
+
+rem ---------------------------------------------
+
+ set thecmd=%LAME% %OPTS%
+ for %%f in (%&) do (%thecmd% %@sfn[%%f]^(ren %@sfn[%%f].mp3 "%@lfn[%%f].mp_">NUL))
+ ren *.mp3.mp_ *.new.mp3 >& NUL
+ ren *.wav.mp_ *.mp3 >& NUL
+ goto endmark
+:errormark
+ echo.
+ echo.
+ echo ERROR processing %1
+ echo.
+:endmark
+rem
+rem finished
+rem
diff --git a/misc/lameGUI.html b/misc/lameGUI.html new file mode 100644 index 0000000..db90fd0 --- /dev/null +++ b/misc/lameGUI.html @@ -0,0 +1,403 @@ +<html> + +<head> +<meta http-equiv="Content-Type" +content="text/html; charset=iso-8859-1"> +<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0"> +<title>Lame</title> +<!-- LAME HTML GUI V0.2 for LAME.VBS by Ralf Kempkens (ralf.kempkens@epost.de) + -- $ID$ + -- + -- purpose of this page is being a frontend for lame.vbs v0.3 or later + -- it is launched from lame.vbs if useGUI in lame.vbs is set to 'True' + -- automatically + -- lame will then use the options chosen + -- + -- TODO: add other options, nicer layout... + --> +</head> + +<body bgcolor="#FFFFFF" topmargin="4" leftmargin="4"> +<script> + function updateOptions() { + var f=document.forms.lameform; + var opts=""; + opts+=f.bitrate.options[f.bitrate.selectedIndex].value + " " + + f.mode.value; + + if (f.high_quality.checked) + opts+= " " + f.high_quality.value; + + if (f.fast.checked) + opts+=" "+f.fast.value; + + if (f.vbr.checked){ + opts+=" "+f.vbr.value+ " " + f.vbr_quality.value + " " + f.max_bitrate.value; + if (f.enforce_min_bitrate.checked) + opts+= " " + f.enforce_min_bitrate.value; + } + + if (f.copyright.checked) + opts+= " " + f.copyright.value; + + if (f.copy.checked) + opts+= " " + f.copy.value; + + if (f.no_filters.checked) + opts+= " " + f.no_filters.value; + + if (f.title.value != "") + opts+= " --tt \""+f.title.value+"\""; + + if (f.artist.value != "") + opts+=" --ta \""+f.artist.value+"\""; + + if (f.album.value != "") + opts+=" --tl \""+f.album.value+"\""; + + if (f.year.value != "") + opts+=" --ty "+f.year.value; + + if (f.track.value != "") + opts+=" --tn "+f.track.value; + + if (f.genre.value >= 0) + opts+=" --tg "+f.genre.value; + + if (f.comment.value != "") + opts+=" --tc \""+f.comment.value+"\""; + + f.lameoptions.value=opts;; + return; + } +</script> +<noscript> +<H1><font color="red">JavaScript must be activated in order to use this frontend. Currently it is not!</font></H1> +</noscript> + +<form method="POST" name="lameform"> + <input type="hidden" name="lameoptions" value="not processed"><h1><font + face="Arial">LAME Frontend</font></h1> + <table border="0"> + <tr> + <td><font face="Arial"><strong>Fixed Bitrate</strong></font></td> + <td colspan="2"> </td> + </tr> + <tr> + <td><font face="Arial">bitrate (-b) <select + name="bitrate" size="1" onchange="updateOptions()"> + <option value="-b 8">8 kbs</option> + <option value="-b 16">16 kbs</option> + <option value="-b 24">24 kbs</option> + <option value="-b 32">32 kbs</option> + <option value="-b 40">40 kbs</option> + <option value="-b 48">48 kbs</option> + <option value="-b 56">56 kbs</option> + <option value="-b 64">64 kbs</option> + <option value="-b 80">80 kbs</option> + <option value="-b 96">96 kbs</option> + <option selected value="-b 128">128 kbs</option> + <option value="-b 112">112 kbs</option> + <option value="-b 144">144 kbs</option> + <option value="-b 160">160 kbs</option> + <option value="-b 192">192 kbs</option> + <option value="-b 224">224 kbs</option> + <option value="-b 256">256 kbs</option> + <option value="-b 320">320 kbs</option> + </select></font></td> + <td colspan="2"><font face="Arial"><input + type="checkbox" checked name="high_quality" + value="-h" onchange="updateOptions()">high quality (-h)</font></td> + </tr> + <tr> + <td> </td> + <td colspan="2"><font face="Arial"><input + type="checkbox" name="fast" value="-f" + onchange="updateOptions()">fast (no noise shaping)</font></td> + </tr> + <tr> + <td> </td> + <td colspan="2"> </td> + </tr> + <tr> + <td><font face="Arial"><strong>Variable Bitrate</strong></font></td> + <td colspan="2"> </td> + </tr> + <tr> + <td><font face="Arial"><input type="checkbox" + name="vbr" value="-v" onchange="updateOptions()">variable + bitrate (-v)</font></td> + <td colspan="2"><font face="Arial">VBR quality (-V) <select + name="vbr_quality" size="1" + onchange="updateOptions()"> + <option value="-V 0">0 (highest)</option> + <option value="-V 1">1</option> + <option value="-V 2">2</option> + <option value="-V 3">3</option> + <option value="-V 4">4</option> + <option selected value="-V 5">5 (medium)</option> + <option value="-V 6">6</option> + <option value="-V 7">7</option> + <option value="-V 8">8</option> + <option value="-V 9">9 (lowest)</option> + </select></font></td> + </tr> + <tr> + <td><font face="Arial">maximum bitrate (-B) <select + name="max_bitrate" size="1" + onchange="updateOptions()"> + <option selected value>none</option> + <option value="-B 8">8 kbs</option> + <option value="-B 16">16 kbs</option> + <option value="-B 24">24 kbs</option> + <option value="-B 32">32 kbs</option> + <option value="-B 40">40 kbs</option> + <option value="-B 48">48 kbs</option> + <option value="-B 56">56 kbs</option> + <option value="-B 64">64 kbs</option> + <option value="-B 80">80 kbs</option> + <option value="-B 96">96 kbs</option> + <option value="-b 128">128 kbs</option> + <option value="-B 112">112 kbs</option> + <option value="-B 144">144 kbs</option> + <option value="-B 160">160 kbs</option> + <option value="-B 192">192 kbs</option> + <option value="-B 224">224 kbs</option> + <option value="-B 256">256 kbs</option> + <option value="-B 320">320 kbs</option> + </select></font></td> + <td colspan="2"><font face="Arial"><input + type="checkbox" name="enforce_min_bitrate" value="-F" + onchange="updateOptions()">enforce min. bitrate (-F)</font></td> + </tr> + <tr> + <td> </td> + <td colspan="2"> </td> + </tr> + <tr> + <td><font face="Arial"><strong>General</strong></font></td> + <td colspan="2"> </td> + </tr> + <tr> + <td><font face="Arial">mode (-m) <select name="mode" + size="1" onchange="updateOptions()"> + <option value="-m m">mono</option> + <option value="-m s">stereo</option> + <option selected value="-m j">joint stereo</option> + <option value="-m f">mid/side stereo</option> + </select></font></td> + <td colspan="2"><font face="Arial"><input + type="checkbox" name="no_filters" value="-k" + onchange="updateOptions()">disable all filters (-k)</font></td> + </tr> + <tr> + <td><font face="Arial"><input type="checkbox" + name="copyright" value="-c" + onchange="updateOptions()">copyrighted (-c)</font></td> + <td colspan="2"><font face="Arial"><input + type="checkbox" name="copy" value="-o" + onchange="updateOptions()">non-original (-o)</font></td> + </tr> + <tr> + <td> </td> + <td colspan="2"> </td> + </tr> + <tr> + <td><font face="Arial"><strong>ID3-Tag</strong></font></td> + <td colspan="2"> </td> + </tr> + <tr> + <td><font face="Arial">title (--tt) <input + type="text" size="30" name="title" onChange="updateOptions()"></font></td> + <td colspan="2"><font face="Arial">artist (--ta) <input + type="text" size="30" name="artist" onChange="updateOptions()"></font></td> + </tr> + <tr> + <td><font face="Arial">album (--tl) <input + type="text" size="30" name="album" onChange="updateOptions()"></font></td> + <td><font face="Arial">year (--ty) <input type="text" + size="4" name="year" onChange="updateOptions()"></font></td> + <td><font face="Arial">track (--tn) <input + type="text" size="2" name="track" onChange="updateOptions()"></font></td> + </tr> + <tr> + <td><font face="Arial">comment (--tc) </font><input + type="text" size="30" name="comment" onChange="updateOptions()"></td> + <td colspan="2"><font face="Arial">genre (--tg) </font><select + name="genre" size="1" onChange="updateOptions()"> + <option selected value="-1">none + <option value="123">A Cappella </option> + <option value="34">Acid </option> + <option value="74">Acid Jazz </option> + <option value="73">Acid Punk </option> + <option value="99">Acoustic </option> + <option value="20">Alternative </option> + <option value="40">Alt. Rock </option> + <option value="26">Ambient </option> + <option value="145">Anime </option> + <option value="90">Avantgarde </option> + <option value="116">Ballad </option> + <option value="41">Bass </option> + <option value="135">Beat </option> + <option value="85">Bebob </option> + <option value="96">Big Band </option> + <option value="138">Black Metal </option> + <option value="89">Bluegrass </option> + <option value="0">Blues </option> + <option value="107">Booty Bass </option> + <option value="132">BritPop </option> + <option value="65">Cabaret </option> + <option value="88">Celtic </option> + <option value="104">Chamber Music </option> + <option value="102">Chanson </option> + <option value="97">Chorus </option> + <option value="136">Christian Gangsta Rap </option> + <option value="61">Christian Rap </option> + <option value="141">Christian Rock </option> + <option value="32">Classical </option> + <option value="1">Classic Rock </option> + <option value="112">Club </option> + <option value="128">Club-House </option> + <option value="57">Comedy </option> + <option value="140">Contemporary Christian </option> + <option value="2">Country </option> + <option value="139">Crossover </option> + <option value="58">Cult </option> + <option value="3">Dance </option> + <option value="125">Dance Hall </option> + <option value="50">Darkwave </option> + <option value="22">Death Metal </option> + <option value="4">Disco </option> + <option value="55">Dream </option> + <option value="127">Drum & Bass </option> + <option value="122">Drum Solo </option> + <option value="120">Duet </option> + <option value="98">Easy Listening </option> + <option value="52">Electronic </option> + <option value="48">Ethnic </option> + <option value="54">Eurodance </option> + <option value="124">Euro-House </option> + <option value="25">Euro-Techno </option> + <option value="84">Fast-Fusion </option> + <option value="80">Folk </option> + <option value="115">Folklore </option> + <option value="81">Folk/Rock </option> + <option value="119">Freestyle </option> + <option value="5">Funk </option> + <option value="30">Fusion </option> + <option value="36">Game </option> + <option value="59">Gangsta Rap </option> + <option value="126">Goa </option> + <option value="38">Gospel </option> + <option value="49">Gothic </option> + <option value="91">Gothic Rock </option> + <option value="6">Grunge </option> + <option value="129">Hardcore </option> + <option value="79">Hard Rock </option> + <option value="137">Heavy Metal </option> + <option value="7">Hip-Hop </option> + <option value="35">House </option> + <option value="100">Humour </option> + <option value="131">Indie </option> + <option value="19">Industrial </option> + <option value="33">Instrumental </option> + <option value="46">Instrumental Pop </option> + <option value="47">Instrumental Rock </option> + <option value="8">Jazz </option> + <option value="29">Jazz+Funk </option> + <option value="146">JPop </option> + <option value="63">Jungle </option> + <option value="86">Latin </option> + <option value="71">Lo-Fi </option> + <option value="45">Meditative </option> + <option value="142">Merengue </option> + <option value="9">Metal </option> + <option value="77">Musical </option> + <option value="82">National Folk </option> + <option value="64">Native American </option> + <option value="133">Negerpunk </option> + <option value="10">New Age </option> + <option value="66">New Wave </option> + <option value="39">Noise </option> + <option value="11">Oldies </option> + <option value="103">Opera </option> + <option value="12">Other </option> + <option value="75">Polka </option> + <option value="134">Polsk Punk </option> + <option value="13">Pop</option> + <option value="53">Pop-Folk </option> + <option value="62">Pop/Funk </option> + <option value="109">Porn Groove </option> + <option value="117">Power Ballad </option> + <option value="23">Pranks </option> + <option value="108">Primus </option> + <option value="92">Progressive Rock </option> + <option value="67">Psychedelic </option> + <option value="93">Psychedelic Rock </option> + <option value="43">Punk </option> + <option value="121">Punk Rock </option> + <option value="15">Rap </option> + <option value="68">Rave </option> + <option value="14">R&B </option> + <option value="16">Reggae </option> + <option value="76">Retro </option> + <option value="87">Revival </option> + <option value="118">Rhythmic Soul </option> + <option value="17">Rock </option> + <option value="78">Rock & Roll </option> + <option value="143">Salsa </option> + <option value="114">Samba </option> + <option value="110">Satire </option> + <option value="69">Showtunes </option> + <option value="21">Ska </option> + <option value="111">Slow Jam </option> + <option value="95">Slow Rock </option> + <option value="105">Sonata </option> + <option value="42">Soul </option> + <option value="37">Sound Clip </option> + <option value="24">Soundtrack </option> + <option value="56">Southern Rock </option> + <option value="44">Space </option> + <option value="101">Speech </option> + <option value="83">Swing </option> + <option value="94">Symphonic Rock </option> + <option value="106">Symphony </option> + <option value="147">Synthpop </option> + <option value="113">Tango </option> + <option value="18">Techno </option> + <option value="51">Techno-Industrial </option> + <option value="130">Terror </option> + <option value="144">Thrash Metal </option> + <option value="60">Top 40 </option> + <option value="70">Trailer </option> + <option value="31">Trance </option> + <option value="72">Tribal </option> + <option value="27">Trip-Hop </option> + <option value="28">Vocal </option> + </select></td> + </tr> + <tr> + <td> </td> + <td> </td> + <td> </td> + </tr> + <tr> + <td align="center" colspan="3"><font face="Arial"><input + type="button" name="okbutton" value="Start LAME" + </font></font></td> + </tr> + </table> +</form> + +<table border="0"> + <tr> + <td>[<a href="USAGE" target="_blank">LAME HELP</a>] [<a + href="README" target="_blank">LAME Readme</a>] [<a + href="history.html" target="_blank">LAME History</a>] [<a + href="http://www.mp3dev.org" target="_blank">LAME + Homepage</a>]</td> + <td> </td> + </tr> +</table> +</body> +</html> diff --git a/misc/lameid3.pl b/misc/lameid3.pl new file mode 100644 index 0000000..5352877 --- /dev/null +++ b/misc/lameid3.pl @@ -0,0 +1,55 @@ +# +# From: Per Bolmstedt <tomten@kol14.com> +# +# AC> If someone has scripts that read input ID3 tags and convert +# AC> them to args for lame (which then encodes the tags into the +# AC> output files), let me know, too! +# +# This is easy peasy using Perl. Especially using Chris Nandor's excellent +# MP3::Info package (available on CPAN). Here's a program I just wrote that +# I think does what you want. Invoke it with "<program> <file> [options]" +# (where the options can include an output filename), like for example: +# +# lameid3.pl HQ.mp3 LQ.mp3 -fv +# +# (Note how the syntax differs from that of Lame's.) The program will +# extract ID3 tags from the input file and invoke Lame with arguments for +# including them. (This program has not undergone any real testing..) + +use MP3::Info; +use strict; + +my %flds = ( + TITLE => 'tt', + ARTIST => 'ta', + ALBUM => 'tl', + YEAR => 'ty', + COMMENT => 'tc', + GENRE => 'tg', + TRACKNUM => 'tn' + ); + +my $f = shift @ARGV; +my $s = "lame ${f} " . &makeid3args( $f ) . join ' ', @ARGV; +print STDERR "[${s}]\n"; +system( $s ); + +sub makeid3args( $ ) +{ + my $s; + if ( my $tag = get_mp3tag( @_->[ 0 ] ) ) + { + for ( keys %flds ) + { + if ( $tag->{ $_ } ) + { + $s .= sprintf( + "--%s \"%s\" ", + %flds->{ $_ }, + $tag->{ $_ } ); + } + } + } + return $s || ""; +} + diff --git a/misc/mlame b/misc/mlame new file mode 100755 index 0000000..23beab5 --- /dev/null +++ b/misc/mlame @@ -0,0 +1,195 @@ +#!/bin/sh + +############################################################################ +# +# Run the LAME encoder on multiple files, with option to delete .wav files +# after encoding. "mlame -?" will give instructions. +# +# Robert Hegemann +# modified on request: Frank Klemm <pfk@uni-jena.de> +# +############################################################################ + +# encoder path to use +mp3coder="lame" +mp3analyzer="mlame_corr" + +# default options to use +options_low="-h -d -mj -b 128" +options_high="-h -d -mj -V 1 -b 112 -B 320" +options=$options_high + +# remove source? +removesource=false + +# force overwrite of destination +testoverwrite=true + +# waiting after error report n seconds +errordelay=1 + +helptext="\n\ +This script runs the LAME mp3 encoder on multiple files: \n\n\ + $0 [options] <file 1> ... <file n>\n\ +\n\ + options:\n\ + -? this help text\n\ + -r remove files after encoding\n\ + -f force overwrite of destination if exists\n\ + -l low quality settings\n\ + -h high quality settings\n\ + -o \"<lame options>\" overrides script default options +\n\ + example:\n\ + $0 -r -f -o \"-v -V 0 -b 112\" a*.wav z*.aif g*.mp?\n\ +\n\ +" + +# process command-line options +# this could be extended to fake the +# commandline interface of the mp3encoder + +while getopts ":o:r:h:l:f" optn; do + case $optn in + o ) options=$OPTARG # replace default options + echo New lame options are \'$options\' + ;; + r ) removesource=true + echo Removing source files after successfully converting + ;; + f ) testoverwrite=false + echo Force overwriting existing destination files + ;; + h ) options=$options_high + ;; + l ) options=$options_low + ;; + \? ) printf "$helptext" + sleep $errordelay + exit 1 + ;; + esac +done +shift $(($OPTIND - 1)) + +# no files remaining? + +if [ "$1" = "" ]; then + printf "$helptext" + sleep $errordelay + exit 1 +fi + +# process input-files + +for src in "$@"; do + + case $src in + *[.][wW][aA][vV] ) + dst=${src%[.][wW][aA][vV]}.mp3 + if [ -f "$src" ]; then + if [ $testoverwrite = true -a -f "$dst" ]; then + echo \'$dst\' already exists, skipping + sleep $errordelay + elif $mp3coder $options `$mp3analyzer "$src"` "$src" "$dst"; then + if [ $removesource = true ]; then + rm -f "$src" + fi + else + echo converting of \'$src\' to \'$dst\' failed + sleep $errordelay + fi + else + echo No source file \'$src\' found. + sleep $errordelay + fi + ;; + + *[.][aA][iI][fF] ) + dst=${src%[.][aA][iI][fF]}.mp3 + if [ -f "$src" ]; then + if [ $testoverwrite = true -a -f "$dst" ]; then + echo \'$dst\' already exists, skipping + sleep $errordelay + elif $mp3coder $options "$src" "$dst"; then + if [ $removesource = true ]; then + rm -f "$src" + fi + else + echo converting of \'$src\' to \'$dst\' failed + sleep $errordelay + fi + else + echo No source file \'$src\' found. + sleep $errordelay + fi + ;; + + *[.][aA][iI][fF][fF] ) + dst=${src%[.][aA][iI][fF][fF]}.mp3 + if [ -f "$src" ]; then + if [ $testoverwrite = true -a -f "$dst" ]; then + echo \'$dst\' already exists, skipping + sleep $errordelay + elif $mp3coder $options "$src" "$dst"; then + if [ $removesource = true ]; then + rm -f "$src" + fi + else + echo converting of \'$src\' to \'$dst\' failed + sleep $errordelay + fi + else + echo No source file \'$src\' found. + sleep $errordelay + fi + ;; + + *[.][mM][pP][gG12] ) + dst=${src%[.][mM][pP][gG12]}.mp3 + if [ -f "$src" ]; then + if [ $testoverwrite = true -a -f "$dst" ]; then + echo \'$dst\' already exists, skipping + sleep $errordelay + elif $mp3coder $options "$src" "$dst"; then + if [ $removesource = true ]; then + rm -f "$src" + fi + else + echo converting of \'$src\' to \'$dst\' failed + sleep $errordelay + fi + else + echo No source file \'$src\' found. + sleep $errordelay + fi + ;; + + *[.][mM][pP]3 ) + dst=${src%[.][mM][pP]3}-new-converted-file.${src##*.} + if [ -f "$src" ]; then + if [ $testoverwrite = true -a -f "$dst" ]; then + echo \'$dst\' already exists, skipping + sleep $errordelay + elif $mp3coder $options "$src" "$dst"; then + if [ $removesource = true ]; then + mv -f "$dst" "$src" + fi + else + echo converting of \'$src\' to \'$dst\' failed + sleep $errordelay + fi + else + echo No source file \'$src\' found. + sleep $errordelay + fi + ;; + + * ) # the rest + echo warning: File extention \'.${src##*.}\' not supported + sleep $errordelay + ;; + + esac + +done diff --git a/misc/mlame_corr.c b/misc/mlame_corr.c new file mode 100644 index 0000000..4305b63 --- /dev/null +++ b/misc/mlame_corr.c @@ -0,0 +1,220 @@ +/* + Bug: + - runs only on little endian machines for WAV files + - Not all WAV files are recognized + */ + +#include <stdio.h> +#include <unistd.h> +#include <math.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <memory.h> + +typedef signed short stereo [2]; +typedef signed short mono; +typedef struct { + unsigned long long n; + long double x; + long double x2; + long double y; + long double y2; + long double xy; +} korr_t; + +void analyze_stereo ( const stereo* p, size_t len, korr_t* k ) +{ + long double _x = 0, _x2 = 0, _y = 0, _y2 = 0, _xy = 0; + double t1; + double t2; + + k -> n += len; + + for ( ; len--; p++ ) { + _x += (t1 = (*p)[0]); _x2 += t1 * t1; + _y += (t2 = (*p)[1]); _y2 += t2 * t2; + _xy += t1 * t2; + } + + k -> x += _x ; + k -> x2 += _x2; + k -> y += _y ; + k -> y2 += _y2; + k -> xy += _xy; +} + +void analyze_dstereo ( const stereo* p, size_t len, korr_t* k ) +{ + static double l0 = 0; + static double l1 = 0; + long double _x = 0, _x2 = 0, _y = 0, _y2 = 0, _xy = 0; + double t1; + double t2; + + k -> n += len; + + for ( ; len--; p++ ) { + _x += (t1 = (*p)[0] - l0); _x2 += t1 * t1; + _y += (t2 = (*p)[1] - l1); _y2 += t2 * t2; + _xy += t1 * t2; + l0 = (*p)[0]; + l1 = (*p)[1]; + } + + k -> x += _x ; + k -> x2 += _x2; + k -> y += _y ; + k -> y2 += _y2; + k -> xy += _xy; +} + + +void analyze_mono ( const mono* p, size_t len, korr_t* k ) +{ + long double _x = 0, _x2 = 0; + double t1; + + k -> n += len; + + for ( ; len--; p++ ) { + _x += (t1 = (*p)); _x2 += t1 * t1; + } + + k -> x += _x ; + k -> x2 += _x2; + k -> y += _x ; + k -> y2 += _x2; + k -> xy += _x2; +} + +void analyze_dmono ( const mono* p, size_t len, korr_t* k ) +{ + static double l0 = 0; + long double _x = 0, _x2 = 0; + double t1; + + k -> n += len; + + for ( ; len--; p++ ) { + _x += (t1 = (*p) - l0); _x2 += t1 * t1; + l0 = *p; + } + + k -> x += _x ; + k -> x2 += _x2; + k -> y += _x ; + k -> y2 += _x2; + k -> xy += _x2; +} + +int sgn ( long double x ) +{ + if ( x > 0 ) return +1; + if ( x < 0 ) return -1; + return 0; +} + +int report ( const korr_t* k ) +{ + long double scale = sqrt ( 1.e5 / (1<<29) ); // Sine Full Scale is +10 dB, 7327 = 100% + long double r; + long double rd; + long double sx; + long double sy; + long double x; + long double y; + long double b; + + r = (k->x2*k->n - k->x*k->x) * (k->y2*k->n - k->y*k->y); + r = r > 0.l ? (k->xy*k->n - k->x*k->y) / sqrt (r) : 1.l; + sx = k->n > 1 ? sqrt ( (k->x2 - k->x*k->x/k->n) / (k->n - 1) ) : 0.l; + sy = k->n > 1 ? sqrt ( (k->y2 - k->y*k->y/k->n) / (k->n - 1) ) : 0.l; + x = k->n > 0 ? k->x/k->n : 0.l; + y = k->n > 0 ? k->y/k->n : 0.l; + + b = atan2 ( sy, sx * sgn (r) ) * ( 8 / M_PI); + +// 6 5 4 3 2 +// _______________________________ +// |\ | /| +// 7 | \ | / | 1 +// | \ | / | +// | \ | / | +// | \ | / | +// 8 |--------------+--------------| 0 +// | / | \ | +// | / | \ | +// -7 | / | \ | -1 +// | / | \ | +// |/_____________|_____________\| +// +// -6 -5 -4 -3 -2 + + if ( r > 0.98 ) { + printf ("-mm"); // disguised mono file + return; + } + if ( fabs (b-2) > 0.666 ) { + printf ("-ms"); // low profit for joint stereo + return; + } + if ( r < 0.333 ) { + printf ("-ms"); // low profit for joint stereo + return; + } +} + +void readfile ( const char* name, int fd ) +{ + unsigned short header [22]; + stereo s [4096]; + mono m [8192]; + size_t samples; + korr_t k0; + korr_t k1; + + memset ( &k0, 0, sizeof(k0) ); + memset ( &k1, 0, sizeof(k1) ); + + read ( fd, header, sizeof(header) ); + + switch ( header[11] ) { + case 1: + printf ("-mm\n"); + break; + + case 2: + while ( ( samples = read (fd, s, sizeof(s)) ) > 0 ) { + analyze_stereo ( s, samples / sizeof (*s), &k0 ); + analyze_dstereo ( s, samples / sizeof (*s), &k1 ); + } + report (&k0); + report (&k1); + break; + + default: + fprintf ( stderr, "%u Channels not supported: %s\n", header[11], name ); + break; + } +} + +int main ( int argc, char** argv ) +{ + char* name; + int fd; + + if (argc < 2) + readfile ( "<stdin>", 0 ); + else + while ( (name = *++argv) != NULL ) { + if ( (fd = open ( name, O_RDONLY )) >= 0 ) { + readfile ( name, fd ); + close ( fd ); + } else { + fprintf ( stderr, "Can't open: %s\n", name ); + } + } + + return 0; +} diff --git a/misc/mugeco.sh b/misc/mugeco.sh new file mode 100755 index 0000000..6be2774 --- /dev/null +++ b/misc/mugeco.sh @@ -0,0 +1,137 @@ +#!/bin/sh +progname=mugeco version=0.1 +programr='Alexander Leidinger' +progdate='7 Dec 2000' +progdesc='MUltiGEnerationCOding' +# NEEDS: getopt, lame +# Please have a look at the DEFAULTS section. + +# $Id: mugeco.sh,v 1.6 2000/12/08 13:47:56 aleidinger Exp $ + +usage() { +cat << EOF +** $progname v$version, $progdate ** +by $programr +$progdesc +usage: $progname [ <flags> ] -g <num> <file> + -v use builtin VBR options + -g <num> number of generations + -h help + + used + - env vars: + * LAME : alternative encoder binary + * LAMEOPT: alternative encoder options + - VBR opts: $enc_vbr_opts + - CBR opts: $enc_cbr_opts +EOF +} + +# DEFAULTS + +# if you can, use getopt(1) (c)1997 by Frodo Looijaard <frodol@dds.nl> +# it's in most modern unixen, or look at http://huizen.dds.nl/~frodol/ +: ${GETOPT=getopt} # helper program +# mktemp (optional) is also in most modern unixen (originally from OpenBSD) +: ${MKTEMP=mktemp} # helper program +: ${TMPDIR:=/tmp} # set default temp directory +: ${LAME:=lame} # path to LAME + +enc_cbr_opts="-b192 -h --lowpass 18 --lowpass-width 0" +enc_vbr_opts="--vbr-mtrh --nspsytune -v -h -d -Y -X3" +enc_opts=${LAMEOPT:-$enc_cbr_opts} +num= # default number of generations + +# DEFINE FUNCTIONS + +e() { echo "$progname: $*"; } +die() { # usage: die [ <exitcode> [ <errormessage> ] ] + trap '' 1 2 3 13 15 + exitcode=0 + [ $# -gt 0 ] && { exitcode=$1; shift; } + [ $# -gt 0 ] && e "Error: $*" >&2 + exit $exitcode +} + +# tfile() +# this function creates temporary files. 'tfile temp' will make a tempfile +# and put the path to it in the variable $temp (defaults to variable $tf) +trap 'for f in $ztfiles; do rm -f "$f"; done' 0 +trap 'trap "" 1 2 3 13 15; exit 10' 1 2 3 13 15 +unset ztfiles +tfile() { # usage: tfile <variable_name> + ztf=`$MKTEMP -q $TMPDIR/$progname.XXXXXX 2>/dev/null` # try mktemp + if [ $? -gt 0 -o -z "$ztf" ]; then # if mktemp fails, do it unsafely + ztf=$TMPDIR/$LOGNAME.$progname.$$ + [ -e "$ztf" ] && ztf= || { touch $ztf && chmod 600 $ztf; } + fi + [ "$ztf" -a -f "$ztf" ] || { echo Could not make tempfile; exit 8; } + ztfiles="$ztfiles $ztf" + eval ${1:-tf}='$ztf' +} + +# PARSE COMMAND LINE + +options="g:vh" # option string for getopt(1) +help=; [ "$1" = -h -o "$1" = -help -o "$1" = --help ] && help=yes +[ "$help" ] && { usage; die; } +$GETOPT -T >/dev/null 2>&1 +[ $? -eq 4 ] && GETOPT="$GETOPT -n $progname -s sh" #frodol's getopt? +eval set -- `$GETOPT "$options" "$@"` +[ $# -lt 1 ] && { die 9 getopt failed; } +while [ $# -gt 0 ]; do + case "$1" in + -g) num=$2; shift ;; + -v) enc_opts=$enc_cbr_opts ;; + -h) help=y ;; + --) shift; break ;; + *) usage; die 9 "invalid command line syntax!" ;; + esac + shift +done +[ "$help" ] && { usage; die; } +[ $# -eq 0 ] && { usage; die 9 no arguments; } #change or remove if desired +# sanity checking +[ "$num" ] && echo "$num"|grep -q '^[0-9]*$' && [ $num -ge 1 ] \ + || die 1 please use the -g flag with a valid number + +# MAIN PROGRAM + +# what version of lame are we using? +lame_vers=`$LAME 2>&1 | awk 'NR==1{print $3}'` + +# check filename +[ -f "$1" ] || die 2 "'$1' isn't a file" +echo "$1"|grep -qi '\.wav$' || die 2 "'$1' isn't a .wav" + +# make tempfiles +base=`echo "$1"|sed 's/\.[^.]*$//'` +dest=${base}_generation_$num.wav +[ -e "$dest" ] && die 2 "'$dest' already exists" +touch "$dest" || die 2 "couldn't create '$dest'" +TMPDIR=. tfile tmpwav +TMPDIR=. tfile tmpmp3 +cp -f "$1" "$tmpwav" + +# do the loop +start=`date` +i=1 +while [ $i -le $num ]; do + e "Working on file '$1', generation number $i..." + + $LAME $enc_opts --tc "lame $lame_vers; Generation: $i" \ + "$tmpwav" "$tmpmp3" || die 3 encoding failed + $LAME --decode --mp3input "$tmpmp3" "$tmpwav" || die 3 decoding failed + + i=`expr $i + 1` +done +end=`date` + +# save the result +ln -f "$tmpwav" "$dest" + +echo +e "Start: $start" +e "Stop : $end" + +die diff --git a/misc/scalartest.c b/misc/scalartest.c new file mode 100644 index 0000000..01680d0 --- /dev/null +++ b/misc/scalartest.c @@ -0,0 +1,166 @@ +#include <stdio.h> +#include <math.h> +#include <asm/msr.h> +#include "resample.h" + +#define CLK 300.e6 +#define LOOPS 20000 + + +typedef double ( *ddf ) ( double ); + + +float a1 [256]; +float a2 [256]; + +void init ( void ) +{ + int i; + + for ( i = 0; i < sizeof(a1)/sizeof(*a1); i++ ) { + a1 [i] = sin(i)+0.2*sin(1.8*i)+log(2+i); + a2 [i] = cos(0.1*i); + } +} + +void test ( int no, scalar_t f ) +{ + unsigned long long t1; + unsigned long long t2; + unsigned long long t3; + unsigned long long t4; + int l; + double last = 0; + double curr = 0; + + printf ( "[%3u] %22.14f\t\t", no, (double)f (a1,a2) ); + fflush ( stdout ); + + do { + rdtscll (t1); + l = LOOPS; + do + ; + while (--l); + rdtscll (t2); + rdtscll (t3); + l = LOOPS; + do + f(a1,a2), f(a1,a2), f(a1,a2), f(a1,a2); + while (--l); + rdtscll (t4); + last = curr; + curr = (t4-t3-t2+t1) / CLK / LOOPS / 4 * 1.e9; + } while ( fabs(curr-last) > 1.e-4 * (curr+last) ); + printf ("%8.2f ns\n", (curr+last) / 2 ); +} + +void testn ( scalarn_t f ) +{ + unsigned long long t1; + unsigned long long t2; + unsigned long long t3; + unsigned long long t4; + int l; + int i; + double last = 0; + double curr = 0; + + for ( i = 1; i <= 64; i += i<6 ? 1 : i<8 ? 2 : i ) { + printf ( "[%3u] %22.14f\t\t", 4*i, (double)f (a1,a2,i) ); + fflush ( stdout ); + + do { + rdtscll (t1); + l = LOOPS; + do + ; + while (--l); + rdtscll (t2); + rdtscll (t3); + l = LOOPS; + do + f(a1,a2,i), f(a1,a2,i), f(a1,a2,i), f(a1,a2,i); + while (--l); + rdtscll (t4); + last = curr; + curr = (t4-t3-t2+t1) / CLK / LOOPS / 4 * 1.e9; + } while ( fabs(curr-last) > 1.e-4 * (curr+last) ); + printf ("%8.2f ns\n", (curr+last) / 2 ); + } +} + +void test2 ( const char* name, ddf f ) +{ + int i; + double x; + + printf ( "\n%%%% %s\n\n", name ); + + for ( i = -1000; i <= 1000; i++ ) { + x = 1.e-3 * i; + printf ( "%5d\t%12.8f\t%12.8f\t%12.8f\n", i, f(x), (f(x+5.e-5) - f(x-5.e-5))*1.e+4, (f(x+1.e-4) + f(x-1.e-4) - 2*f(x))*5.e+7 ); + } + printf ( "%%%%\n" ); + fflush ( stdout ); +} + + +int main ( int argc, char** argv ) +{ + +#if 0 + + test2 ( "Hann", hanning ); + test2 ( "Hamm", hamming ); + test2 ( "BM", blackman ); + test2 ( "BM1",blackman1 ); + test2 ( "BM2",blackman2 ); + test2 ( "BMH N",blackmanharris_nuttall ); + test2 ( "MNH Min",blackmanharris_min4 ); + +#else + + init (); + + test ( 4, scalar04_float32 ); + test ( 4, scalar04_float32_i387 ); + test ( 4, scalar04_float32_3DNow ); + test ( 4, scalar04_float32_SIMD ); + + test ( 8, scalar08_float32 ); + test ( 8, scalar08_float32_i387 ); + test ( 8, scalar08_float32_3DNow ); + test ( 8, scalar08_float32_SIMD ); + + test ( 12, scalar12_float32 ); + test ( 12, scalar12_float32_i387 ); + test ( 12, scalar12_float32_3DNow ); + test ( 12, scalar12_float32_SIMD ); + + test ( 16, scalar16_float32 ); + test ( 16, scalar16_float32_i387 ); + test ( 16, scalar16_float32_3DNow ); + test ( 16, scalar16_float32_SIMD ); + + test ( 20, scalar20_float32 ); + test ( 20, scalar20_float32_i387 ); + test ( 20, scalar20_float32_3DNow ); + test ( 20, scalar20_float32_SIMD ); + + test ( 24, scalar24_float32 ); + test ( 24, scalar24_float32_i387 ); + test ( 24, scalar24_float32_3DNow ); + test ( 24, scalar24_float32_SIMD ); + + testn( scalar4n_float32 ); + testn( scalar4n_float32_i387 ); + testn( scalar4n_float32_3DNow ); + testn( scalar4n_float32_SIMD ); + +#endif + + return 0; +} + +/* end of scalartest.c */ |