diff --git a/.bzrignore b/.bzrignore index 513346a1..6c9ff988 100644 --- a/.bzrignore +++ b/.bzrignore @@ -18,13 +18,13 @@ Makefile Makefile.in aclocal.m4 autom4te.cache -compile -config.guess +Cfg/compile +Cfg/config.guess config.log config.status -config.sub +Cfg/config.sub configure -depcomp +Cfg/depcomp doc/libsndfile.css examples/cooledit-fixer examples/generate @@ -35,12 +35,12 @@ examples/sndfile-convert examples/sndfile-data-trim examples/sndfile-info examples/sndfile-play -install-sh +Cfg/install-sh libsndfile-1.0.*pre* libsndfile.spec libtool -ltmain.sh -missing +Cfg/ltmain.sh +Cfg/missing regtest/sndfile-regtest sndfile.pc src/*sndfile.def @@ -83,3 +83,4 @@ tests/utils.c tests/utils.h tests/write_read_test.c src/FLAC/src/test_libFLAC/matrix +*.oct diff --git a/ChangeLog b/ChangeLog index c3e4f147..a60a48b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,115 @@ +2007-10-21 Erik de Castro Lopo + + * src/sndfile.h.in src/sndfile.c + Add command SFC_GET_CURRENT_SF_INFO. + + * src/sndfile.h.in src/sndfile.c src/create_symbols_file.py + Remove function sf_get_info (only ever in pre-release code). + + * tests/command_test.c + Add test for SFC_GET_CURRENT_SF_INFO. + +2007-10-15 Erik de Castro Lopo + + * src/wav.c + Add parsing of 'exif' chunks. Originally coded by Trent Apted. + + * configure.ac + Put config stuff in Cfg directory. + Remove check for inttypes.h. + +2007-10-10 Erik de Castro Lopo + + * src/w64.c + Fix writing of 'riff' chunk length and check for correct value in parser. + +2007-09-20 Erik de Castro Lopo + + * doc/index.html + Link to MP3 FAQ entry. + +2007-09-18 Erik de Castro Lopo + + * src/flac.c + Move the blocksize check to an earlier stage of flac_buffer_copy. + +2007-09-12 Erik de Castro Lopo + + * src/FLAC + Huge merge from FLAC upstream. + +2007-09-10 Erik de Castro Lopo + + * examples/*.c + Change license to all example programs to BSD. + +2007-09-08 Erik de Castro Lopo + + * src/FLAC/include/FLAC/metadata.h + Include to prevent compile error on OSX. + + * Octave/octave_test.sh + Disable test on OSX. Can't get it to work. + + * src/flac.c + Check the blocksize returned from the FLAC decoder to prevent buffer + overruns. Reported by Jeremy Friesner. Thanks. + +2007-09-07 Erik de Castro Lopo + + * Makefile.am M4/octave.m4 + Fix build when Octave headers are not present. + +2007-08-27 Erik de Castro Lopo + + * doc/development.html + Add note about bzr repository directory looking empty. + +2007-08-26 Erik de Castro Lopo + + * configure.ac Octave/* M4/octave_* + Bunch of changes to add ability to build GNU Octave modules to read/write + sound files using libsndfile from Octave. + +2007-08-23 Erik de Castro Lopo + + * acinclude.m4 configure.ac ... + Get rid of acinclude.m4 and replace it with an M4 directory. + +2007-08-21 Erik de Castro Lopo + + * src/sndfile.h.in + Remove crufty Metrowerks compiler support. Allow header file to be compiled + on windows with both GCC and microsoft compiler. + +2007-08-19 Erik de Castro Lopo + + * tests/dft_cmp.[ch] tests/floating_point_test.tpl + Clean up floating point tests. + +2007-08-14 Erik de Castro Lopo + + * src/aiff.c + Fix segfault when COMM chunk length is byte swapped. + +2007-08-09 Erik de Castro Lopo + + * src/common.h src/mat4.c src/mat5.c src/sndfile.c + Add a generic SFE_CHANNEL_COUNT_ZERO error, remove format specific errors. + + * src/au.c + Fix crash on AU files with zero channel count. Reported by Ben Alison. + +2007-08-08 Erik de Castro Lopo + + * src/voc.c + Fix bug in handling file supplied by Matt Olenik. + +2007-07-31 Erik de Castro Lopo + + * src/OGG + Merge from OGG upstream sources. + 2007-07-25 Erik de Castro Lopo * src/FLAC diff --git a/M4/Makefile.am b/M4/Makefile.am new file mode 100644 index 00000000..3ea1b7fb --- /dev/null +++ b/M4/Makefile.am @@ -0,0 +1,5 @@ +## Process this file with automake to produce Makefile.in + +EXTRA_DIST = add_cflags.m4 clip_mode.m4 endian.m4 extra_largefile.m4 \ + flexible_array.m4 llrint.m4 lrint.m4 lrintf.m4 octave.m4 + diff --git a/M4/add_cflags.m4 b/M4/add_cflags.m4 new file mode 100644 index 00000000..eeb6efda --- /dev/null +++ b/M4/add_cflags.m4 @@ -0,0 +1,15 @@ +dnl @synopsis AC_ADD_CFLAGS +dnl +dnl Add the given option to CFLAGS, if it doesn't break the compiler + +AC_DEFUN([AC_ADD_CFLAGS], +[AC_MSG_CHECKING([if $CC accepts $1]) + ac_add_cflags__old_cflags="$CFLAGS" + CFLAGS="$CFLAGS $1" + AC_TRY_LINK([#include ], + [puts("Hello, World!"); return 0;], + AC_MSG_RESULT([yes]), + AC_MSG_RESULT([no]) + CFLAGS="$ac_add_cflags__old_cflags") + ]) +])# AC_ADD_CFLAGS diff --git a/M4/clip_mode.m4 b/M4/clip_mode.m4 new file mode 100644 index 00000000..57c94a96 --- /dev/null +++ b/M4/clip_mode.m4 @@ -0,0 +1,124 @@ +dnl @synopsis AC_C_CLIP_MODE +dnl +dnl Determine the clipping mode when converting float to int. +dnl @version 1.0 May 17 2003 +dnl @author Erik de Castro Lopo +dnl +dnl Permission to use, copy, modify, distribute, and sell this file for any +dnl purpose is hereby granted without fee, provided that the above copyright +dnl and this permission notice appear in all copies. No representations are +dnl made about the suitability of this software for any purpose. It is +dnl provided "as is" without express or implied warranty. + + + + + + + +dnl Find the clipping mode in the following way: +dnl 1) If we are not cross compiling test it. +dnl 2) IF we are cross compiling, assume that clipping isn't done correctly. + +AC_DEFUN([AC_C_CLIP_MODE], +[AC_CACHE_CHECK(processor clipping capabilities, + ac_cv_c_clip_type, + +# Initialize to unknown +ac_cv_c_clip_positive=unknown +ac_cv_c_clip_negative=unknown + + +if test $ac_cv_c_clip_positive = unknown ; then + AC_TRY_RUN( + [[ + #define _ISOC9X_SOURCE 1 + #define _ISOC99_SOURCE 1 + #define __USE_ISOC99 1 + #define __USE_ISOC9X 1 + #include + int main (void) + { double fval ; + int k, ival ; + + fval = 1.0 * 0x7FFFFFFF ; + for (k = 0 ; k < 100 ; k++) + { ival = (lrint (fval)) >> 24 ; + if (ival != 127) + return 1 ; + + fval *= 1.2499999 ; + } ; + + return 0 ; + } + ]], + ac_cv_c_clip_positive=yes, + ac_cv_c_clip_positive=no, + ac_cv_c_clip_positive=unknown + ) + + AC_TRY_RUN( + [[ + #define _ISOC9X_SOURCE 1 + #define _ISOC99_SOURCE 1 + #define __USE_ISOC99 1 + #define __USE_ISOC9X 1 + #include + int main (void) + { double fval ; + int k, ival ; + + fval = -8.0 * 0x10000000 ; + for (k = 0 ; k < 100 ; k++) + { ival = (lrint (fval)) >> 24 ; + if (ival != -128) + return 1 ; + + fval *= 1.2499999 ; + } ; + + return 0 ; + } + ]], + ac_cv_c_clip_negative=yes, + ac_cv_c_clip_negative=no, + ac_cv_c_clip_negative=unknown + ) + fi + +if test $ac_cv_c_clip_positive = yes ; then + ac_cv_c_clip_positive=1 +else + ac_cv_c_clip_positive=0 + fi + +if test $ac_cv_c_clip_negative = yes ; then + ac_cv_c_clip_negative=1 +else + ac_cv_c_clip_negative=0 + fi + +[[ +case "$ac_cv_c_clip_positive$ac_cv_c_clip_negative" in + "00") + ac_cv_c_clip_type="none" + ;; + "10") + ac_cv_c_clip_type="positive" + ;; + "01") + ac_cv_c_clip_type="negative" + ;; + "11") + ac_cv_c_clip_type="both" + ;; + esac + ]] + +) +] + +)# AC_C_CLIP_MODE + + diff --git a/M4/endian.m4 b/M4/endian.m4 new file mode 100644 index 00000000..df91ecc3 --- /dev/null +++ b/M4/endian.m4 @@ -0,0 +1,159 @@ +dnl @synopsis AC_C_FIND_ENDIAN +dnl +dnl Determine endian-ness of target processor. +dnl @version 1.1 Mar 03 2002 +dnl @author Erik de Castro Lopo +dnl +dnl Majority written from scratch to replace the standard autoconf macro +dnl AC_C_BIGENDIAN. Only part remaining from the original it the invocation +dnl of the AC_TRY_RUN macro. +dnl +dnl Permission to use, copy, modify, distribute, and sell this file for any +dnl purpose is hereby granted without fee, provided that the above copyright +dnl and this permission notice appear in all copies. No representations are +dnl made about the suitability of this software for any purpose. It is +dnl provided "as is" without express or implied warranty. + +dnl Find endian-ness in the following way: +dnl 1) Look in . +dnl 2) If 1) fails, look in and . +dnl 3) If 1) and 2) fails and not cross compiling run a test program. +dnl 4) If 1) and 2) fails and cross compiling then guess based on target. + +AC_DEFUN([AC_C_FIND_ENDIAN], +[AC_CACHE_CHECK(processor byte ordering, + ac_cv_c_byte_order, + +# Initialize to unknown +ac_cv_c_byte_order=unknown + +if test x$ac_cv_header_endian_h = xyes ; then + + # First try which should set BYTE_ORDER. + + [AC_TRY_LINK([ + #include + #if BYTE_ORDER != LITTLE_ENDIAN + not big endian + #endif + ], return 0 ;, + ac_cv_c_byte_order=little + )] + + [AC_TRY_LINK([ + #include + #if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + ], return 0 ;, + ac_cv_c_byte_order=big + )] + + fi + +if test $ac_cv_c_byte_order = unknown ; then + + [AC_TRY_LINK([ + #include + #include + #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros + #endif + ], return 0 ;, + + [AC_TRY_LINK([ + #include + #include + #if BYTE_ORDER != LITTLE_ENDIAN + not big endian + #endif + ], return 0 ;, + ac_cv_c_byte_order=little + )] + + [AC_TRY_LINK([ + #include + #include + #if BYTE_ORDER != LITTLE_ENDIAN + not big endian + #endif + ], return 0 ;, + ac_cv_c_byte_order=little + )] + + )] + + fi + +if test $ac_cv_c_byte_order = unknown ; then + if test $cross_compiling = yes ; then + # This is the last resort. Try to guess the target processor endian-ness + # by looking at the target CPU type. + [ + case "$target_cpu" in + alpha* | i?86* | mipsel* | ia64*) + ac_cv_c_big_endian=0 + ac_cv_c_little_endian=1 + ;; + + m68* | mips* | powerpc* | hppa* | sparc*) + ac_cv_c_big_endian=1 + ac_cv_c_little_endian=0 + ;; + + esac + ] + else + AC_TRY_RUN( + [[ + int main (void) + { /* Are we little or big endian? From Harbison&Steele. */ + union + { long l ; + char c [sizeof (long)] ; + } u ; + u.l = 1 ; + return (u.c [sizeof (long) - 1] == 1); + } + ]], , ac_cv_c_byte_order=big, + ac_cv_c_byte_order=unknown + ) + + AC_TRY_RUN( + [[int main (void) + { /* Are we little or big endian? From Harbison&Steele. */ + union + { long l ; + char c [sizeof (long)] ; + } u ; + u.l = 1 ; + return (u.c [0] == 1); + }]], , ac_cv_c_byte_order=little, + ac_cv_c_byte_order=unknown + ) + fi + fi + +) +] + +if test $ac_cv_c_byte_order = big ; then + ac_cv_c_big_endian=1 + ac_cv_c_little_endian=0 +elif test $ac_cv_c_byte_order = little ; then + ac_cv_c_big_endian=0 + ac_cv_c_little_endian=1 +else + ac_cv_c_big_endian=0 + ac_cv_c_little_endian=0 + + AC_MSG_WARN([[*****************************************************************]]) + AC_MSG_WARN([[*** Not able to determine endian-ness of target processor. ]]) + AC_MSG_WARN([[*** The constants CPU_IS_BIG_ENDIAN and CPU_IS_LITTLE_ENDIAN in ]]) + AC_MSG_WARN([[*** src/config.h may need to be hand editied. ]]) + AC_MSG_WARN([[*****************************************************************]]) + fi + +)# AC_C_FIND_ENDIAN + + diff --git a/M4/extra_largefile.m4 b/M4/extra_largefile.m4 new file mode 100644 index 00000000..47401f85 --- /dev/null +++ b/M4/extra_largefile.m4 @@ -0,0 +1,114 @@ +dnl By default, many hosts won't let programs access large files; +dnl one must use special compiler options to get large-file access to work. +dnl For more details about this brain damage please see: +dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html + +dnl Written by Paul Eggert . + +dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE. +dnl AC_SYS_EXTRA_LARGEFILE_FLAGS(FLAGSNAME) +AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_FLAGS], + [AC_CACHE_CHECK([for $1 value to request large file support], + ac_cv_sys_largefile_$1, + [ac_cv_sys_largefile_$1=`($GETCONF LFS_$1) 2>/dev/null` || { + ac_cv_sys_largefile_$1=no + ifelse($1, CFLAGS, + [case "$host_os" in + # IRIX 6.2 and later require cc -n32. +changequote(, )dnl + irix6.[2-9]* | irix6.1[0-9]* | irix[7-9].* | irix[1-9][0-9]*) +changequote([, ])dnl + if test "$GCC" != yes; then + ac_cv_sys_largefile_CFLAGS=-n32 + fi + ac_save_CC="$CC" + CC="$CC $ac_cv_sys_largefile_CFLAGS" + AC_TRY_LINK(, , , ac_cv_sys_largefile_CFLAGS=no) + CC="$ac_save_CC" + esac]) + }])]) + +dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE. +dnl AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(VAR, VAL) +AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND], + [case $2 in + no) ;; + ?*) + case "[$]$1" in + '') $1=$2 ;; + *) $1=[$]$1' '$2 ;; + esac ;; + esac]) + +dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE. +dnl AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(C-MACRO, CACHE-VAR, COMMENT, CODE-TO-SET-DEFAULT) +AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE], + [AC_CACHE_CHECK([for $1], $2, + [$2=no +changequote(, )dnl + $4 + for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do + case "$ac_flag" in + -D$1) + $2=1 ;; + -D$1=*) + $2=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;; + esac + done +changequote([, ])dnl + ]) + if test "[$]$2" != no; then + AC_DEFINE_UNQUOTED([$1], [$]$2, [$3]) + fi]) + +AC_DEFUN([AC_SYS_EXTRA_LARGEFILE], + [AC_REQUIRE([AC_CANONICAL_HOST]) + AC_ARG_ENABLE(largefile, + [ --disable-largefile omit support for large files]) + if test "$enable_largefile" != no; then + AC_CHECK_TOOL(GETCONF, getconf) + AC_SYS_EXTRA_LARGEFILE_FLAGS(CFLAGS) + AC_SYS_EXTRA_LARGEFILE_FLAGS(LDFLAGS) + AC_SYS_EXTRA_LARGEFILE_FLAGS(LIBS) + + for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do + case "$ac_flag" in + no) ;; + -D_FILE_OFFSET_BITS=*) ;; + -D_LARGEFILE_SOURCE | -D_LARGEFILE_SOURCE=*) ;; + -D_LARGE_FILES | -D_LARGE_FILES=*) ;; + -D?* | -I?*) + AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(CPPFLAGS, "$ac_flag") ;; + *) + AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(CFLAGS, "$ac_flag") ;; + esac + done + AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(LDFLAGS, "$ac_cv_sys_largefile_LDFLAGS") + AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(LIBS, "$ac_cv_sys_largefile_LIBS") + AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, + ac_cv_sys_file_offset_bits, + [Number of bits in a file offset, on hosts where this is settable.]) + [case "$host_os" in + # HP-UX 10.20 and later + hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*) + ac_cv_sys_file_offset_bits=64 ;; + esac] + AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, + ac_cv_sys_largefile_source, + [Define to make fseeko etc. visible, on some hosts.], + [case "$host_os" in + # HP-UX 10.20 and later + hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*) + ac_cv_sys_largefile_source=1 ;; + esac]) + AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_LARGE_FILES, + ac_cv_sys_large_files, + [Define for large files, on AIX-style hosts.], + [case "$host_os" in + # AIX 4.2 and later + aix4.[2-9]* | aix4.1[0-9]* | aix[5-9].* | aix[1-9][0-9]*) + ac_cv_sys_large_files=1 ;; + esac]) + fi + ]) + diff --git a/M4/flexible_array.m4 b/M4/flexible_array.m4 new file mode 100644 index 00000000..7f558d3e --- /dev/null +++ b/M4/flexible_array.m4 @@ -0,0 +1,32 @@ +dnl @synopsis AC_C99_FLEXIBLE_ARRAY +dnl +dnl Dose the compiler support the 1999 ISO C Standard "stuct hack". +dnl @version 1.1 Mar 15 2004 +dnl @author Erik de Castro Lopo +dnl +dnl Permission to use, copy, modify, distribute, and sell this file for any +dnl purpose is hereby granted without fee, provided that the above copyright +dnl and this permission notice appear in all copies. No representations are +dnl made about the suitability of this software for any purpose. It is +dnl provided "as is" without express or implied warranty. + +AC_DEFUN([AC_C99_FLEXIBLE_ARRAY], +[AC_CACHE_CHECK(C99 struct flexible array support, + ac_cv_c99_flexible_array, + +# Initialize to unknown +ac_cv_c99_flexible_array=no + +AC_TRY_LINK([[ + #include + typedef struct { + int k; + char buffer [] ; + } MY_STRUCT ; + ]], + [ MY_STRUCT *p = calloc (1, sizeof (MY_STRUCT) + 42); ], + ac_cv_c99_flexible_array=yes, + ac_cv_c99_flexible_array=no + ))] +) # AC_C99_FLEXIBLE_ARRAY + diff --git a/M4/llrint.m4 b/M4/llrint.m4 new file mode 100644 index 00000000..0f5ce698 --- /dev/null +++ b/M4/llrint.m4 @@ -0,0 +1,38 @@ +dnl @synopsis AC_C99_FUNC_LLRINT +dnl +dnl Check whether C99's llrint function is available. +dnl @version 1.1 Sep 30 2002 +dnl @author Erik de Castro Lopo +dnl +dnl Permission to use, copy, modify, distribute, and sell this file for any +dnl purpose is hereby granted without fee, provided that the above copyright +dnl and this permission notice appear in all copies. No representations are +dnl made about the suitability of this software for any purpose. It is +dnl provided "as is" without express or implied warranty. +dnl +AC_DEFUN([AC_C99_FUNC_LLRINT], +[AC_CACHE_CHECK(for llrint, + ac_cv_c99_llrint, +[ +llrint_save_CFLAGS=$CFLAGS +CFLAGS="-lm" +AC_TRY_LINK([ +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 +#define __USE_ISOC99 1 +#define __USE_ISOC9X 1 + +#include +#include +], int64_t x ; x = llrint(3.14159) ;, ac_cv_c99_llrint=yes, ac_cv_c99_llrint=no) + +CFLAGS=$llrint_save_CFLAGS + +]) + +if test "$ac_cv_c99_llrint" = yes; then + AC_DEFINE(HAVE_LLRINT, 1, + [Define if you have C99's llrint function.]) +fi +])# AC_C99_FUNC_LLRINT + diff --git a/M4/lrint.m4 b/M4/lrint.m4 new file mode 100644 index 00000000..3e3319e1 --- /dev/null +++ b/M4/lrint.m4 @@ -0,0 +1,37 @@ +dnl @synopsis AC_C99_FUNC_LRINT +dnl +dnl Check whether C99's lrint function is available. +dnl @version 1.3 Feb 12 2002 +dnl @author Erik de Castro Lopo +dnl +dnl Permission to use, copy, modify, distribute, and sell this file for any +dnl purpose is hereby granted without fee, provided that the above copyright +dnl and this permission notice appear in all copies. No representations are +dnl made about the suitability of this software for any purpose. It is +dnl provided "as is" without express or implied warranty. +dnl +AC_DEFUN([AC_C99_FUNC_LRINT], +[AC_CACHE_CHECK(for lrint, + ac_cv_c99_lrint, +[ +lrint_save_CFLAGS=$CFLAGS +CFLAGS="-lm" +AC_TRY_LINK([ +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 +#define __USE_ISOC99 1 +#define __USE_ISOC9X 1 + +#include +], if (!lrint(3.14159)) lrint(2.7183);, ac_cv_c99_lrint=yes, ac_cv_c99_lrint=no) + +CFLAGS=$lrint_save_CFLAGS + +]) + +if test "$ac_cv_c99_lrint" = yes; then + AC_DEFINE(HAVE_LRINT, 1, + [Define if you have C99's lrint function.]) +fi +])# AC_C99_FUNC_LRINT + diff --git a/M4/lrintf.m4 b/M4/lrintf.m4 new file mode 100644 index 00000000..f921e9ed --- /dev/null +++ b/M4/lrintf.m4 @@ -0,0 +1,37 @@ +dnl @synopsis AC_C99_FUNC_LRINTF +dnl +dnl Check whether C99's lrintf function is available. +dnl @version 1.3 Feb 12 2002 +dnl @author Erik de Castro Lopo +dnl +dnl Permission to use, copy, modify, distribute, and sell this file for any +dnl purpose is hereby granted without fee, provided that the above copyright +dnl and this permission notice appear in all copies. No representations are +dnl made about the suitability of this software for any purpose. It is +dnl provided "as is" without express or implied warranty. +dnl +AC_DEFUN([AC_C99_FUNC_LRINTF], +[AC_CACHE_CHECK(for lrintf, + ac_cv_c99_lrintf, +[ +lrintf_save_CFLAGS=$CFLAGS +CFLAGS="-lm" +AC_TRY_LINK([ +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 +#define __USE_ISOC99 1 +#define __USE_ISOC9X 1 + +#include +], if (!lrintf(3.14159)) lrintf(2.7183);, ac_cv_c99_lrintf=yes, ac_cv_c99_lrintf=no) + +CFLAGS=$lrintf_save_CFLAGS + +]) + +if test "$ac_cv_c99_lrintf" = yes; then + AC_DEFINE(HAVE_LRINTF, 1, + [Define if you have C99's lrintf function.]) +fi +])# AC_C99_FUNC_LRINTF + diff --git a/M4/mkoctfile_version.m4 b/M4/mkoctfile_version.m4 new file mode 100644 index 00000000..4fdfd63d --- /dev/null +++ b/M4/mkoctfile_version.m4 @@ -0,0 +1,37 @@ +dnl @synopsis AC_MKOCTFILE_VERSION +dnl +dnl Find the version of mkoctfile. +dnl @version 1.0 Aug 23 2007 +dnl @author Erik de Castro Lopo +dnl +dnl Permission to use, copy, modify, distribute, and sell this file for any +dnl purpose is hereby granted without fee, provided that the above copyright +dnl and this permission notice appear in all copies. No representations are +dnl made about the suitability of this software for any purpose. It is +dnl provided "as is" without express or implied warranty. +dnl + +AC_DEFUN([AC_MKOCTFILE_VERSION], +[ + + +AC_ARG_WITH(mkoctfile, + [ --with-mkoctfile choose the mkoctfile version], [ with_mkoctfile=$withval ]) + +test -z "$with_mkoctfile" && with_mkoctfile=mkoctfile + +AC_CHECK_PROG(HAVE_MKOCTFILE,$with_mkoctfile,yes,no) + +if test "x$ac_cv_prog_HAVE_MKOCTFILE" = "xyes" ; then + MKOCTFILE=$with_mkoctfile + + AC_MSG_CHECKING([for version of $MKOCTFILE]) + MKOCTFILE_VERSION=`$with_mkoctfile --version 2>&1 | sed 's/mkoctfile, version //g'` + AC_MSG_RESULT($MKOCTFILE_VERSION) + fi + +AC_SUBST(MKOCTFILE) +AC_SUBST(MKOCTFILE_VERSION) + +])# AC_MKOCTFILE_VERSION + diff --git a/M4/octave.m4 b/M4/octave.m4 new file mode 100644 index 00000000..f889723c --- /dev/null +++ b/M4/octave.m4 @@ -0,0 +1,156 @@ +dnl Evaluate an expression in octave +dnl +dnl OCTAVE_EVAL(expr,var) -> var=expr +dnl +dnl Stolen from octave-forge + +AC_DEFUN([OCTAVE_EVAL], +[ +AC_MSG_CHECKING([for $1 in $OCTAVE]) +$2=`echo "disp($1)" | $OCTAVE -qfH` +AC_MSG_RESULT($$2) +AC_SUBST($2) +]) # OCTAVE_EVAL + +dnl @synopsis AC_OCTAVE_VERSION +dnl +dnl Find the version of Octave. +dnl @version 1.0 Aug 23 2007 +dnl @author Erik de Castro Lopo +dnl +dnl Permission to use, copy, modify, distribute, and sell this file for any +dnl purpose is hereby granted without fee, provided that the above copyright +dnl and this permission notice appear in all copies. No representations are +dnl made about the suitability of this software for any purpose. It is +dnl provided "as is" without express or implied warranty. +dnl + +AC_DEFUN([AC_OCTAVE_VERSION], +[ + +AC_ARG_WITH(octave, + [ --with-octave choose the octave version], [ with_octave=$withval ]) + +test -z "$with_octave" && with_octave=octave + +AC_CHECK_PROG(HAVE_OCTAVE,$with_octave,yes,no) + +if test "x$ac_cv_prog_HAVE_OCTAVE" = "xyes" ; then + OCTAVE=$with_octave + OCTAVE_EVAL(OCTAVE_VERSION,OCTAVE_VERSION) + fi + +AC_SUBST(OCTAVE) +AC_SUBST(OCTAVE_VERSION) + +])# AC_OCTAVE_VERSION + +dnl @synopsis AC_OCTAVE_CONFIG_VERSION +dnl +dnl Find the version of Octave. +dnl @version 1.0 Aug 23 2007 +dnl @author Erik de Castro Lopo +dnl +dnl Permission to use, copy, modify, distribute, and sell this file for any +dnl purpose is hereby granted without fee, provided that the above copyright +dnl and this permission notice appear in all copies. No representations are +dnl made about the suitability of this software for any purpose. It is +dnl provided "as is" without express or implied warranty. +dnl + +AC_DEFUN([AC_OCTAVE_CONFIG_VERSION], +[ + +AC_ARG_WITH(octave-config, + [ --with-octave-config choose the octave-config version], [ with_octave_config=$withval ]) + +test -z "$with_octave_config" && with_octave_config=octave-config + +AC_CHECK_PROG(HAVE_OCTAVE_CONFIG,$with_octave_config,yes,no) + +if test "x$ac_cv_prog_HAVE_OCTAVE_CONFIG" = "xyes" ; then + OCTAVE_CONFIG=$with_octave_config + AC_MSG_CHECKING([for version of $OCTAVE_CONFIG]) + OCTAVE_CONFIG_VERSION=`$OCTAVE_CONFIG --version` + AC_MSG_RESULT($OCTAVE_CONFIG_VERSION) + fi + +AC_SUBST(OCTAVE_CONFIG) +AC_SUBST(OCTAVE_CONFIG_VERSION) + +])# AC_OCTAVE_CONFIG_VERSION + +dnl @synopsis AC_OCTAVE_BUILD +dnl +dnl Check programs and headers required for building octave plugins. +dnl @version 1.0 Aug 23 2007 +dnl @author Erik de Castro Lopo +dnl +dnl Permission to use, copy, modify, distribute, and sell this file for any +dnl purpose is hereby granted without fee, provided that the above copyright +dnl and this permission notice appear in all copies. No representations are +dnl made about the suitability of this software for any purpose. It is +dnl provided "as is" without express or implied warranty. + + +AC_DEFUN([AC_OCTAVE_BUILD], +[ + +dnl Default to no. +OCTAVE_BUILD=no + +AC_OCTAVE_VERSION +AC_MKOCTFILE_VERSION +AC_OCTAVE_CONFIG_VERSION + +prog_concat="$ac_cv_prog_HAVE_OCTAVE$ac_cv_prog_HAVE_OCTAVE_CONFIG$ac_cv_prog_HAVE_MKOCTFILE" + +if test "x$prog_concat" = "xyesyesyes" ; then + if test "x$OCTAVE_VERSION" != "x$MKOCTFILE_VERSION" ; then + AC_MSG_WARN([** Mismatch between versions of octave and mkoctfile. **]) + AC_MSG_WARN([** Octave libsndfile modules will not be built. **]) + elif test "x$OCTAVE_VERSION" != "x$OCTAVE_CONFIG_VERSION" ; then + AC_MSG_WARN([** Mismatch between versions of octave and octave-config. **]) + AC_MSG_WARN([** Octave libsndfile modules will not be built. **]) + else + OCTAVE_DEST_ODIR=`$OCTAVE_CONFIG --oct-site-dir | sed 's%^/usr%${prefix}%'` + OCTAVE_DEST_MDIR=`$OCTAVE_CONFIG --m-site-dir | sed 's%^/usr%${prefix}%'` + + AC_MSG_RESULT([retrieving compile and link flags from $MKOCTFILE]) + + OCT_CXXFLAGS=`$MKOCTFILE -p ALL_CXXFLAGS` + OCT_CXXFLAGS="$OCT_CXXFLAGS `$MKOCTFILE -p FPICFLAG`" + OCT_LIB_DIR=`$MKOCTFILE -p LFLAGS` + + dnl Pinched from mkoctfile. + dnl + dnl LINK_DEPS="$LFLAGS $OCTAVE_LIBS $LDFLAGS $BLAS_LIBS $FFTW_LIBS $LIBS $FLIBS" + dnl cmd="$DL_LD $DL_LDFLAGS $pass_on_options -o $octfile $objfiles $ldflags $LINK_DEPS" + + + OCT_LIBS=`$MKOCTFILE -p LFLAGS` + OCT_LIBS="$OCT_LIBS `$MKOCTFILE -p OCTAVE_LIBS`" + OCT_LIBS="$OCT_LIBS `$MKOCTFILE -p LDFLAGS`" + OCT_LIBS="$OCT_LIBS `$MKOCTFILE -p BLAS_LIBS`" + OCT_LIBS="$OCT_LIBS `$MKOCTFILE -p FFTW_LIBS`" + OCT_LIBS="$OCT_LIBS `$MKOCTFILE -p LIBS`" + OCT_LIBS="$OCT_LIBS `$MKOCTFILE -p FLIBS`" + + OCT_LIBS="`$MKOCTFILE -p DL_LDFLAGS` $OCT_LIBS" + + OCTAVE_BUILD=yes + AC_MSG_RESULT([building octave libsndfile module... $OCTAVE_BUILD]) + fi + fi + + +AC_SUBST(OCTAVE_DEST_ODIR) +AC_SUBST(OCTAVE_DEST_MDIR) + +AC_SUBST(OCT_CXXFLAGS) +AC_SUBST(OCT_LIB_DIR) +AC_SUBST(OCT_LIBS) + +AM_CONDITIONAL(BUILD_OCTAVE_MOD, test -n "$OCT_CXXFLAGS") + +])# AC_OCTAVE_BUILD diff --git a/Makefile.am b/Makefile.am index bae93e10..ec03728f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,11 +1,14 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = man doc Win32 Octave src examples regtest tests -DIST_SUBDIRS = $(SUBDIRS) -EXTRA_DIST = reconfigure.mk acinclude.m4 libsndfile.spec.in \ - sndfile.pc.in Mingw-make-dist.sh - - +if BUILD_OCTAVE_MOD +octave_dir = Octave +endif + +SUBDIRS = M4 man doc Win32 src $(octave_dir) examples regtest tests +DIST_SUBDIRS = M4 man doc Win32 src Octave examples regtest tests +EXTRA_DIST = libsndfile.spec.in sndfile.pc.in Mingw-make-dist.sh + + pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = sndfile.pc @@ -19,9 +22,3 @@ genfiles : (cd tests ; make genfiles) -## Do not edit or modify anything in this comment block. -## The arch-tag line is a file identity tag for the GNU Arch -## revision control system. -## -## arch-tag: e40c569e-8020-4e95-b774-6b0703614526 - diff --git a/Octave/Makefile.am b/Octave/Makefile.am index 146cd29c..7e84c6ac 100644 --- a/Octave/Makefile.am +++ b/Octave/Makefile.am @@ -1,14 +1,79 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = sndfile_load.m sndfile_save.m sndfile_play.m +# Prevent any extension. +EXEEXT = + +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + +EXTRA_DIST = sndfile_load.m sndfile_save.m sndfile_play.m \ + octave_test.m octave_test.sh $(oct_module_srcs) octconfigdir = $(exec_prefix)/share/octave/site/m octconfig_DATA = sndfile_load.m sndfile_save.m sndfile_play.m - -## Do not edit or modify anything in this comment block. -## The arch-tag line is a file identity tag for the GNU Arch -## revision control system. -## -## arch-tag: 56f1645a-3a13-4846-acc7-8b4abf2904ff +OCTAVE_DEST_MDIR = @OCTAVE_DEST_MDIR@ +OCTAVE_DEST_ODIR = @OCTAVE_DEST_ODIR@ +OCT_CXXFLAGS = @OCT_CXXFLAGS@ +OCT_LIB_DIR = @OCT_LIB_DIR@ +OCT_LIBS = @OCT_LIBS@ + +SNDFILEDIR = $(top_builddir)/src +INCLUDES = -I$(SNDFILEDIR) + +oct_module_srcs = sfread.cc sfwrite.cc format.cc +oct_modules = sfread.oct sfwrite.oct + +# Make these noinst so they can be installed manually. +noinst_DATA = $(oct_modules) + +noinst_HEADERS = format.h + + +# Need to jump through extra hoops here because we only these Octave +# modules must be dynamic. However, to make the tests pass, they need +# to be statically linked to the libsndfile that has just been built. +# +# Maybe should create both dynamic and static versions and install +# the dynamic and test the static. +sfread.oct : format.cc sfread.cc + $(CXXLINK) $(OCT_CXXFLAGS) $(INCLUDES) $+ $(OCT_LIB_DIR) $(OCT_LIBS) $(SNDFILEDIR)/libsndfile.la + +sfwrite.oct : format.cc sfwrite.cc + $(CXXLINK) $(OCT_CXXFLAGS) $(INCLUDES) $+ $(OCT_LIB_DIR) $(OCT_LIBS) $(SNDFILEDIR)/libsndfile.la + + +# Allow for the test being run in the build dir, but the test script +# being located in the source dir. +check : + octave_src_dir=$(srcdir) $(srcdir)/octave_test.sh + + +# Since the octave modules are installed in a special location, a custom install +# and uninstall routine must be specified. +install-exec-local : $(oct_modules) + @$(NORMAL_INSTALL) + test -z "$(OCTAVE_DEST_ODIR)" || $(mkdir_p) "$(DESTDIR)$(OCTAVE_DEST_ODIR)" + @list='$(oct_modules)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(INSTALL) '$$p' '$(DESTDIR)$(OCTAVE_DEST_ODIR)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(INSTALL) "$$p" "$(DESTDIR)$(OCTAVE_DEST_ODIR)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-local : + @$(NORMAL_UNINSTALL) + @list='$(oct_modules)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(OCTAVE_DEST_ODIR)/$$f'"; \ + rm -f "$(DESTDIR)$(OCTAVE_DEST_ODIR)/$$f"; \ + done + +clean-local : + rm -f $(oct_modules) diff --git a/Octave/Readme.txt b/Octave/Readme.txt new file mode 100644 index 00000000..363c1c8f --- /dev/null +++ b/Octave/Readme.txt @@ -0,0 +1,23 @@ +The libsndfile Modules for GNU Octave +===================================== + +These modules are currently known to work with version 2.9 of GNU Octave on +Linux. They have not been tested elsewhere. + + +Build Requirements +------------------ + +In order to build these libsndfile related modules for GNU Octave on a Debian +GNU/Linux (or Debian derived) system, you will need (on top of what is normally +required to build libsndfile) the package: + + octaveX.Y-headers + +where X.Y matches the version number of your installation of GNU Octave. + +The configure script in the top level libsndfile directory will detect the +presence and correct versions of the Octave build tools. The building of these +modules will only go ahead if everything is correct. + + diff --git a/Octave/format.cc b/Octave/format.cc new file mode 100644 index 00000000..e4ef4e47 --- /dev/null +++ b/Octave/format.cc @@ -0,0 +1,214 @@ +/* +** Copyright (C) 2007 Erik de Castro Lopo +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU Lesser General Public License as published by +** the Free Software Foundation; either version 2.1 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU Lesser General Public License for more details. +** +** You should have received a copy of the GNU Lesser General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include + +#include "sndfile.h" + +#include "format.h" + +static void +str_split (const std::string & str, const std::string & delim, std::vector & output) +{ + unsigned int offset = 0 ; + size_t delim_index = 0 ; + + delim_index = str.find (delim, offset) ; + + while (delim_index != std::string::npos) + { + output.push_back (str.substr(offset, delim_index - offset)) ; + offset += delim_index - offset + delim.length () ; + delim_index = str.find (delim, offset) ; + } + + output.push_back (str.substr (offset)) ; +} /* str_split */ + +static int +hash_of_str (const std::string & str) +{ + int hash = 0 ; + + for (unsigned k = 0 ; k < str.length () ; k++) + hash = (hash * 3) + tolower (str [k]) ; + + return hash ; +} /* hash_of_str */ + +static int +major_format_of_hash (const std::string & str) +{ int hash ; + + hash = hash_of_str (str) ; + + switch (hash) + { + case 0x5c8 : /* 'wav' */ return SF_FORMAT_WAV ; + case 0xf84 : /* 'aiff' */ return SF_FORMAT_AIFF ; + case 0x198 : /* 'au' */ return SF_FORMAT_AU ; + case 0x579 : /* 'paf' */ return SF_FORMAT_PAF ; + case 0x5e5 : /* 'svx' */ return SF_FORMAT_SVX ; + case 0x1118 : /* 'nist' */ return SF_FORMAT_NIST ; + case 0x5d6 : /* 'voc' */ return SF_FORMAT_VOC ; + case 0x324a : /* 'ircam' */ return SF_FORMAT_IRCAM ; + case 0x505 : /* 'w64' */ return SF_FORMAT_W64 ; + case 0x1078 : /* 'mat4' */ return SF_FORMAT_MAT4 ; + case 0x1079 : /* 'mat5' */ return SF_FORMAT_MAT5 ; + case 0x5b8 : /* 'pvf' */ return SF_FORMAT_PVF ; + case 0x1d1 : /* 'xi' */ return SF_FORMAT_XI ; + case 0x56f : /* 'htk' */ return SF_FORMAT_HTK ; + case 0x5aa : /* 'sds' */ return SF_FORMAT_SDS ; + case 0x53d : /* 'avr' */ return SF_FORMAT_AVR ; + case 0x11d0 : /* 'wavx' */ return SF_FORMAT_WAVEX ; + case 0x569 : /* 'sd2' */ return SF_FORMAT_SD2 ; + case 0x1014 : /* 'flac' */ return SF_FORMAT_FLAC ; + case 0x504 : /* 'caf' */ return SF_FORMAT_CAF ; + case 0x5f6 : /* 'wve' */ return SF_FORMAT_WVE ; + default : break ; + } ; + + printf ("%s : hash '%s' -> 0x%x\n", __func__, str.c_str (), hash) ; + + return 0 ; +} /* major_format_of_hash */ + +static int +minor_format_of_hash (const std::string & str) +{ int hash ; + + hash = hash_of_str (str) ; + + switch (hash) + { + case 0x1085 : /* 'int8' */ return SF_FORMAT_PCM_S8 ; + case 0x358a : /* 'uint8' */ return SF_FORMAT_PCM_U8 ; + case 0x31b0 : /* 'int16' */ return SF_FORMAT_PCM_16 ; + case 0x31b1 : /* 'int24' */ return SF_FORMAT_PCM_24 ; + case 0x31b2 : /* 'int32' */ return SF_FORMAT_PCM_32 ; + case 0x3128 : /* 'float' */ return SF_FORMAT_FLOAT ; + case 0x937d : /* 'double' */ return SF_FORMAT_DOUBLE ; + case 0x11bd : /* 'ulaw' */ return SF_FORMAT_ULAW ; + case 0xfa1 : /* 'alaw' */ return SF_FORMAT_ALAW ; + case 0xfc361 : /* 'ima_adpcm' */ return SF_FORMAT_IMA_ADPCM ; + case 0x5739a : /* 'ms_adpcm' */ return SF_FORMAT_MS_ADPCM ; + case 0x9450 : /* 'gsm610' */ return SF_FORMAT_GSM610 ; + case 0x172a3 : /* 'g721_32' */ return SF_FORMAT_G721_32 ; + case 0x172d8 : /* 'g723_24' */ return SF_FORMAT_G723_24 ; + case 0x172da : /* 'g723_40' */ return SF_FORMAT_G723_40 ; + default : break ; + } ; + + printf ("%s : hash '%s' -> 0x%x\n", __func__, str.c_str (), hash) ; + + return 0 ; +} /* minor_format_of_hash */ + + +int +format_of_str (const std::string & fmt) +{ + std::vector split ; + + str_split (fmt, "-", split) ; + + if (split.size () != 2) + return 0 ; + + int major_fmt = major_format_of_hash (split.at (0)) ; + if (major_fmt == 0) + return 0 ; + + int minor_fmt = minor_format_of_hash (split.at (1)) ; + if (minor_fmt == 0) + return 0 ; + + return major_fmt | minor_fmt ; +} /* format_of_str */ + +static const char * +string_of_major_format (int format) +{ + switch (format & SF_FORMAT_TYPEMASK) + { + case SF_FORMAT_WAV : return "wav" ; + case SF_FORMAT_AIFF : return "aiff" ; + case SF_FORMAT_AU : return "au" ; + case SF_FORMAT_PAF : return "paf" ; + case SF_FORMAT_SVX : return "svx" ; + case SF_FORMAT_NIST : return "nist" ; + case SF_FORMAT_VOC : return "voc" ; + case SF_FORMAT_IRCAM : return "ircam" ; + case SF_FORMAT_W64 : return "w64" ; + case SF_FORMAT_MAT4 : return "mat4" ; + case SF_FORMAT_MAT5 : return "mat5" ; + case SF_FORMAT_PVF : return "pvf" ; + case SF_FORMAT_XI : return "xi" ; + case SF_FORMAT_HTK : return "htk" ; + case SF_FORMAT_SDS : return "sds" ; + case SF_FORMAT_AVR : return "avr" ; + case SF_FORMAT_WAVEX : return "wavx" ; + case SF_FORMAT_SD2 : return "sd2" ; + case SF_FORMAT_FLAC : return "flac" ; + case SF_FORMAT_CAF : return "caf" ; + case SF_FORMAT_WVE : return "wfe" ; + default : break ; + } ; + + return "unknown" ; +} /* string_of_major_format */ + +static const char * +string_of_minor_format (int format) +{ + switch (format & SF_FORMAT_SUBMASK) + { + case SF_FORMAT_PCM_S8 : return "int8" ; + case SF_FORMAT_PCM_U8 : return "uint8" ; + case SF_FORMAT_PCM_16 : return "int16" ; + case SF_FORMAT_PCM_24 : return "int24" ; + case SF_FORMAT_PCM_32 : return "int32" ; + case SF_FORMAT_FLOAT : return "float" ; + case SF_FORMAT_DOUBLE : return "double" ; + case SF_FORMAT_ULAW : return "ulaw" ; + case SF_FORMAT_ALAW : return "alaw" ; + case SF_FORMAT_IMA_ADPCM : return "ima_adpcm" ; + case SF_FORMAT_MS_ADPCM : return "ms_adpcm" ; + case SF_FORMAT_GSM610 : return "gsm610" ; + case SF_FORMAT_G721_32 : return "g721_32" ; + case SF_FORMAT_G723_24 : return "g723_24" ; + case SF_FORMAT_G723_40 : return "g723_40" ; + default : break ; + } ; + + return "unknown" ; +} /* string_of_minor_format */ + +void +string_of_format (std::string & fmt, int format) +{ + char buffer [64] ; + + snprintf (buffer, sizeof (buffer), "%s-%s", string_of_major_format (format), string_of_minor_format (format)) ; + + fmt = buffer ; + + return ; +} /* string_of_format */ diff --git a/Octave/format.h b/Octave/format.h new file mode 100644 index 00000000..18843cee --- /dev/null +++ b/Octave/format.h @@ -0,0 +1,21 @@ +/* +** Copyright (C) 2007 Erik de Castro Lopo +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU Lesser General Public License as published by +** the Free Software Foundation; either version 2.1 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU Lesser General Public License for more details. +** +** You should have received a copy of the GNU Lesser General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +int format_of_str (const std::string & fmt) ; + +void string_of_format (std::string & fmt, int format) ; diff --git a/Octave/octave_test.m b/Octave/octave_test.m new file mode 100644 index 00000000..30b60139 --- /dev/null +++ b/Octave/octave_test.m @@ -0,0 +1,56 @@ +# Copyright (C) 2007 Erik de Castro Lopo +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# These tests are nowhere near comprehensive. + +printf ("\n\n\n\n\n\n\n") ; + +printf (" Running Octave tests : ") ; +fflush (stdout) ; + +filename = "whatever" ; +srate_out = 32000 ; +fmt_out = "wav-float" ; + +t = (2 * pi / srate_out * (0:srate_out-1))' ; +data_out = sin (440.0 * t) ; + +# Write out a file. +sfwrite (filename, data_out, srate_out, fmt_out) ; + +# Read it back in again. +[ data_in, srate_in, fmt_in ] = sfread (filename) ; + +if (srate_in != srate_out) + error ("\n\nSample rate mismatch : %d -> %d.\n\n", srate_out, srate_in) ; + endif + +# Octave strcmp return 1 for the same. +if (strcmp (fmt_in, fmt_out) != 1) + error ("\n\nFormat error : '%s' -> '%s'.\n\n", fmt_out, fmt_in) ; + endif + +err = max (abs (data_out - data_in)) ; + +if (err > 1e-7) + error ("err : %g\n", err) ; + endif + +printf ("ok") ; + +printf ("\n\n\n\n\n\n\n") ; + +unlink (filename) ; diff --git a/Octave/octave_test.sh b/Octave/octave_test.sh new file mode 100755 index 00000000..419b5969 --- /dev/null +++ b/Octave/octave_test.sh @@ -0,0 +1,63 @@ +#!/bin/bash + + +# Check where we're being run from. +if [ -d Octave ]; then + cd Octave + fi + +# Find libsndfile shared object. +libsndfile_lib_location="" + +if [ -f "../src/.libs/libsndfile.so" ]; then + libsndfile_lib_location="../src/.libs/" +elif [ -f "../src/libsndfile.so" ]; then + libsndfile_lib_location="../src/" +elif [ -f "../src/.libs/libsndfile.dylib" ]; then + libsndfile_lib_location="../src/.libs/" +elif [ -f "../src/libsndfile.dylib" ]; then + libsndfile_lib_location="../src/" +else + echo "Not able to find the libsndfile shared lib we've just built." + exit 1 + fi +libsndfile_lib_location=`(cd $libsndfile_lib_location && pwd)` + + +# Find sfread.oct and sfwrite.oct +sfread_write_oct_location="" + +if [ -f .libs/sfread.oct ]; then + sfread_write_oct_location=".libs" +elif [ -f sfread.oct ]; then + sfread_write_oct_location="." +else + echo "Not able to find the sfread.oct/sfwrite.oct binaries we've just built." + exit 1 + fi + +case `file -b $sfread_write_oct_location/sfread.oct` in + ELF*) + ;; + Mach*) + echo "Tests don't work on this platform." + exit 0 + ;; + *) + echo "Not able to find the sfread.oct/sfwrite.oct binaries we've just built." + exit 1 + ;; + esac + +# echo "libsndfile_lib_location : $libsndfile_lib_location" +# echo "sfread_write_oct_location : $sfread_write_oct_location" + +LD_LIBRARY_PATH="$libsndfile_lib_location:$LD_LIBRARY_PATH" + +octave_src_dir=`(cd $octave_src_dir && pwd)` + +octave_script="$octave_src_dir/octave_test.m" + +(cd $sfread_write_oct_location && octave -qH $octave_script) + + diff --git a/Octave/sfread.cc b/Octave/sfread.cc new file mode 100644 index 00000000..4fd17717 --- /dev/null +++ b/Octave/sfread.cc @@ -0,0 +1,103 @@ +/* +** Copyright (C) 2007 Erik de Castro Lopo +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU Lesser General Public License as published by +** the Free Software Foundation; either version 2.1 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU Lesser General Public License for more details. +** +** You should have received a copy of the GNU Lesser General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include + +#include "sndfile.h" + +#include "format.h" + +#define FOUR_GIG (0x100000000LL) +#define BUFFER_FRAMES 8192 + +DEFUN_DLD (sfread, args, nargout , "\ +-*- texinfo -*-\n\ +@deftypefn {Function File} {@var{I},@var{srate},@var{format} =} sfread (@var{filename})\n\ +Read a sound file from disk using libsndfile.\n\ +\n\ +@seealso{wavread}\n\ +@end deftypefn\n\ +") +{ SNDFILE * file ; + SF_INFO sfinfo ; + + octave_value_list retval ; + + int nargin = args.length () ; + + /* Bail out if the input parameters are bad. */ + if ((nargin != 1) || !args (0) .is_string () || nargout < 1 || nargout > 3) + { print_usage () ; + return retval ; + } ; + + memset (&sfinfo, 0, sizeof (sfinfo)) ; + + std::string filename = args (0).string_value () ; + + if ((file = sf_open (filename.c_str (), SFM_READ, &sfinfo)) == NULL) + { error ("sfread: couldn't open file %s : %s", filename.c_str (), sf_strerror (NULL)) ; + return retval ; + } ; + + if (sfinfo.frames > FOUR_GIG) + printf ("This is a really huge file (%lld frames).\nYou may run out of memory trying to load it.\n", (long long) sfinfo.frames) ; + + dim_vector dim = dim_vector () ; + dim.resize (2) ; + dim (0) = sfinfo.frames ; + dim (1) = sfinfo.channels ; + + /* Should I be using Matrix instead? */ + NDArray out (dim, 0.0) ; + + float buffer [BUFFER_FRAMES * sfinfo.channels] ; + int readcount ; + sf_count_t total = 0 ; + + do + { readcount = sf_readf_float (file, buffer, BUFFER_FRAMES) ; + + /* Make sure we don't read more frames than we allocated. */ + if (total + readcount > sfinfo.frames) + readcount = sfinfo.frames - total ; + + for (int ch = 0 ; ch < sfinfo.channels ; ch++) + { for (int k = 0 ; k < readcount ; k++) + out (total + k, ch) = buffer [k * sfinfo.channels + ch] ; + } ; + + total += readcount ; + } while (readcount > 0 && total < sfinfo.frames) ; + + retval.append (out.squeeze ()) ; + + if (nargout >= 2) + retval.append ((octave_uint32) sfinfo.samplerate) ; + + if (nargout >= 3) + { std::string fmt ("") ; + string_of_format (fmt, sfinfo.format) ; + retval.append (fmt) ; + } ; + + /* Clean up. */ + sf_close (file) ; + + return retval ; +} /* sfread */ diff --git a/Octave/sfwrite.cc b/Octave/sfwrite.cc new file mode 100644 index 00000000..e6b04404 --- /dev/null +++ b/Octave/sfwrite.cc @@ -0,0 +1,112 @@ +/* +** Copyright (C) 2007 Erik de Castro Lopo +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU Lesser General Public License as published by +** the Free Software Foundation; either version 2.1 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU Lesser General Public License for more details. +** +** You should have received a copy of the GNU Lesser General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include + +#include "sndfile.h" + +#include "format.h" + +#define FOUR_GIG (0x100000000LL) +#define BUFFER_FRAMES 8192 + +DEFUN_DLD (sfwrite, args, nargout , "\ +-*- texinfo -*-\n\ +@deftypefn {Function File} sfwrite (@var{filename},@var{data},@var{srate},@var{format})\n\ +Write a sound file to disk using libsndfile.\n\ +\n\ +@seealso{wavwrite}\n\ +@end deftypefn\n\ +") +{ SNDFILE * file ; + SF_INFO sfinfo ; + + octave_value_list retval ; + + int nargin = args.length () ; + + /* Bail out if the input parameters are bad. */ + if (nargin != 4 || !args (0).is_string () || !args (1).is_real_matrix () + || !args (2).is_real_scalar () || !args (3).is_string () + || nargout != 0) + { print_usage () ; + return retval ; + } ; + + std::string filename = args (0).string_value () ; + std::string format = args (3).string_value () ; + + memset (&sfinfo, 0, sizeof (sfinfo)) ; + + sfinfo.format = format_of_str (format) ; + if (sfinfo.format == 0) + { error ("Bad format '%s'", format.c_str ()) ; + return retval ; + } ; + + sfinfo.samplerate = lrint (args (2).scalar_value ()) ; + if (sfinfo.samplerate < 1) + { error ("Bad sample rate : %d.\n", sfinfo.samplerate) ; + return retval ; + } ; + + Matrix data = args (1).matrix_value () ; + long rows = args (1).rows () ; + long cols = args (1).columns () ; + + if (cols > rows) + { error ("Audio data should have one column per channel, but supplied data " + "has %ld rows and %ld columns.\n", rows, cols) ; + return retval ; + } ; + + sfinfo.channels = cols ; + + if ((file = sf_open (filename.c_str (), SFM_WRITE, &sfinfo)) == NULL) + { error ("Couldn't open file %s : %s", filename.c_str (), sf_strerror (NULL)) ; + return retval ; + } ; + + float buffer [BUFFER_FRAMES * sfinfo.channels] ; + int writecount ; + long total = 0 ; + + do + { + writecount = BUFFER_FRAMES ; + + /* Make sure we don't read more frames than we allocated. */ + if (total + writecount > rows) + writecount = rows - total ; + + for (int ch = 0 ; ch < sfinfo.channels ; ch++) + { for (int k = 0 ; k < writecount ; k++) + buffer [k * sfinfo.channels + ch] = data (total + k, ch) ; + } ; + + if (writecount > 0) + sf_writef_float (file, buffer, writecount) ; + + total += writecount ; + } while (writecount > 0 && total < rows) ; + + /* Clean up. */ + sf_close (file) ; + + return retval ; +} /* sfwrite */ diff --git a/acinclude.m4 b/acinclude.m4 deleted file mode 100644 index 33d91294..00000000 --- a/acinclude.m4 +++ /dev/null @@ -1,569 +0,0 @@ -dnl By default, many hosts won't let programs access large files; -dnl one must use special compiler options to get large-file access to work. -dnl For more details about this brain damage please see: -dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html - -dnl Written by Paul Eggert . - -dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE. -dnl AC_SYS_EXTRA_LARGEFILE_FLAGS(FLAGSNAME) -AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_FLAGS], - [AC_CACHE_CHECK([for $1 value to request large file support], - ac_cv_sys_largefile_$1, - [ac_cv_sys_largefile_$1=`($GETCONF LFS_$1) 2>/dev/null` || { - ac_cv_sys_largefile_$1=no - ifelse($1, CFLAGS, - [case "$host_os" in - # IRIX 6.2 and later require cc -n32. -changequote(, )dnl - irix6.[2-9]* | irix6.1[0-9]* | irix[7-9].* | irix[1-9][0-9]*) -changequote([, ])dnl - if test "$GCC" != yes; then - ac_cv_sys_largefile_CFLAGS=-n32 - fi - ac_save_CC="$CC" - CC="$CC $ac_cv_sys_largefile_CFLAGS" - AC_TRY_LINK(, , , ac_cv_sys_largefile_CFLAGS=no) - CC="$ac_save_CC" - esac]) - }])]) - -dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE. -dnl AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(VAR, VAL) -AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND], - [case $2 in - no) ;; - ?*) - case "[$]$1" in - '') $1=$2 ;; - *) $1=[$]$1' '$2 ;; - esac ;; - esac]) - -dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE. -dnl AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(C-MACRO, CACHE-VAR, COMMENT, CODE-TO-SET-DEFAULT) -AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE], - [AC_CACHE_CHECK([for $1], $2, - [$2=no -changequote(, )dnl - $4 - for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do - case "$ac_flag" in - -D$1) - $2=1 ;; - -D$1=*) - $2=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;; - esac - done -changequote([, ])dnl - ]) - if test "[$]$2" != no; then - AC_DEFINE_UNQUOTED([$1], [$]$2, [$3]) - fi]) - -AC_DEFUN([AC_SYS_EXTRA_LARGEFILE], - [AC_REQUIRE([AC_CANONICAL_HOST]) - AC_ARG_ENABLE(largefile, - [ --disable-largefile omit support for large files]) - if test "$enable_largefile" != no; then - AC_CHECK_TOOL(GETCONF, getconf) - AC_SYS_EXTRA_LARGEFILE_FLAGS(CFLAGS) - AC_SYS_EXTRA_LARGEFILE_FLAGS(LDFLAGS) - AC_SYS_EXTRA_LARGEFILE_FLAGS(LIBS) - - for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do - case "$ac_flag" in - no) ;; - -D_FILE_OFFSET_BITS=*) ;; - -D_LARGEFILE_SOURCE | -D_LARGEFILE_SOURCE=*) ;; - -D_LARGE_FILES | -D_LARGE_FILES=*) ;; - -D?* | -I?*) - AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(CPPFLAGS, "$ac_flag") ;; - *) - AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(CFLAGS, "$ac_flag") ;; - esac - done - AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(LDFLAGS, "$ac_cv_sys_largefile_LDFLAGS") - AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(LIBS, "$ac_cv_sys_largefile_LIBS") - AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, - ac_cv_sys_file_offset_bits, - [Number of bits in a file offset, on hosts where this is settable.]) - [case "$host_os" in - # HP-UX 10.20 and later - hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*) - ac_cv_sys_file_offset_bits=64 ;; - esac] - AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, - ac_cv_sys_largefile_source, - [Define to make fseeko etc. visible, on some hosts.], - [case "$host_os" in - # HP-UX 10.20 and later - hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*) - ac_cv_sys_largefile_source=1 ;; - esac]) - AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_LARGE_FILES, - ac_cv_sys_large_files, - [Define for large files, on AIX-style hosts.], - [case "$host_os" in - # AIX 4.2 and later - aix4.[2-9]* | aix4.1[0-9]* | aix[5-9].* | aix[1-9][0-9]*) - ac_cv_sys_large_files=1 ;; - esac]) - fi - ]) - - - - - - -dnl @synopsis AC_C_FIND_ENDIAN -dnl -dnl Determine endian-ness of target processor. -dnl @version 1.1 Mar 03 2002 -dnl @author Erik de Castro Lopo -dnl -dnl Majority written from scratch to replace the standard autoconf macro -dnl AC_C_BIGENDIAN. Only part remaining from the original it the invocation -dnl of the AC_TRY_RUN macro. -dnl -dnl Permission to use, copy, modify, distribute, and sell this file for any -dnl purpose is hereby granted without fee, provided that the above copyright -dnl and this permission notice appear in all copies. No representations are -dnl made about the suitability of this software for any purpose. It is -dnl provided "as is" without express or implied warranty. - -dnl Find endian-ness in the following way: -dnl 1) Look in . -dnl 2) If 1) fails, look in and . -dnl 3) If 1) and 2) fails and not cross compiling run a test program. -dnl 4) If 1) and 2) fails and cross compiling then guess based on target. - -AC_DEFUN([AC_C_FIND_ENDIAN], -[AC_CACHE_CHECK(processor byte ordering, - ac_cv_c_byte_order, - -# Initialize to unknown -ac_cv_c_byte_order=unknown - -if test x$ac_cv_header_endian_h = xyes ; then - - # First try which should set BYTE_ORDER. - - [AC_TRY_LINK([ - #include - #if BYTE_ORDER != LITTLE_ENDIAN - not big endian - #endif - ], return 0 ;, - ac_cv_c_byte_order=little - )] - - [AC_TRY_LINK([ - #include - #if BYTE_ORDER != BIG_ENDIAN - not big endian - #endif - ], return 0 ;, - ac_cv_c_byte_order=big - )] - - fi - -if test $ac_cv_c_byte_order = unknown ; then - - [AC_TRY_LINK([ - #include - #include - #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN - bogus endian macros - #endif - ], return 0 ;, - - [AC_TRY_LINK([ - #include - #include - #if BYTE_ORDER != LITTLE_ENDIAN - not big endian - #endif - ], return 0 ;, - ac_cv_c_byte_order=little - )] - - [AC_TRY_LINK([ - #include - #include - #if BYTE_ORDER != LITTLE_ENDIAN - not big endian - #endif - ], return 0 ;, - ac_cv_c_byte_order=little - )] - - )] - - fi - -if test $ac_cv_c_byte_order = unknown ; then - if test $cross_compiling = yes ; then - # This is the last resort. Try to guess the target processor endian-ness - # by looking at the target CPU type. - [ - case "$target_cpu" in - alpha* | i?86* | mipsel* | ia64*) - ac_cv_c_big_endian=0 - ac_cv_c_little_endian=1 - ;; - - m68* | mips* | powerpc* | hppa* | sparc*) - ac_cv_c_big_endian=1 - ac_cv_c_little_endian=0 - ;; - - esac - ] - else - AC_TRY_RUN( - [[ - int main (void) - { /* Are we little or big endian? From Harbison&Steele. */ - union - { long l ; - char c [sizeof (long)] ; - } u ; - u.l = 1 ; - return (u.c [sizeof (long) - 1] == 1); - } - ]], , ac_cv_c_byte_order=big, - ac_cv_c_byte_order=unknown - ) - - AC_TRY_RUN( - [[int main (void) - { /* Are we little or big endian? From Harbison&Steele. */ - union - { long l ; - char c [sizeof (long)] ; - } u ; - u.l = 1 ; - return (u.c [0] == 1); - }]], , ac_cv_c_byte_order=little, - ac_cv_c_byte_order=unknown - ) - fi - fi - -) -] - -if test $ac_cv_c_byte_order = big ; then - ac_cv_c_big_endian=1 - ac_cv_c_little_endian=0 -elif test $ac_cv_c_byte_order = little ; then - ac_cv_c_big_endian=0 - ac_cv_c_little_endian=1 -else - ac_cv_c_big_endian=0 - ac_cv_c_little_endian=0 - - AC_MSG_WARN([[*****************************************************************]]) - AC_MSG_WARN([[*** Not able to determine endian-ness of target processor. ]]) - AC_MSG_WARN([[*** The constants CPU_IS_BIG_ENDIAN and CPU_IS_LITTLE_ENDIAN in ]]) - AC_MSG_WARN([[*** src/config.h may need to be hand editied. ]]) - AC_MSG_WARN([[*****************************************************************]]) - fi - -)# AC_C_FIND_ENDIAN - - - - - -dnl @synopsis AC_C99_FLEXIBLE_ARRAY -dnl -dnl Dose the compiler support the 1999 ISO C Standard "stuct hack". -dnl @version 1.1 Mar 15 2004 -dnl @author Erik de Castro Lopo -dnl -dnl Permission to use, copy, modify, distribute, and sell this file for any -dnl purpose is hereby granted without fee, provided that the above copyright -dnl and this permission notice appear in all copies. No representations are -dnl made about the suitability of this software for any purpose. It is -dnl provided "as is" without express or implied warranty. - -AC_DEFUN([AC_C99_FLEXIBLE_ARRAY], -[AC_CACHE_CHECK(C99 struct flexible array support, - ac_cv_c99_flexible_array, - -# Initialize to unknown -ac_cv_c99_flexible_array=no - -AC_TRY_LINK([[ - #include - typedef struct { - int k; - char buffer [] ; - } MY_STRUCT ; - ]], - [ MY_STRUCT *p = calloc (1, sizeof (MY_STRUCT) + 42); ], - ac_cv_c99_flexible_array=yes, - ac_cv_c99_flexible_array=no - ))] -) # AC_C99_FLEXIBLE_ARRAY - - - - - -dnl @synopsis AC_C99_FUNC_LRINT -dnl -dnl Check whether C99's lrint function is available. -dnl @version 1.3 Feb 12 2002 -dnl @author Erik de Castro Lopo -dnl -dnl Permission to use, copy, modify, distribute, and sell this file for any -dnl purpose is hereby granted without fee, provided that the above copyright -dnl and this permission notice appear in all copies. No representations are -dnl made about the suitability of this software for any purpose. It is -dnl provided "as is" without express or implied warranty. -dnl -AC_DEFUN([AC_C99_FUNC_LRINT], -[AC_CACHE_CHECK(for lrint, - ac_cv_c99_lrint, -[ -lrint_save_CFLAGS=$CFLAGS -CFLAGS="-lm" -AC_TRY_LINK([ -#define _ISOC9X_SOURCE 1 -#define _ISOC99_SOURCE 1 -#define __USE_ISOC99 1 -#define __USE_ISOC9X 1 - -#include -], if (!lrint(3.14159)) lrint(2.7183);, ac_cv_c99_lrint=yes, ac_cv_c99_lrint=no) - -CFLAGS=$lrint_save_CFLAGS - -]) - -if test "$ac_cv_c99_lrint" = yes; then - AC_DEFINE(HAVE_LRINT, 1, - [Define if you have C99's lrint function.]) -fi -])# AC_C99_FUNC_LRINT -dnl @synopsis AC_C99_FUNC_LRINTF -dnl -dnl Check whether C99's lrintf function is available. -dnl @version 1.3 Feb 12 2002 -dnl @author Erik de Castro Lopo -dnl -dnl Permission to use, copy, modify, distribute, and sell this file for any -dnl purpose is hereby granted without fee, provided that the above copyright -dnl and this permission notice appear in all copies. No representations are -dnl made about the suitability of this software for any purpose. It is -dnl provided "as is" without express or implied warranty. -dnl -AC_DEFUN([AC_C99_FUNC_LRINTF], -[AC_CACHE_CHECK(for lrintf, - ac_cv_c99_lrintf, -[ -AC_TRY_LINK([ -#define _ISOC9X_SOURCE 1 -#define _ISOC99_SOURCE 1 -#define __USE_ISOC99 1 -#define __USE_ISOC9X 1 - -#include -], if (!lrintf(3.14159)) lrintf(2.7183);, ac_cv_c99_lrintf=yes, ac_cv_c99_lrintf=no) -]) - -if test "$ac_cv_c99_lrintf" = yes; then - AC_DEFINE(HAVE_LRINTF, 1, - [Define if you have C99's lrintf function.]) -fi -])# AC_C99_FUNC_LRINTF - - - - -dnl @synopsis AC_C99_FUNC_LLRINT -dnl -dnl Check whether C99's llrint function is available. -dnl @version 1.1 Sep 30 2002 -dnl @author Erik de Castro Lopo -dnl -dnl Permission to use, copy, modify, distribute, and sell this file for any -dnl purpose is hereby granted without fee, provided that the above copyright -dnl and this permission notice appear in all copies. No representations are -dnl made about the suitability of this software for any purpose. It is -dnl provided "as is" without express or implied warranty. -dnl -AC_DEFUN([AC_C99_FUNC_LLRINT], -[AC_CACHE_CHECK(for llrint, - ac_cv_c99_llrint, -[ -AC_TRY_LINK([ -#define _ISOC9X_SOURCE 1 -#define _ISOC99_SOURCE 1 -#define __USE_ISOC99 1 -#define __USE_ISOC9X 1 - -#include -#include -], int64_t x ; x = llrint(3.14159) ;, ac_cv_c99_llrint=yes, ac_cv_c99_llrint=no) -]) - -if test "$ac_cv_c99_llrint" = yes; then - AC_DEFINE(HAVE_LLRINT, 1, - [Define if you have C99's llrint function.]) -fi -])# AC_C99_FUNC_LLRINT - - - -dnl @synopsis AC_C_CLIP_MODE -dnl -dnl Determine the clipping mode when converting float to int. -dnl @version 1.0 May 17 2003 -dnl @author Erik de Castro Lopo -dnl -dnl Permission to use, copy, modify, distribute, and sell this file for any -dnl purpose is hereby granted without fee, provided that the above copyright -dnl and this permission notice appear in all copies. No representations are -dnl made about the suitability of this software for any purpose. It is -dnl provided "as is" without express or implied warranty. - - - -dnl Find the clipping mode in the following way: -dnl 1) If we are not cross compiling test it. -dnl 2) IF we are cross compiling, assume that clipping isn't done correctly. - -AC_DEFUN([AC_C_CLIP_MODE], -[AC_CACHE_CHECK(processor clipping capabilities, - ac_cv_c_clip_type, - -# Initialize to unknown -ac_cv_c_clip_positive=unknown -ac_cv_c_clip_negative=unknown - -if test $ac_cv_c_clip_positive = unknown ; then - AC_TRY_RUN( - [[ - #define _ISOC9X_SOURCE 1 - #define _ISOC99_SOURCE 1 - #define __USE_ISOC99 1 - #define __USE_ISOC9X 1 - #include - int main (void) - { double fval ; - int k, ival ; - - fval = 1.0 * 0x7FFFFFFF ; - for (k = 0 ; k < 100 ; k++) - { ival = (lrint (fval)) >> 24 ; - if (ival != 127) - return 1 ; - - fval *= 1.2499999 ; - } ; - - return 0 ; - } - ]], - ac_cv_c_clip_positive=yes, - ac_cv_c_clip_positive=no, - ac_cv_c_clip_positive=unknown - ) - - AC_TRY_RUN( - [[ - #define _ISOC9X_SOURCE 1 - #define _ISOC99_SOURCE 1 - #define __USE_ISOC99 1 - #define __USE_ISOC9X 1 - #include - int main (void) - { double fval ; - int k, ival ; - - fval = -8.0 * 0x10000000 ; - for (k = 0 ; k < 100 ; k++) - { ival = (lrint (fval)) >> 24 ; - if (ival != -128) - return 1 ; - - fval *= 1.2499999 ; - } ; - - return 0 ; - } - ]], - ac_cv_c_clip_negative=yes, - ac_cv_c_clip_negative=no, - ac_cv_c_clip_negative=unknown - ) - fi - -if test $ac_cv_c_clip_positive = yes ; then - ac_cv_c_clip_positive=1 -else - ac_cv_c_clip_positive=0 - fi - -if test $ac_cv_c_clip_negative = yes ; then - ac_cv_c_clip_negative=1 -else - ac_cv_c_clip_negative=0 - fi - -[[ -case "$ac_cv_c_clip_positive$ac_cv_c_clip_negative" in - "00") - ac_cv_c_clip_type="none" - ;; - "10") - ac_cv_c_clip_type="positive" - ;; - "01") - ac_cv_c_clip_type="negative" - ;; - "11") - ac_cv_c_clip_type="both" - ;; - esac - ]] - -) -] - -)# AC_C_CLIP_MODE - - -dnl @synopsis AC_ADD_CFLAGS -dnl -dnl Add the given option to CFLAGS, if it doesn't break the compiler - -AC_DEFUN([AC_ADD_CFLAGS], -[AC_MSG_CHECKING([if $CC accepts $1]) - ac_add_cflags__old_cflags="$CFLAGS" - CFLAGS="$CFLAGS $1" - AC_TRY_LINK([#include ], - [printf("Hello, World!\n"); return 0;], - AC_MSG_RESULT([yes]), - AC_MSG_RESULT([no]) - CFLAGS="$ac_add_cflags__old_cflags") -]) - - - - -ifelse(dnl - - Do not edit or modify anything in this comment block. - The arch-tag line is a file identity tag for the GNU Arch - revision control system. - - arch-tag: bc38294d-bb5c-42ad-90b9-779def5eaab7 - -)dnl diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 00000000..3b64b21e --- /dev/null +++ b/autogen.sh @@ -0,0 +1,132 @@ +#!/bin/sh +# Run this to set up the build system: configure, makefiles, etc. +# (based on the version in enlightenment's cvs) + +ACLOCAL_FLAGS="-I M4" + +package="libsndfile" + +olddir=`pwd` +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +cd "$srcdir" +DIE=0 + +echo "checking for autoconf... " +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have autoconf installed to compile $package." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +VERSIONGREP="sed -e s/.*[^0-9\.]\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/" +VERSIONMKMAJ="sed -e s/\([0-9][0-9]*\)[^0-9].*/\\1/" +VERSIONMKMIN="sed -e s/.*[0-9][0-9]*\.//" + +# do we need automake? +if test -r Makefile.am; then + AM_OPTIONS=`fgrep AUTOMAKE_OPTIONS Makefile.am` + AM_NEEDED=`echo $AM_OPTIONS | $VERSIONGREP` + if test x"$AM_NEEDED" = "x$AM_OPTIONS"; then + AM_NEEDED="" + fi + if test -z $AM_NEEDED; then + echo -n "checking for automake... " + AUTOMAKE=automake + ACLOCAL=aclocal + if ($AUTOMAKE --version < /dev/null > /dev/null 2>&1); then + echo "yes" + else + echo "no" + AUTOMAKE= + fi + else + echo -n "checking for automake $AM_NEEDED or later... " + majneeded=`echo $AM_NEEDED | $VERSIONMKMAJ` + minneeded=`echo $AM_NEEDED | $VERSIONMKMIN` + for am in automake-$AM_NEEDED automake$AM_NEEDED \ + automake automake-1.7 automake-1.8 automake-1.9 automake-1.10; do + ($am --version < /dev/null > /dev/null 2>&1) || continue + ver=`$am --version < /dev/null | head -n 1 | $VERSIONGREP` + maj=`echo $ver | $VERSIONMKMAJ` + min=`echo $ver | $VERSIONMKMIN` + if test $maj -eq $majneeded -a $min -ge $minneeded; then + AUTOMAKE=$am + echo $AUTOMAKE + break + fi + done + test -z $AUTOMAKE && echo "no" + echo -n "checking for aclocal $AM_NEEDED or later... " + for ac in aclocal-$AM_NEEDED aclocal$AM_NEEDED \ + aclocal aclocal-1.7 aclocal-1.8 aclocal-1.9 aclocal-1.10; do + ($ac --version < /dev/null > /dev/null 2>&1) || continue + ver=`$ac --version < /dev/null | head -n 1 | $VERSIONGREP` + maj=`echo $ver | $VERSIONMKMAJ` + min=`echo $ver | $VERSIONMKMIN` + if test $maj -eq $majneeded -a $min -ge $minneeded; then + ACLOCAL=$ac + echo $ACLOCAL + break + fi + done + test -z $ACLOCAL && echo "no" + fi + test -z $AUTOMAKE || test -z $ACLOCAL && { + echo + echo "You must have automake installed to compile $package." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + exit 1 + } +fi + +echo -n "checking for libtool... " +for LIBTOOLIZE in libtoolize glibtoolize nope; do + ($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 && break +done +if test x$LIBTOOLIZE = xnope; then + echo "nope." + LIBTOOLIZE=libtoolize +else + echo $LIBTOOLIZE +fi +($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have libtool installed to compile $package." + echo "Download the appropriate package for your system," + echo "or get the source from one of the GNU ftp sites" + echo "listed in http://www.gnu.org/order/ftp.html" + DIE=1 +} + +if test "$DIE" -eq 1; then + exit 1 +fi + +if test -z "$*"; then + echo "I am going to run ./configure with no arguments - if you wish " + echo "to pass any to it, please specify them on the $0 command line." +fi + +echo "Generating configuration files for $package, please wait...." + +echo " $ACLOCAL $ACLOCAL_FLAGS" +$ACLOCAL $ACLOCAL_FLAGS || exit 1 +echo " $LIBTOOLIZE --automake" +$LIBTOOLIZE --automake || exit 1 +echo " autoheader" +autoheader || exit 1 +echo " $AUTOMAKE --add-missing $AUTOMAKE_FLAGS" +$AUTOMAKE --add-missing $AUTOMAKE_FLAGS || exit 1 +echo " autoconf" +autoconf || exit 1 + +cd $olddir +$srcdir/configure --enable-maintainer-mode --enable-gcc-werror "$@" && echo + +(cd src && make genfiles) +(cd tests && make genfiles) diff --git a/configure.ac b/configure.ac index 2ab0aecd..8e4c235a 100644 --- a/configure.ac +++ b/configure.ac @@ -3,13 +3,20 @@ dnl Require autoconf version AC_PREREQ(2.57) -AC_INIT([libsndfile],[1.0.18pre13],[erikd@mega-nerd.com]) +AC_INIT([libsndfile],[1.0.18pre17],[erikd@mega-nerd.com]) + +# Put config stuff in Cfg. +AC_CONFIG_AUX_DIR(Cfg) + AC_CONFIG_SRCDIR([src/sndfile.c]) AC_CANONICAL_TARGET([]) AM_INIT_AUTOMAKE($PACKAGE_NAME,$PACKAGE_VERSION) AC_CONFIG_HEADERS([src/config.h]) +dnl Add parameters for aclocal +AC_SUBST(ACLOCAL_AMFLAGS, "-I M4") + AC_LANG([C]) #------------------------------------------------------------------------------------ @@ -33,7 +40,7 @@ SHARED_VERSION_INFO="1:18:0" AC_PROG_CC AM_PROG_LIBTOOL -AC_CHECK_PROG(autogen, autogen, yes, no) +AC_CHECK_PROG(HAVE_AUTOGEN, autogen, yes, no) AC_PROG_INSTALL AC_PROG_LN_S @@ -43,7 +50,6 @@ AC_HEADER_STDC AC_CHECK_HEADERS(endian.h) AC_CHECK_HEADERS(byteswap.h) AC_CHECK_HEADERS(locale.h) -AC_CHECK_HEADERS(inttypes.h) AC_HEADER_SYS_WAIT @@ -259,6 +265,13 @@ case "$host_os" in ;; esac +#==================================================================================== +# Check for requirements for building plugins for other languages/enviroments. + +dnl Octave maths environment http://www.octave.org/ +AC_OCTAVE_BUILD + + #==================================================================================== # Check for libsqlite3 (only used in regtest). @@ -466,7 +479,7 @@ if test $ac_cv_sizeof_double != 8 ; then AC_MSG_WARN([[******************************************************************]]) fi -if test x"$ac_cv_prog_autogen" = "xno" ; then +if test x"$ac_cv_prog_HAVE_AUTOGEN" = "xno" ; then AC_MSG_WARN([[Touching files in directory tests/.]]) touch tests/*.c tests/*.h fi @@ -611,16 +624,13 @@ AC_CONFIG_FILES([ \ src/FLAC/src/share/utf8/Makefile src/FLAC/src/test_libFLAC/Makefile \ src/FLAC/src/test_libs_common/Makefile src/FLAC/src/test_seeking/Makefile \ src/FLAC/src/test_streams/Makefile src/FLAC/test/Makefile \ - src/FLAC/src/monkeys_audio_utilities/Makefile \ - src/FLAC/src/monkeys_audio_utilities/flac_mac/Makefile \ - src/FLAC/src/monkeys_audio_utilities/flac_ren/Makefile \ src/FLAC/src/test_grabbag/Makefile src/FLAC/src/test_grabbag/cuesheet/Makefile \ src/FLAC/src/test_grabbag/picture/Makefile \ \ src/OGG/include/ogg/Makefile src/OGG/include/Makefile src/OGG/Makefile \ man/Makefile examples/Makefile tests/Makefile regtest/Makefile \ - doc/Makefile doc/libsndfile.css \ - Win32/Makefile Octave/Makefile \ + M4/Makefile doc/Makefile Win32/Makefile Octave/Makefile \ + doc/libsndfile.css \ Makefile libsndfile.spec sndfile.pc \ ]) AC_OUTPUT diff --git a/doc/development.html b/doc/development.html index 61fbda42..ee0d2218 100644 --- a/doc/development.html +++ b/doc/development.html @@ -33,7 +33,8 @@ it on windows.

-The main archive archive can be found at: +The main archive archive can be found at (yes, the directory looks empty, +but it isn't): http://www.mega-nerd.com/Bzr/libsndfile-pub/

diff --git a/doc/index.html b/doc/index.html index fce8c4fb..f2bcd0ad 100644 --- a/doc/index.html +++ b/doc/index.html @@ -282,8 +282,12 @@
  • FLAC.

    - I have decided that I will not be adding support for MPEG Layer 3 due to the - patent issues surrounding this file format. + I have decided that I will not be adding support for MPEG Layer 3 (commonly + known as MP3) due to the patent issues surrounding this file format. + See + + the FAQ + for more.

    Other file formats may also be added on request. diff --git a/examples/generate.c b/examples/generate.c index 1b0eec79..d0433130 100644 --- a/examples/generate.c +++ b/examples/generate.c @@ -1,19 +1,33 @@ /* -** Copyright (C) 2002-2005 Erik de Castro Lopo +** Copyright (C) 2002-2007 Erik de Castro Lopo ** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. +** All rights reserved. ** -** 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. +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: ** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the author nor the names of any contributors may be used +** to endorse or promote products derived from this software without +** specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "sfconfig.h" diff --git a/examples/list_formats.c b/examples/list_formats.c index 0b6db499..24b6b7c8 100644 --- a/examples/list_formats.c +++ b/examples/list_formats.c @@ -1,19 +1,33 @@ /* -** Copyright (C) 2001-2005 Erik de Castro Lopo +** Copyright (C) 2001-2007 Erik de Castro Lopo ** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. +** All rights reserved. ** -** 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. +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: ** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the author nor the names of any contributors may be used +** to endorse or promote products derived from this software without +** specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include diff --git a/examples/make_sine.c b/examples/make_sine.c index 3a50c26f..e7b9e0f4 100644 --- a/examples/make_sine.c +++ b/examples/make_sine.c @@ -1,19 +1,33 @@ /* -** Copyright (C) 1999-2005 Erik de Castro Lopo +** Copyright (C) 1999-2007 Erik de Castro Lopo ** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. +** All rights reserved. ** -** 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. +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: ** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the author nor the names of any contributors may be used +** to endorse or promote products derived from this software without +** specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include diff --git a/examples/paf_write.c b/examples/paf_write.c deleted file mode 100644 index 394b2a35..00000000 --- a/examples/paf_write.c +++ /dev/null @@ -1,88 +0,0 @@ -/* -** Copyright (C) 1999-2005 Erik de Castro Lopo -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - - -#include -#include -#include - -#include - -#define SAMPLE_RATE 8000 -#define SAMPLE_COUNT 100 - -int -main (void) -{ SNDFILE *file ; - SF_INFO sfinfo ; - char *filename ; - int k, buffer [SAMPLE_COUNT] ; - - for (k = 0 ; k < SAMPLE_COUNT ; k++) - buffer [k] = ((3 * k + 2) << 24) + ((3 * k + 1) << 16) + ((3 * k) << 8) ; - - /* Big endian first. */ - sfinfo.samplerate = SAMPLE_RATE ; - sfinfo.frames = SAMPLE_COUNT ; - sfinfo.channels = 1 ; - sfinfo.format = (SF_ENDIAN_BIG | SF_FORMAT_PAF | SF_FORMAT_PCM_24) ; - - filename = "be-pcm24.paf" ; - - if (! (file = sf_open (filename, SFM_WRITE, &sfinfo))) - { printf ("Error : Not able to open output file.\n") ; - return 1 ; - } ; - - printf ("Writing data to '%s'\n", filename) ; - - if (sf_write_int (file, buffer, SAMPLE_COUNT) != SAMPLE_COUNT) - puts (sf_strerror (file)) ; - - sf_close (file) ; - - /* Little endian first. */ - sfinfo.samplerate = SAMPLE_RATE ; - sfinfo.frames = SAMPLE_COUNT ; - sfinfo.channels = 1 ; - sfinfo.format = (SF_ENDIAN_LITTLE | SF_FORMAT_PAF | SF_FORMAT_PCM_24) ; - - filename = "le-pcm24.paf" ; - - if (! (file = sf_open (filename, SFM_WRITE, &sfinfo))) - { printf ("Error : Not able to open output file.\n") ; - return 1 ; - } ; - - printf ("Writing data to '%s'\n", filename) ; - - if (sf_write_int (file, buffer, SAMPLE_COUNT) != SAMPLE_COUNT) - puts (sf_strerror (file)) ; - - sf_close (file) ; - - return 0 ; -} /* main */ - -/* -** Do not edit or modify anything in this comment block. -** The arch-tag line is a file identity tag for the GNU Arch -** revision control system. -** -** arch-tag: 62025b88-1f3f-46fb-994a-8220bf915772 -*/ diff --git a/examples/sfprocess.c b/examples/sfprocess.c index e48fcfb6..43144750 100644 --- a/examples/sfprocess.c +++ b/examples/sfprocess.c @@ -1,19 +1,33 @@ /* ** Copyright (C) 2001-2005 Erik de Castro Lopo ** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. +** All rights reserved. ** -** 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. +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: ** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the author nor the names of any contributors may be used +** to endorse or promote products derived from this software without +** specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include diff --git a/examples/sndfile-convert.c b/examples/sndfile-convert.c index 7072382e..a9d0751a 100644 --- a/examples/sndfile-convert.c +++ b/examples/sndfile-convert.c @@ -1,22 +1,35 @@ /* -** Copyright (C) 1999-2005 Erik de Castro Lopo +** Copyright (C) 1999-2007 Erik de Castro Lopo ** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. +** All rights reserved. ** -** 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. +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: ** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the author nor the names of any contributors may be used +** to endorse or promote products derived from this software without +** specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include #include #include diff --git a/examples/sndfile-data-trim.c b/examples/sndfile-data-trim.c index 25b8f921..e2cd4f80 100644 --- a/examples/sndfile-data-trim.c +++ b/examples/sndfile-data-trim.c @@ -1,19 +1,33 @@ /* ** Copyright (C) 2007 Erik de Castro Lopo ** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. +** All rights reserved. ** -** 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. +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: ** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the author nor the names of any contributors may be used +** to endorse or promote products derived from this software without +** specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/examples/sndfile-info.c b/examples/sndfile-info.c index 44e2ec17..d6f3945a 100644 --- a/examples/sndfile-info.c +++ b/examples/sndfile-info.c @@ -1,19 +1,33 @@ /* -** Copyright (C) 1999-2006 Erik de Castro Lopo +** Copyright (C) 1999-2007 Erik de Castro Lopo ** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. +** All rights reserved. ** -** 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. +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: ** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the author nor the names of any contributors may be used +** to endorse or promote products derived from this software without +** specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include diff --git a/examples/sndfile-play.c b/examples/sndfile-play.c index 60ebf93a..abcd1da2 100644 --- a/examples/sndfile-play.c +++ b/examples/sndfile-play.c @@ -1,19 +1,33 @@ /* -** Copyright (C) 1999-2005 Erik de Castro Lopo +** Copyright (C) 1999-2007 Erik de Castro Lopo ** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. +** All rights reserved. ** -** 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. +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: ** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the author nor the names of any contributors may be used +** to endorse or promote products derived from this software without +** specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "sfconfig.h" diff --git a/reconfigure.mk b/reconfigure.mk deleted file mode 100755 index bd65bc82..00000000 --- a/reconfigure.mk +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/make -f - -# The auto tools MUST be run in the following order: -# -# 1. aclocal -# 2. libtoolize (if you use libtool) -# 3. autoconf -# 4. autoheader (if you use autoheader) -# 5. automake (if you use automake) -# -# The following makefile runs these in the correct order according to their -# dependancies. It also makes up for Mac OSX's fucked-upped-ness. - -ACLOCAL = aclocal - -ifneq ($(shell uname -s), Darwin) - LIBTOOLIZE = libtoolize -else - # Fuck Apple! Why the hell did they rename libtoolize???? - LIBTOOLIZE = glibtoolize - # Fink (and DarwinPorts/MacPorts) sucks as well, but this seems necessary. - ACLOCAL_INC = -I /opt/local/share/aclocal -endif - -genfiles : config.status - (cd src && make genfiles) - (cd tests && make genfiles) - -config.status: configure src/config.h.in Makefile.in src/Makefile.in tests/Makefile.in - ./configure --enable-gcc-werror - -configure: ltmain.sh - autoconf - -Makefile.in: Makefile.am - automake --copy --add-missing - -src/Makefile.in: src/Makefile.am - automake --copy --add-missing - -tests/Makefile.in: tests/Makefile.am - automake --copy --add-missing - -src/config.h.in: configure - autoheader - -libtool ltmain.sh: aclocal.m4 - $(LIBTOOLIZE) --copy --force - -# Need to re-run aclocal whenever acinclude.m4 is modified. -aclocal.m4: acinclude.m4 - $(ACLOCAL) $(ACLOCAL_INC) - -clean: - rm -f libtool ltmain.sh aclocal.m4 src/config.h.in config.cache config.status - rm -rf autom4te.cache - find . -name Makefile.in -exec rm -f {} \; - find . -name .deps -type d -exec rm -rf {} \; - diff --git a/src/FLAC/include/FLAC/Makefile.am b/src/FLAC/include/FLAC/Makefile.am index 19f49b1f..7a80fe60 100644 --- a/src/FLAC/include/FLAC/Makefile.am +++ b/src/FLAC/include/FLAC/Makefile.am @@ -28,9 +28,7 @@ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -flaccincludedir = $(includedir)/FLAC - -flaccinclude_HEADERS = \ +noinst_HEADERS = \ all.h \ assert.h \ callback.h \ diff --git a/src/FLAC/include/FLAC/all.h b/src/FLAC/include/FLAC/all.h index 1611a261..66ccdd2a 100644 --- a/src/FLAC/include/FLAC/all.h +++ b/src/FLAC/include/FLAC/all.h @@ -141,6 +141,11 @@ * encoder, and no metadata interface, you can remove the stream encoder * and the metadata interface, which will greatly reduce the size of the * library. + * + * Also, there are several places in the libFLAC code with comments marked + * with "OPT:" where a #define can be changed to enable code that might be + * faster on a specific platform. Experimenting with these can yield faster + * binaries. */ /** \defgroup porting Porting Guide for New Versions diff --git a/src/FLAC/include/FLAC/metadata.h b/src/FLAC/include/FLAC/metadata.h index f9796aea..c679e79f 100644 --- a/src/FLAC/include/FLAC/metadata.h +++ b/src/FLAC/include/FLAC/metadata.h @@ -32,6 +32,7 @@ #ifndef FLAC__METADATA_H #define FLAC__METADATA_H +#include /* for off_t */ #include "export.h" #include "callback.h" #include "format.h" @@ -443,6 +444,37 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIte */ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator); +/*@@@@add to tests*/ +/** Returns a flag telling if the current metadata block is the last. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c true if the current metadata block is the last in the file, + * else \c false. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_last(const FLAC__Metadata_SimpleIterator *iterator); + +/*@@@@add to tests*/ +/** Get the offset of the metadata block at the current position. This + * avoids reading the actual block data which can save time for large + * blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval off_t + * The offset of the metadata block at the current iterator position. + * This is the byte offset relative to the beginning of the file of + * the current metadata block's header. + */ +FLAC_API off_t FLAC__metadata_simple_iterator_get_block_offset(const FLAC__Metadata_SimpleIterator *iterator); + /** Get the type of the metadata block at the current position. This * avoids reading the actual block data which can save time for large * blocks. @@ -455,9 +487,52 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIte * \retval FLAC__MetadataType * The type of the metadata block at the current iterator position. */ - FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator); +/*@@@@add to tests*/ +/** Get the length of the metadata block at the current position. This + * avoids reading the actual block data which can save time for large + * blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \assert + * \code iterator != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval unsigned + * The length of the metadata block at the current iterator position. + * The is same length as that in the + * metadata block header, + * i.e. the length of the metadata body that follows the header. + */ +FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator); + +/*@@@@add to tests*/ +/** Get the application ID of the \c APPLICATION block at the current + * position. This avoids reading the actual block data which can save + * time for large blocks. + * + * \param iterator A pointer to an existing initialized iterator. + * \param id A pointer to a buffer of at least \c 4 bytes where + * the ID will be stored. + * \assert + * \code iterator != NULL \endcode + * \code id != NULL \endcode + * \a iterator has been successfully initialized with + * FLAC__metadata_simple_iterator_init() + * \retval FLAC__bool + * \c true if the ID was successfully read, else \c false, in which + * case you should check FLAC__metadata_simple_iterator_status() to + * find out why. If the status is + * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, then the + * current metadata block is not an \c APPLICATION block. Otherwise + * if the status is + * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR or + * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, an I/O error + * occurred and the iterator can no longer be used. + */ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_get_application_id(FLAC__Metadata_SimpleIterator *iterator, FLAC__byte *id); + /** Get the metadata block at the current position. You can modify the * block but must use FLAC__metadata_simple_iterator_set_block() to * write it back to the FLAC file. @@ -471,7 +546,8 @@ FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const * \a iterator has been successfully initialized with * FLAC__metadata_simple_iterator_init() * \retval FLAC__StreamMetadata* - * The current metadata block. + * The current metadata block, or \c NULL if there was a memory + * allocation error. */ FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator); diff --git a/src/FLAC/include/share/Makefile.am b/src/FLAC/include/share/Makefile.am index b50d883d..513828b8 100644 --- a/src/FLAC/include/share/Makefile.am +++ b/src/FLAC/include/share/Makefile.am @@ -5,6 +5,7 @@ AUTOMAKE_OPTIONS = foreign SUBDIRS = grabbag EXTRA_DIST = \ + alloc.h \ getopt.h \ grabbag.h \ replaygain_analysis.h \ diff --git a/src/FLAC/include/share/alloc.h b/src/FLAC/include/share/alloc.h new file mode 100644 index 00000000..63b12f3b --- /dev/null +++ b/src/FLAC/include/share/alloc.h @@ -0,0 +1,210 @@ +/* alloc - Convenience routines for safely allocating memory + * Copyright (C) 2007 Josh Coalson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef FLAC__SHARE__ALLOC_H +#define FLAC__SHARE__ALLOC_H + +#if HAVE_CONFIG_H +# include +#endif + +/* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early + * before #including this file, otherwise SIZE_MAX might not be defined + */ + +#include /* for SIZE_MAX */ +#if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__ +#include /* for SIZE_MAX in case limits.h didn't get it */ +#endif +#include /* for size_t, malloc(), etc */ + +#ifndef SIZE_MAX +# ifndef SIZE_T_MAX +# ifdef _MSC_VER +# define SIZE_T_MAX UINT_MAX +# else +# error +# endif +# endif +# define SIZE_MAX SIZE_T_MAX +#endif + +#define FLaC__INLINE inline + +/* avoid malloc()ing 0 bytes, see: + * https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003 +*/ +static FLaC__INLINE void *safe_malloc_(size_t size) +{ + /* malloc(0) is undefined; FLAC src convention is to always allocate */ + if(!size) + size++; + return malloc(size); +} + +static FLaC__INLINE void *safe_calloc_(size_t nmemb, size_t size) +{ + if(!nmemb || !size) + return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ + return calloc(nmemb, size); +} + +/*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */ + +static FLaC__INLINE void *safe_malloc_add_2op_(size_t size1, size_t size2) +{ + size2 += size1; + if(size2 < size1) + return 0; + return safe_malloc_(size2); +} + +static FLaC__INLINE void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3) +{ + size2 += size1; + if(size2 < size1) + return 0; + size3 += size2; + if(size3 < size2) + return 0; + return safe_malloc_(size3); +} + +static FLaC__INLINE void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4) +{ + size2 += size1; + if(size2 < size1) + return 0; + size3 += size2; + if(size3 < size2) + return 0; + size4 += size3; + if(size4 < size3) + return 0; + return safe_malloc_(size4); +} + +static FLaC__INLINE void *safe_malloc_mul_2op_(size_t size1, size_t size2) +#if 0 +needs support for cases where sizeof(size_t) != 4 +{ + /* could be faster #ifdef'ing off SIZEOF_SIZE_T */ + if(sizeof(size_t) == 4) { + if ((double)size1 * (double)size2 < 4294967296.0) + return malloc(size1*size2); + } + return 0; +} +#else +/* better? */ +{ + if(!size1 || !size2) + return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ + if(size1 > SIZE_MAX / size2) + return 0; + return malloc(size1*size2); +} +#endif + +static FLaC__INLINE void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3) +{ + if(!size1 || !size2 || !size3) + return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ + if(size1 > SIZE_MAX / size2) + return 0; + size1 *= size2; + if(size1 > SIZE_MAX / size3) + return 0; + return malloc(size1*size3); +} + +/* size1*size2 + size3 */ +static FLaC__INLINE void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3) +{ + if(!size1 || !size2) + return safe_malloc_(size3); + if(size1 > SIZE_MAX / size2) + return 0; + return safe_malloc_add_2op_(size1*size2, size3); +} + +/* size1 * (size2 + size3) */ +static FLaC__INLINE void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3) +{ + if(!size1 || (!size2 && !size3)) + return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ + size2 += size3; + if(size2 < size3) + return 0; + return safe_malloc_mul_2op_(size1, size2); +} + +static FLaC__INLINE void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) +{ + size2 += size1; + if(size2 < size1) + return 0; + return realloc(ptr, size2); +} + +static FLaC__INLINE void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) +{ + size2 += size1; + if(size2 < size1) + return 0; + size3 += size2; + if(size3 < size2) + return 0; + return realloc(ptr, size3); +} + +static FLaC__INLINE void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) +{ + size2 += size1; + if(size2 < size1) + return 0; + size3 += size2; + if(size3 < size2) + return 0; + size4 += size3; + if(size4 < size3) + return 0; + return realloc(ptr, size4); +} + +static FLaC__INLINE void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) +{ + if(!size1 || !size2) + return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ + if(size1 > SIZE_MAX / size2) + return 0; + return realloc(ptr, size1*size2); +} + +/* size1 * (size2 + size3) */ +static FLaC__INLINE void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) +{ + if(!size1 || (!size2 && !size3)) + return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ + size2 += size3; + if(size2 < size3) + return 0; + return safe_realloc_mul_2op_(ptr, size1, size2); +} + +#endif diff --git a/src/FLAC/include/test_libs_common/metadata_utils.h b/src/FLAC/include/test_libs_common/metadata_utils.h index e1e87b30..2f0f3eef 100644 --- a/src/FLAC/include/test_libs_common/metadata_utils.h +++ b/src/FLAC/include/test_libs_common/metadata_utils.h @@ -24,9 +24,6 @@ */ #include "FLAC/format.h" -#include -#include /* for malloc() */ -#include /* for memcmp() */ FLAC__bool mutils__compare_block_data_streaminfo(const FLAC__StreamMetadata_StreamInfo *block, const FLAC__StreamMetadata_StreamInfo *blockcopy); diff --git a/src/FLAC/src/Makefile.am b/src/FLAC/src/Makefile.am index ec715bb3..1c292c5c 100644 --- a/src/FLAC/src/Makefile.am +++ b/src/FLAC/src/Makefile.am @@ -18,7 +18,6 @@ SUBDIRS = \ libFLAC \ share \ - monkeys_audio_utilities \ test_grabbag \ test_libs_common \ test_libFLAC \ diff --git a/src/FLAC/src/libFLAC/bitwriter.c b/src/FLAC/src/libFLAC/bitwriter.c index 848ed4d6..683daac1 100644 --- a/src/FLAC/src/libFLAC/bitwriter.c +++ b/src/FLAC/src/libFLAC/bitwriter.c @@ -44,6 +44,7 @@ #include "private/bitwriter.h" #include "private/crc.h" #include "FLAC/assert.h" +#include "share/alloc.h" /* Things should be fastest when this matches the machine word size */ /* WATCHOUT: if you change this you must also change the following #defines down to SWAP_BE_WORD_TO_HOST below to match */ @@ -127,7 +128,7 @@ static FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, unsigned bits_to_add) FLAC__ASSERT(new_capacity > bw->capacity); FLAC__ASSERT(new_capacity >= bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD)); - new_buffer = (bwword*)realloc(bw->buffer, sizeof(bwword)*new_capacity); + new_buffer = (bwword*)safe_realloc_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity); if(new_buffer == 0) return false; bw->buffer = new_buffer; diff --git a/src/FLAC/src/libFLAC/format.c b/src/FLAC/src/libFLAC/format.c index 25d69372..68580948 100644 --- a/src/FLAC/src/libFLAC/format.c +++ b/src/FLAC/src/libFLAC/format.c @@ -61,9 +61,9 @@ FLAC_API const char *FLAC__VERSION_STRING = "1.2.0"; #if defined _MSC_VER || defined __BORLANDC__ || defined __MINW32__ /* yet one more hack because of MSVC6: */ -FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.2.0 20070715"; +FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.2.0 CVS-20070820"; #else -FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC CVS 1.2.0 20070715"; +FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.2.0 CVS-20070820"; #endif FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; diff --git a/src/FLAC/src/libFLAC/include/private/md5.h b/src/FLAC/src/libFLAC/include/private/md5.h index 659912c5..e5f675a8 100644 --- a/src/FLAC/src/libFLAC/include/private/md5.h +++ b/src/FLAC/src/libFLAC/include/private/md5.h @@ -33,7 +33,7 @@ typedef struct { FLAC__uint32 buf[4]; FLAC__uint32 bytes[2]; FLAC__byte *internal_buf; - unsigned capacity; + size_t capacity; } FLAC__MD5Context; void FLAC__MD5Init(FLAC__MD5Context *context); diff --git a/src/FLAC/src/libFLAC/lpc.c b/src/FLAC/src/libFLAC/lpc.c index 26d1382e..7806348f 100644 --- a/src/FLAC/src/libFLAC/lpc.c +++ b/src/FLAC/src/libFLAC/lpc.c @@ -569,7 +569,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da } #else /* fully unrolled version for normal use */ { - unsigned i; + int i; FLAC__int64 sum; FLAC__ASSERT(order > 0); @@ -584,7 +584,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da if(order > 8) { if(order > 10) { if(order == 12) { - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; @@ -602,7 +602,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da } } else { /* order == 11 */ - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; @@ -621,7 +621,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da } else { if(order == 10) { - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; @@ -637,7 +637,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da } } else { /* order == 9 */ - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; @@ -656,7 +656,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da else if(order > 4) { if(order > 6) { if(order == 8) { - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; @@ -670,7 +670,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da } } else { /* order == 7 */ - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; @@ -685,7 +685,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da } else { if(order == 6) { - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; @@ -697,7 +697,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da } } else { /* order == 5 */ - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; @@ -712,7 +712,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da else { if(order > 2) { if(order == 4) { - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; @@ -722,7 +722,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da } } else { /* order == 3 */ - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; @@ -733,7 +733,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da } else { if(order == 2) { - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; @@ -741,14 +741,14 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da } } else { /* order == 1 */ - for(i = 0; i < data_len; i++) + for(i = 0; i < (int)data_len; i++) residual[i] = data[i] - (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization); } } } } else { /* order > 12 */ - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; switch(order) { case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; @@ -1099,7 +1099,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l } #else /* fully unrolled version for normal use */ { - unsigned i; + int i; FLAC__int64 sum; FLAC__ASSERT(order > 0); @@ -1114,7 +1114,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l if(order > 8) { if(order > 10) { if(order == 12) { - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; @@ -1132,7 +1132,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l } } else { /* order == 11 */ - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; @@ -1151,7 +1151,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l } else { if(order == 10) { - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; @@ -1167,7 +1167,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l } } else { /* order == 9 */ - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; @@ -1186,7 +1186,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l else if(order > 4) { if(order > 6) { if(order == 8) { - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; @@ -1200,7 +1200,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l } } else { /* order == 7 */ - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; @@ -1215,7 +1215,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l } else { if(order == 6) { - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; @@ -1227,7 +1227,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l } } else { /* order == 5 */ - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; @@ -1242,7 +1242,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l else { if(order > 2) { if(order == 4) { - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; @@ -1252,7 +1252,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l } } else { /* order == 3 */ - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; @@ -1263,7 +1263,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l } else { if(order == 2) { - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; @@ -1271,14 +1271,14 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l } } else { /* order == 1 */ - for(i = 0; i < data_len; i++) + for(i = 0; i < (int)data_len; i++) data[i] = residual[i] + (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization); } } } } else { /* order > 12 */ - for(i = 0; i < data_len; i++) { + for(i = 0; i < (int)data_len; i++) { sum = 0; switch(order) { case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; diff --git a/src/FLAC/src/libFLAC/md5.c b/src/FLAC/src/libFLAC/md5.c index 47e163f9..37cef67b 100644 --- a/src/FLAC/src/libFLAC/md5.c +++ b/src/FLAC/src/libFLAC/md5.c @@ -6,6 +6,7 @@ #include /* for memcpy() */ #include "private/md5.h" +#include "share/alloc.h" #ifndef FLaC__INLINE #define FLaC__INLINE @@ -396,13 +397,19 @@ static void format_input_(FLAC__byte *buf, const FLAC__int32 * const signal[], u */ FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample) { - const unsigned bytes_needed = channels * samples * bytes_per_sample; + const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample; + + /* overflow check */ + if((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample) + return false; + if((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples) + return false; if(ctx->capacity < bytes_needed) { FLAC__byte *tmp = (FLAC__byte*)realloc(ctx->internal_buf, bytes_needed); if(0 == tmp) { free(ctx->internal_buf); - if(0 == (ctx->internal_buf = (FLAC__byte*)malloc(bytes_needed))) + if(0 == (ctx->internal_buf = (FLAC__byte*)safe_malloc_(bytes_needed))) return false; } ctx->internal_buf = tmp; diff --git a/src/FLAC/src/libFLAC/memory.c b/src/FLAC/src/libFLAC/memory.c index 7c7aee94..4d100975 100644 --- a/src/FLAC/src/libFLAC/memory.c +++ b/src/FLAC/src/libFLAC/memory.c @@ -35,6 +35,7 @@ #include "private/memory.h" #include "FLAC/assert.h" +#include "share/alloc.h" void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) { @@ -44,7 +45,7 @@ void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) #ifdef FLAC__ALIGN_MALLOC_DATA /* align on 32-byte (256-bit) boundary */ - x = malloc(bytes+31); + x = safe_malloc_add_2op_(bytes, /*+*/31); #ifdef SIZEOF_VOIDP #if SIZEOF_VOIDP == 4 /* could do *aligned_address = x + ((unsigned) (32 - (((unsigned)x) & 31))) & 31; */ @@ -64,7 +65,7 @@ void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) return 0; #endif #else - x = malloc(bytes); + x = safe_malloc_(bytes); *aligned_address = x; #endif return x; @@ -83,7 +84,10 @@ FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32 FLAC__ASSERT(0 != aligned_pointer); FLAC__ASSERT(unaligned_pointer != aligned_pointer); - pu = (FLAC__int32*)FLAC__memory_alloc_aligned(sizeof(FLAC__int32) * elements, &u.pv); + if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ + return false; + + pu = (FLAC__int32*)FLAC__memory_alloc_aligned(sizeof(*pu) * (size_t)elements, &u.pv); if(0 == pu) { return false; } @@ -109,7 +113,10 @@ FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint FLAC__ASSERT(0 != aligned_pointer); FLAC__ASSERT(unaligned_pointer != aligned_pointer); - pu = (FLAC__uint32*)FLAC__memory_alloc_aligned(sizeof(FLAC__uint32) * elements, &u.pv); + if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ + return false; + + pu = (FLAC__uint32*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); if(0 == pu) { return false; } @@ -135,7 +142,10 @@ FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint FLAC__ASSERT(0 != aligned_pointer); FLAC__ASSERT(unaligned_pointer != aligned_pointer); - pu = (FLAC__uint64*)FLAC__memory_alloc_aligned(sizeof(FLAC__uint64) * elements, &u.pv); + if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ + return false; + + pu = (FLAC__uint64*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); if(0 == pu) { return false; } @@ -161,7 +171,10 @@ FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned FLAC__ASSERT(0 != aligned_pointer); FLAC__ASSERT(unaligned_pointer != aligned_pointer); - pu = (unsigned*)FLAC__memory_alloc_aligned(sizeof(unsigned) * elements, &u.pv); + if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ + return false; + + pu = (unsigned*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); if(0 == pu) { return false; } @@ -189,7 +202,10 @@ FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real * FLAC__ASSERT(0 != aligned_pointer); FLAC__ASSERT(unaligned_pointer != aligned_pointer); - pu = (FLAC__real*)FLAC__memory_alloc_aligned(sizeof(FLAC__real) * elements, &u.pv); + if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ + return false; + + pu = (FLAC__real*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); if(0 == pu) { return false; } diff --git a/src/FLAC/src/libFLAC/metadata_iterators.c b/src/FLAC/src/libFLAC/metadata_iterators.c index a36540ff..b99cb5f3 100644 --- a/src/FLAC/src/libFLAC/metadata_iterators.c +++ b/src/FLAC/src/libFLAC/metadata_iterators.c @@ -61,6 +61,7 @@ #include "FLAC/assert.h" #include "FLAC/stream_decoder.h" +#include "share/alloc.h" #ifdef max #undef max @@ -577,6 +578,22 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIte return true; } +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_last(const FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + return iterator->is_last; +} + +FLAC_API off_t FLAC__metadata_simple_iterator_get_block_offset(const FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + return iterator->offset[iterator->depth]; +} + FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator) { FLAC__ASSERT(0 != iterator); @@ -585,6 +602,41 @@ FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const return iterator->type; } +FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + return iterator->length; +} + +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_get_application_id(FLAC__Metadata_SimpleIterator *iterator, FLAC__byte *id) +{ + const unsigned id_bytes = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8; + + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + FLAC__ASSERT(0 != id); + + if(iterator->type != FLAC__METADATA_TYPE_APPLICATION) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT; + return false; + } + + if(fread(id, 1, id_bytes, iterator->file) != id_bytes) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + return false; + } + + /* back up */ + if(0 != fseeko(iterator->file, -((int)id_bytes), SEEK_CUR)) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + + return true; +} + FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator) { FLAC__StreamMetadata *block = FLAC__metadata_object_new(iterator->type); @@ -2101,6 +2153,9 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_application_cb_(FLA if(read_cb(block->id, 1, id_bytes, handle) != id_bytes) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + if(block_length < id_bytes) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + block_length -= id_bytes; if(block_length == 0) { @@ -2128,7 +2183,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_seektable_cb_(FLAC_ if(block->num_points == 0) block->points = 0; - else if(0 == (block->points = (FLAC__StreamMetadata_SeekPoint*)malloc(block->num_points * sizeof(FLAC__StreamMetadata_SeekPoint)))) + else if(0 == (block->points = (FLAC__StreamMetadata_SeekPoint*)safe_malloc_mul_2op_(block->num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)))) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; for(i = 0; i < block->num_points; i++) { @@ -2161,7 +2216,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_entr entry->entry = 0; } else { - if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length+1))) + if(0 == (entry->entry = (FLAC__byte*)safe_malloc_add_2op_(entry->length, /*+*/1))) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; if(read_cb(entry->entry, 1, entry->length, handle) != entry->length) @@ -2336,7 +2391,7 @@ static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_picture_cstr if(0 != *data) free(*data); - if(0 == (*data = (FLAC__byte*)malloc(*length+1))) + if(0 == (*data = (FLAC__byte*)safe_malloc_add_2op_(*length, /*+*/1))) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; if(*length > 0) { @@ -2365,7 +2420,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_picture_cb_(FLAC__I len = FLAC__STREAM_METADATA_PICTURE_TYPE_LEN / 8; if(read_cb(buffer, 1, len, handle) != len) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; - block->type = unpack_uint32_(buffer, len); + block->type = (FLAC__StreamMetadata_Picture_Type)unpack_uint32_(buffer, len); if((status = read_metadata_block_data_picture_cstring_cb_(handle, read_cb, (FLAC__byte**)(&(block->mime_type)), &len, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN)) != FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK) return status; @@ -3155,7 +3210,7 @@ FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix { static const char *tempfile_suffix = ".metadata_edit"; if(0 == tempfile_path_prefix) { - if(0 == (*tempfilename = (char*)malloc(strlen(filename) + strlen(tempfile_suffix) + 1))) { + if(0 == (*tempfilename = (char*)safe_malloc_add_3op_(strlen(filename), /*+*/strlen(tempfile_suffix), /*+*/1))) { *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; return false; } @@ -3169,7 +3224,7 @@ FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix else p++; - if(0 == (*tempfilename = (char*)malloc(strlen(tempfile_path_prefix) + 1 + strlen(p) + strlen(tempfile_suffix) + 1))) { + if(0 == (*tempfilename = (char*)safe_malloc_add_4op_(strlen(tempfile_path_prefix), /*+*/strlen(p), /*+*/strlen(tempfile_suffix), /*+*/2))) { *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; return false; } diff --git a/src/FLAC/src/libFLAC/metadata_object.c b/src/FLAC/src/libFLAC/metadata_object.c index 75117670..c7f16db1 100644 --- a/src/FLAC/src/libFLAC/metadata_object.c +++ b/src/FLAC/src/libFLAC/metadata_object.c @@ -39,6 +39,7 @@ #include "private/metadata.h" #include "FLAC/assert.h" +#include "share/alloc.h" /**************************************************************************** @@ -53,14 +54,14 @@ * from != NULL && bytes > 0 * to <- copy of from * else ASSERT - * malloc error leaved 'to' unchanged + * malloc error leaves 'to' unchanged */ static FLAC__bool copy_bytes_(FLAC__byte **to, const FLAC__byte *from, unsigned bytes) { FLAC__ASSERT(0 != to); if(bytes > 0 && 0 != from) { FLAC__byte *x; - if(0 == (x = (FLAC__byte*)malloc(bytes))) + if(0 == (x = (FLAC__byte*)safe_malloc_(bytes))) return false; memcpy(x, from, bytes); *to = x; @@ -94,7 +95,7 @@ static FLAC__bool free_copy_bytes_(FLAC__byte **to, const FLAC__byte *from, unsi /* realloc() failure leaves entry unchanged */ static FLAC__bool ensure_null_terminated_(FLAC__byte **entry, unsigned length) { - FLAC__byte *x = (FLAC__byte*)realloc(*entry, length+1); + FLAC__byte *x = (FLAC__byte*)safe_realloc_add_2op_(*entry, length, /*+*/1); if(0 != x) { x[length] = '\0'; *entry = x; @@ -132,7 +133,7 @@ static FLAC__bool copy_vcentry_(FLAC__StreamMetadata_VorbisComment_Entry *to, co else { FLAC__byte *x; FLAC__ASSERT(from->length > 0); - if(0 == (x = (FLAC__byte*)malloc(from->length+1))) + if(0 == (x = (FLAC__byte*)safe_malloc_add_2op_(from->length, /*+*/1))) return false; memcpy(x, from->entry, from->length); x[from->length] = '\0'; @@ -150,7 +151,7 @@ static FLAC__bool copy_track_(FLAC__StreamMetadata_CueSheet_Track *to, const FLA else { FLAC__StreamMetadata_CueSheet_Index *x; FLAC__ASSERT(from->num_indices > 0); - if(0 == (x = (FLAC__StreamMetadata_CueSheet_Index*)malloc(from->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index)))) + if(0 == (x = (FLAC__StreamMetadata_CueSheet_Index*)safe_malloc_mul_2op_(from->num_indices, /*times*/sizeof(FLAC__StreamMetadata_CueSheet_Index)))) return false; memcpy(x, from->indices, from->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index)); to->indices = x; @@ -172,7 +173,7 @@ static FLAC__StreamMetadata_SeekPoint *seekpoint_array_new_(unsigned num_points) FLAC__ASSERT(num_points > 0); - object_array = (FLAC__StreamMetadata_SeekPoint*)malloc(num_points * sizeof(FLAC__StreamMetadata_SeekPoint)); + object_array = (FLAC__StreamMetadata_SeekPoint*)safe_malloc_mul_2op_(num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)); if(0 != object_array) { unsigned i; @@ -205,7 +206,7 @@ static FLAC__StreamMetadata_VorbisComment_Entry *vorbiscomment_entry_array_new_( { FLAC__ASSERT(num_comments > 0); - return (FLAC__StreamMetadata_VorbisComment_Entry*)calloc(num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry)); + return (FLAC__StreamMetadata_VorbisComment_Entry*)safe_calloc_(num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry)); } static void vorbiscomment_entry_array_delete_(FLAC__StreamMetadata_VorbisComment_Entry *object_array, unsigned num_comments) @@ -344,14 +345,14 @@ static FLAC__StreamMetadata_CueSheet_Index *cuesheet_track_index_array_new_(unsi { FLAC__ASSERT(num_indices > 0); - return (FLAC__StreamMetadata_CueSheet_Index*)calloc(num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)); + return (FLAC__StreamMetadata_CueSheet_Index*)safe_calloc_(num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)); } static FLAC__StreamMetadata_CueSheet_Track *cuesheet_track_array_new_(unsigned num_tracks) { FLAC__ASSERT(num_tracks > 0); - return (FLAC__StreamMetadata_CueSheet_Track*)calloc(num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)); + return (FLAC__StreamMetadata_CueSheet_Track*)safe_calloc_(num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)); } static void cuesheet_track_array_delete_(FLAC__StreamMetadata_CueSheet_Track *object_array, unsigned num_tracks) @@ -537,6 +538,10 @@ FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMet case FLAC__METADATA_TYPE_PADDING: break; case FLAC__METADATA_TYPE_APPLICATION: + if(to->length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8) { /* underflow check */ + FLAC__metadata_object_delete(to); + return 0; + } memcpy(&to->data.application.id, &object->data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8); if(!copy_bytes_(&to->data.application.data, object->data.application.data, object->length - FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)) { FLAC__metadata_object_delete(to); @@ -545,6 +550,10 @@ FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMet break; case FLAC__METADATA_TYPE_SEEKTABLE: to->data.seek_table.num_points = object->data.seek_table.num_points; + if(to->data.seek_table.num_points > SIZE_MAX / sizeof(FLAC__StreamMetadata_SeekPoint)) { /* overflow check */ + FLAC__metadata_object_delete(to); + return 0; + } if(!copy_bytes_((FLAC__byte**)&to->data.seek_table.points, (FLAC__byte*)object->data.seek_table.points, object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint))) { FLAC__metadata_object_delete(to); return 0; @@ -930,8 +939,12 @@ FLAC_API FLAC__bool FLAC__metadata_object_seektable_resize_points(FLAC__StreamMe return false; } else { - const unsigned old_size = object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint); - const unsigned new_size = new_num_points * sizeof(FLAC__StreamMetadata_SeekPoint); + const size_t old_size = object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint); + const size_t new_size = new_num_points * sizeof(FLAC__StreamMetadata_SeekPoint); + + /* overflow check */ + if((size_t)new_num_points > SIZE_MAX / sizeof(FLAC__StreamMetadata_SeekPoint)) + return false; FLAC__ASSERT(object->data.seek_table.num_points > 0); @@ -1157,8 +1170,12 @@ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_resize_comments(FLAC__St return false; } else { - const unsigned old_size = object->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry); - const unsigned new_size = new_num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry); + const size_t old_size = object->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry); + const size_t new_size = new_num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry); + + /* overflow check */ + if((size_t)new_num_comments > SIZE_MAX / sizeof(FLAC__StreamMetadata_VorbisComment_Entry)) + return false; FLAC__ASSERT(object->data.vorbis_comment.num_comments > 0); @@ -1306,7 +1323,7 @@ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_from_name_value_pa const size_t nn = strlen(field_name); const size_t nv = strlen(field_value); entry->length = nn + 1 /*=*/ + nv; - if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length+1))) + if(0 == (entry->entry = (FLAC__byte*)safe_malloc_add_4op_(nn, /*+*/1, /*+*/nv, /*+*/1))) return false; memcpy(entry->entry, field_name, nn); entry->entry[nn] = '='; @@ -1333,9 +1350,9 @@ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair FLAC__ASSERT(0 != eq); if(0 == eq) return false; /* double protection */ - if(0 == (*field_name = (char*)malloc(nn+1))) + if(0 == (*field_name = (char*)safe_malloc_add_2op_(nn, /*+*/1))) return false; - if(0 == (*field_value = (char*)malloc(nv+1))) { + if(0 == (*field_value = (char*)safe_malloc_add_2op_(nv, /*+*/1))) { free(*field_name); return false; } @@ -1465,8 +1482,12 @@ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_resize_indices(FLAC__St return false; } else { - const unsigned old_size = track->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index); - const unsigned new_size = new_num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index); + const size_t old_size = track->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index); + const size_t new_size = new_num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index); + + /* overflow check */ + if((size_t)new_num_indices > SIZE_MAX / sizeof(FLAC__StreamMetadata_CueSheet_Index)) + return false; FLAC__ASSERT(track->num_indices > 0); @@ -1549,8 +1570,12 @@ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMet return false; } else { - const unsigned old_size = object->data.cue_sheet.num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track); - const unsigned new_size = new_num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track); + const size_t old_size = object->data.cue_sheet.num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track); + const size_t new_size = new_num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track); + + /* overflow check */ + if((size_t)new_num_tracks > SIZE_MAX / sizeof(FLAC__StreamMetadata_CueSheet_Track)) + return false; FLAC__ASSERT(object->data.cue_sheet.num_tracks > 0); @@ -1707,6 +1732,8 @@ FLAC_API FLAC__bool FLAC__metadata_object_picture_set_mime_type(FLAC__StreamMeta /* do the copy first so that if we fail we leave the object untouched */ if(copy) { + if(new_length >= SIZE_MAX) /* overflow check */ + return false; if(!copy_bytes_((FLAC__byte**)(&object->data.picture.mime_type), (FLAC__byte*)mime_type, new_length+1)) return false; } @@ -1737,6 +1764,8 @@ FLAC_API FLAC__bool FLAC__metadata_object_picture_set_description(FLAC__StreamMe /* do the copy first so that if we fail we leave the object untouched */ if(copy) { + if(new_length >= SIZE_MAX) /* overflow check */ + return false; if(!copy_bytes_(&object->data.picture.description, description, new_length+1)) return false; } diff --git a/src/FLAC/src/libFLAC/ogg_helper.c b/src/FLAC/src/libFLAC/ogg_helper.c index aeaf99f4..73f9f0be 100644 --- a/src/FLAC/src/libFLAC/ogg_helper.c +++ b/src/FLAC/src/libFLAC/ogg_helper.c @@ -36,6 +36,7 @@ #include /* for malloc() */ #include /* for memcmp(), memcpy() */ #include "FLAC/assert.h" +#include "share/alloc.h" #include "private/ogg_helper.h" #include "protected/stream_encoder.h" @@ -112,7 +113,7 @@ FLAC__bool simple_ogg_page__get_at(FLAC__StreamEncoder *encoder, FLAC__uint64 po } /* allocate space for the page header */ - if(0 == (page->header = (unsigned char *)malloc(OGG_MAX_HEADER_LEN))) { + if(0 == (page->header = (unsigned char *)safe_malloc_(OGG_MAX_HEADER_LEN))) { encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -154,7 +155,7 @@ FLAC__bool simple_ogg_page__get_at(FLAC__StreamEncoder *encoder, FLAC__uint64 po } /* allocate space for the page body */ - if(0 == (page->body = (unsigned char *)malloc(page->body_len))) { + if(0 == (page->body = (unsigned char *)safe_malloc_(page->body_len))) { encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; return false; } diff --git a/src/FLAC/src/libFLAC/stream_decoder.c b/src/FLAC/src/libFLAC/stream_decoder.c index 864f6800..6240dfb2 100644 --- a/src/FLAC/src/libFLAC/stream_decoder.c +++ b/src/FLAC/src/libFLAC/stream_decoder.c @@ -53,6 +53,7 @@ #endif #endif #include "FLAC/assert.h" +#include "share/alloc.h" #include "protected/stream_decoder.h" #include "private/bitreader.h" #include "private/bitmath.h" @@ -181,7 +182,7 @@ typedef struct FLAC__StreamDecoderPrivate { FLAC__StreamMetadata seek_table; FLAC__bool metadata_filter[128]; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */ FLAC__byte *metadata_filter_ids; - unsigned metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */ + size_t metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */ FLAC__Frame frame; FLAC__bool cached; /* true if there is a byte in lookahead */ FLAC__CPUInfo cpuinfo; @@ -784,7 +785,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__ FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { - if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2))) { + if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -843,7 +844,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__S FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { - if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2))) { + if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1287,9 +1288,11 @@ FILE *get_binary_stdin_(void) */ #if defined _MSC_VER || defined __MINGW32__ _setmode(_fileno(stdin), _O_BINARY); -#elif defined __CYGWIN__ || defined __EMX__ +#elif defined __CYGWIN__ /* almost certainly not needed for any modern Cygwin, but let's be safe... */ setmode(_fileno(stdin), _O_BINARY); +#elif defined __EMX__ + setmode(fileno(stdin), O_BINARY); #endif return stdin; @@ -1323,7 +1326,7 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigne * (at negative indices) for alignment purposes; we use 4 * to keep the data well-aligned. */ - tmp = (FLAC__int32*)malloc(sizeof(FLAC__int32)*(size+4)); + tmp = (FLAC__int32*)safe_malloc_muladd2_(sizeof(FLAC__int32), /*times (*/size, /*+*/4/*)*/); if(tmp == 0) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; @@ -1348,7 +1351,7 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigne FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id) { - unsigned i; + size_t i; FLAC__ASSERT(0 != decoder); FLAC__ASSERT(0 != decoder->private_); @@ -1469,6 +1472,11 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)) return false; /* read_callback_ sets the state for us */ + if(real_length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) { /* underflow check */ + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;/*@@@@@@ maybe wrong error? need to resync?*/ + return false; + } + real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8; if(decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id)) @@ -1531,7 +1539,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) if(!decoder->private_->is_seeking && decoder->private_->metadata_callback) decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data); - /* now we have to free any malloc'ed data in the block */ + /* now we have to free any malloc()ed data in the block */ switch(type) { case FLAC__METADATA_TYPE_PADDING: break; @@ -1671,7 +1679,7 @@ FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_ decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; /* use realloc since we may pass through here several times (e.g. after seeking) */ - if(0 == (decoder->private_->seek_table.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)realloc(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint)))) { + if(0 == (decoder->private_->seek_table.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)safe_realloc_mul_2op_(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1710,7 +1718,7 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length)) return false; /* read_callback_ sets the state for us */ if(obj->vendor_string.length > 0) { - if(0 == (obj->vendor_string.entry = (FLAC__byte*)malloc(obj->vendor_string.length+1))) { + if(0 == (obj->vendor_string.entry = (FLAC__byte*)safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1728,7 +1736,7 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre /* read comments */ if(obj->num_comments > 0) { - if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)malloc(obj->num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) { + if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)safe_malloc_mul_2op_(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1737,7 +1745,7 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length)) return false; /* read_callback_ sets the state for us */ if(obj->comments[i].length > 0) { - if(0 == (obj->comments[i].entry = (FLAC__byte*)malloc(obj->comments[i].length+1))) { + if(0 == (obj->comments[i].entry = (FLAC__byte*)safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1783,7 +1791,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet obj->num_tracks = x; if(obj->num_tracks > 0) { - if(0 == (obj->tracks = (FLAC__StreamMetadata_CueSheet_Track*)calloc(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) { + if(0 == (obj->tracks = (FLAC__StreamMetadata_CueSheet_Track*)safe_calloc_(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1816,7 +1824,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet track->num_indices = (FLAC__byte)x; if(track->num_indices > 0) { - if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)calloc(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) { + if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)safe_calloc_(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1853,7 +1861,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta /* read MIME type */ if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN)) return false; /* read_callback_ sets the state for us */ - if(0 == (obj->mime_type = (char*)malloc(x+1))) { + if(0 == (obj->mime_type = (char*)safe_malloc_add_2op_(x, /*+*/1))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1866,7 +1874,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta /* read description */ if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN)) return false; /* read_callback_ sets the state for us */ - if(0 == (obj->description = (FLAC__byte*)malloc(x+1))) { + if(0 == (obj->description = (FLAC__byte*)safe_malloc_add_2op_(x, /*+*/1))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1895,7 +1903,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta /* read data */ if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN)) return false; /* read_callback_ sets the state for us */ - if(0 == (obj->data = (FLAC__byte*)malloc(obj->data_length))) { + if(0 == (obj->data = (FLAC__byte*)safe_malloc_(obj->data_length))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -2043,6 +2051,8 @@ FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FL } if(!read_zero_padding_(decoder)) return false; + if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption (i.e. "zero bits" were not all zeroes) */ + return true; /* * Read the frame CRC-16 from the footer and check @@ -2078,7 +2088,7 @@ FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FL decoder->private_->output[0][i] = (mid + side) >> 1; decoder->private_->output[1][i] = (mid - side) >> 1; #else - //@@@@@@ OPT: try without 'side' temp variable + /* OPT: without 'side' temp variable */ mid = (decoder->private_->output[0][i] << 1) | (decoder->private_->output[1][i] & 1); /* i.e. if 'side' is odd... */ decoder->private_->output[0][i] = (mid + decoder->private_->output[1][i]) >> 1; decoder->private_->output[1][i] = (mid - decoder->private_->output[1][i]) >> 1; @@ -3178,7 +3188,7 @@ FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint { FLAC__uint64 left_pos = 0, right_pos = stream_length; FLAC__uint64 left_sample = 0, right_sample = FLAC__stream_decoder_get_total_samples(decoder); - FLAC__uint64 this_frame_sample = 0; /* only initialized to avoid compiler warning */ + FLAC__uint64 this_frame_sample = (FLAC__uint64)0 - 1; FLAC__uint64 pos = 0; /* only initialized to avoid compiler warning */ FLAC__bool did_a_seek; unsigned iteration = 0; diff --git a/src/FLAC/src/libFLAC/stream_encoder.c b/src/FLAC/src/libFLAC/stream_encoder.c index 41531ac6..bb4f5f4b 100644 --- a/src/FLAC/src/libFLAC/stream_encoder.c +++ b/src/FLAC/src/libFLAC/stream_encoder.c @@ -54,6 +54,7 @@ #endif #include "FLAC/assert.h" #include "FLAC/stream_decoder.h" +#include "share/alloc.h" #include "protected/stream_encoder.h" #include "private/bitwriter.h" #include "private/bitmath.h" @@ -198,6 +199,7 @@ static unsigned evaluate_fixed_subframe_( unsigned subframe_bps, unsigned order, unsigned rice_parameter, + unsigned rice_parameter_limit, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool do_escape_coding, @@ -219,6 +221,7 @@ static unsigned evaluate_lpc_subframe_( unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, + unsigned rice_parameter_limit, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool do_escape_coding, @@ -244,12 +247,13 @@ static unsigned find_best_partition_order_( unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, + unsigned rice_parameter_limit, unsigned min_partition_order, unsigned max_partition_order, unsigned bps, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, - FLAC__EntropyCodingMethod_PartitionedRice *best_partitioned_rice + FLAC__EntropyCodingMethod *best_ecm ); static void precompute_partition_info_sums_( @@ -280,6 +284,7 @@ static FLAC__bool set_partitioned_rice_( const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, + const unsigned rice_parameter_limit, const unsigned rice_parameter_search_dist, const unsigned partition_order, const FLAC__bool search_for_escapes, @@ -987,7 +992,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( */ encoder->private_->verify.input_fifo.size = encoder->protected_->blocksize+OVERREAD_; for(i = 0; i < encoder->protected_->channels; i++) { - if(0 == (encoder->private_->verify.input_fifo.data[i] = (FLAC__int32*)malloc(sizeof(FLAC__int32) * encoder->private_->verify.input_fifo.size))) { + if(0 == (encoder->private_->verify.input_fifo.data[i] = (FLAC__int32*)safe_malloc_mul_2op_(sizeof(FLAC__int32), /*times*/encoder->private_->verify.input_fifo.size))) { encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; } @@ -1726,7 +1731,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encod } if(num_blocks) { FLAC__StreamMetadata **m; - if(0 == (m = (FLAC__StreamMetadata**)malloc(sizeof(m[0]) * num_blocks))) + if(0 == (m = (FLAC__StreamMetadata**)safe_malloc_mul_2op_(sizeof(m[0]), /*times*/num_blocks))) return false; memcpy(m, metadata, sizeof(m[0]) * num_blocks); encoder->protected_->metadata = m; @@ -3197,6 +3202,8 @@ FLAC__bool process_subframe_( unsigned rice_parameter; unsigned _candidate_bits, _best_bits; unsigned _best_subframe; + /* only use RICE2 partitions if stream bps > 16 */ + const unsigned rice_parameter_limit = FLAC__stream_encoder_get_bits_per_sample(encoder) > 16? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; FLAC__ASSERT(frame_header->blocksize > 0); @@ -3259,11 +3266,11 @@ FLAC__bool process_subframe_( rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > FLAC__FP_ZERO)? (unsigned)FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]+FLAC__FP_ONE_HALF) : 0; /* 0.5 is for rounding */ #endif rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */ - if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + if(rice_parameter >= rice_parameter_limit) { #ifdef DEBUG_VERBOSE - fprintf(stderr, "clipping rice_parameter (%u -> %u) @0\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); + fprintf(stderr, "clipping rice_parameter (%u -> %u) @0\n", rice_parameter, rice_parameter_limit - 1); #endif - rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; + rice_parameter = rice_parameter_limit - 1; } _candidate_bits = evaluate_fixed_subframe_( @@ -3276,6 +3283,7 @@ FLAC__bool process_subframe_( subframe_bps, fixed_order, rice_parameter, + rice_parameter_limit, min_partition_order, max_partition_order, encoder->protected_->do_escape_coding, @@ -3330,11 +3338,11 @@ FLAC__bool process_subframe_( continue; /* don't even try */ rice_parameter = (lpc_residual_bits_per_sample > 0.0)? (unsigned)(lpc_residual_bits_per_sample+0.5) : 0; /* 0.5 is for rounding */ rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */ - if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + if(rice_parameter >= rice_parameter_limit) { #ifdef DEBUG_VERBOSE - fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); + fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, rice_parameter_limit - 1); #endif - rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; + rice_parameter = rice_parameter_limit - 1; } if(encoder->protected_->do_qlp_coeff_prec_search) { min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION; @@ -3363,6 +3371,7 @@ FLAC__bool process_subframe_( lpc_order, qlp_coeff_precision, rice_parameter, + rice_parameter_limit, min_partition_order, max_partition_order, encoder->protected_->do_escape_coding, @@ -3502,6 +3511,7 @@ unsigned evaluate_fixed_subframe_( unsigned subframe_bps, unsigned order, unsigned rice_parameter, + unsigned rice_parameter_limit, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool do_escape_coding, @@ -3530,12 +3540,13 @@ unsigned evaluate_fixed_subframe_( residual_samples, order, rice_parameter, + rice_parameter_limit, min_partition_order, max_partition_order, subframe_bps, do_escape_coding, rice_parameter_search_dist, - &subframe->data.fixed.entropy_coding_method.data.partitioned_rice + &subframe->data.fixed.entropy_coding_method ); subframe->data.fixed.order = order; @@ -3564,6 +3575,7 @@ unsigned evaluate_lpc_subframe_( unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, + unsigned rice_parameter_limit, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool do_escape_coding, @@ -3611,12 +3623,13 @@ unsigned evaluate_lpc_subframe_( residual_samples, order, rice_parameter, + rice_parameter_limit, min_partition_order, max_partition_order, subframe_bps, do_escape_coding, rice_parameter_search_dist, - &subframe->data.lpc.entropy_coding_method.data.partitioned_rice + &subframe->data.lpc.entropy_coding_method ); subframe->data.lpc.order = order; @@ -3669,16 +3682,18 @@ unsigned find_best_partition_order_( unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, + unsigned rice_parameter_limit, unsigned min_partition_order, unsigned max_partition_order, unsigned bps, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, - FLAC__EntropyCodingMethod_PartitionedRice *best_partitioned_rice + FLAC__EntropyCodingMethod *best_ecm ) { unsigned residual_bits, best_residual_bits = 0; unsigned best_parameters_index = 0; + unsigned best_partition_order = 0; const unsigned blocksize = residual_samples + predictor_order; max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(max_partition_order, blocksize, predictor_order); @@ -3704,6 +3719,7 @@ unsigned find_best_partition_order_( residual_samples, predictor_order, rice_parameter, + rice_parameter_limit, rice_parameter_search_dist, (unsigned)partition_order, do_escape_coding, @@ -3719,20 +3735,37 @@ unsigned find_best_partition_order_( if(best_residual_bits == 0 || residual_bits < best_residual_bits) { best_residual_bits = residual_bits; best_parameters_index = !best_parameters_index; - best_partitioned_rice->order = partition_order; + best_partition_order = partition_order; } } } - /* - * We are allowed to de-const the pointer based on our special knowledge; - * it is const to the outside world. - */ + best_ecm->data.partitioned_rice.order = best_partition_order; + { - FLAC__EntropyCodingMethod_PartitionedRiceContents* best_partitioned_rice_contents = (FLAC__EntropyCodingMethod_PartitionedRiceContents*)best_partitioned_rice->contents; - FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(best_partitioned_rice_contents, max(6, best_partitioned_rice->order)); - memcpy(best_partitioned_rice_contents->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, sizeof(unsigned)*(1<<(best_partitioned_rice->order))); - memcpy(best_partitioned_rice_contents->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(unsigned)*(1<<(best_partitioned_rice->order))); + /* + * We are allowed to de-const the pointer based on our special + * knowledge; it is const to the outside world. + */ + FLAC__EntropyCodingMethod_PartitionedRiceContents* prc = (FLAC__EntropyCodingMethod_PartitionedRiceContents*)best_ecm->data.partitioned_rice.contents; + unsigned partition; + + /* save best parameters and raw_bits */ + FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(prc, max(6, best_partition_order)); + memcpy(prc->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, sizeof(unsigned)*(1<<(best_partition_order))); + if(do_escape_coding) + memcpy(prc->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(unsigned)*(1<<(best_partition_order))); + /* + * Now need to check if the type should be changed to + * FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 based on the + * size of the rice parameters. + */ + for(partition = 0; partition < (1u<parameters[partition] >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + best_ecm->type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2; + break; + } + } } return best_residual_bits; @@ -3885,7 +3918,7 @@ static FLaC__INLINE unsigned count_rice_bits_in_partition_( ) { unsigned i, partition_bits = - FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + /* actually could end up being FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN but err on side of 16bps */ (1+rice_parameter) * partition_samples /* 1 for unary stop bit + rice_parameter for the binary portion */ ; for(i = 0; i < partition_samples; i++) @@ -3900,7 +3933,7 @@ static FLaC__INLINE unsigned count_rice_bits_in_partition_( ) { return - FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + /* actually could end up being FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN but err on side of 16bps */ (1+rice_parameter) * partition_samples + /* 1 for unary stop bit + rice_parameter for the binary portion */ ( rice_parameter? @@ -3927,6 +3960,7 @@ FLAC__bool set_partitioned_rice_( const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, + const unsigned rice_parameter_limit, const unsigned rice_parameter_search_dist, const unsigned partition_order, const FLAC__bool search_for_escapes, @@ -3944,7 +3978,8 @@ FLAC__bool set_partitioned_rice_( (void)rice_parameter_search_dist; #endif - FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER); + FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER); + FLAC__ASSERT(rice_parameter_limit <= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER); FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order)); parameters = partitioned_rice_contents->parameters; @@ -3959,11 +3994,11 @@ FLAC__bool set_partitioned_rice_( else min_rice_parameter = suggested_rice_parameter - rice_parameter_search_dist; max_rice_parameter = suggested_rice_parameter + rice_parameter_search_dist; - if(max_rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + if(max_rice_parameter >= rice_parameter_limit) { #ifdef DEBUG_VERBOSE - fprintf(stderr, "clipping rice_parameter (%u -> %u) @5\n", max_rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); + fprintf(stderr, "clipping rice_parameter (%u -> %u) @5\n", max_rice_parameter, rice_parameter_limit - 1); #endif - max_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; + max_rice_parameter = rice_parameter_limit - 1; } } else @@ -3986,12 +4021,14 @@ FLAC__bool set_partitioned_rice_( } #endif if(search_for_escapes) { - partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[0] * residual_samples; + partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[0] * residual_samples; if(partition_bits <= best_partition_bits) { raw_bits[0] = raw_bits_per_partition[0]; - best_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; + best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */ best_partition_bits = partition_bits; } + else + raw_bits[0] = 0; } parameters[0] = best_rice_parameter; bits_ += best_partition_bits; @@ -4020,11 +4057,11 @@ FLAC__bool set_partitioned_rice_( */ for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1) ; - if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + if(rice_parameter >= rice_parameter_limit) { #ifdef DEBUG_VERBOSE - fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); + fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1); #endif - rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; + rice_parameter = rice_parameter_limit - 1; } best_partition_bits = (unsigned)(-1); @@ -4035,11 +4072,11 @@ FLAC__bool set_partitioned_rice_( else min_rice_parameter = rice_parameter - rice_parameter_search_dist; max_rice_parameter = rice_parameter + rice_parameter_search_dist; - if(max_rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + if(max_rice_parameter >= rice_parameter_limit) { #ifdef DEBUG_VERBOSE - fprintf(stderr, "clipping rice_parameter (%u -> %u) @7\n", max_rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); + fprintf(stderr, "clipping rice_parameter (%u -> %u) @7\n", max_rice_parameter, rice_parameter_limit - 1); #endif - max_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; + max_rice_parameter = rice_parameter_limit - 1; } } else @@ -4060,12 +4097,14 @@ FLAC__bool set_partitioned_rice_( } #endif if(search_for_escapes) { - partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples; + partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples; if(partition_bits <= best_partition_bits) { raw_bits[partition] = raw_bits_per_partition[partition]; - best_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; + best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */ best_partition_bits = partition_bits; } + else + raw_bits[partition] = 0; } parameters[partition] = best_rice_parameter; bits_ += best_partition_bits; diff --git a/src/FLAC/src/libFLAC/stream_encoder_framing.c b/src/FLAC/src/libFLAC/stream_encoder_framing.c index 07e40f9c..1cb9cf60 100644 --- a/src/FLAC/src/libFLAC/stream_encoder_framing.c +++ b/src/FLAC/src/libFLAC/stream_encoder_framing.c @@ -45,7 +45,7 @@ #define max(x,y) ((x)>(y)?(x):(y)) static FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCodingMethod *method); -static FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order); +static FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order, const FLAC__bool is_extended); FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw) { @@ -229,7 +229,7 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_RESERVED_LEN)) return false; - if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN)) + if(!FLAC__bitwriter_write_raw_uint32(bw, (header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER)? 0 : 1, FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN)) return false; FLAC__ASSERT(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE); @@ -253,10 +253,8 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit default: if(header->blocksize <= 0x100) blocksize_hint = u = 6; - else if(header->blocksize <= 0x10000) - blocksize_hint = u = 7; else - u = 0; + blocksize_hint = u = 7; break; } if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BLOCK_SIZE_LEN)) @@ -265,14 +263,17 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit FLAC__ASSERT(FLAC__format_sample_rate_is_valid(header->sample_rate)); sample_rate_hint = 0; switch(header->sample_rate) { - case 8000: u = 4; break; - case 16000: u = 5; break; - case 22050: u = 6; break; - case 24000: u = 7; break; - case 32000: u = 8; break; - case 44100: u = 9; break; - case 48000: u = 10; break; - case 96000: u = 11; break; + case 88200: u = 1; break; + case 176400: u = 2; break; + case 192000: u = 3; break; + case 8000: u = 4; break; + case 16000: u = 5; break; + case 22050: u = 6; break; + case 24000: u = 7; break; + case 32000: u = 8; break; + case 44100: u = 9; break; + case 48000: u = 10; break; + case 96000: u = 11; break; default: if(header->sample_rate <= 255000 && header->sample_rate % 1000 == 0) sample_rate_hint = u = 12; @@ -325,9 +326,14 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_ZERO_PAD_LEN)) return false; - FLAC__ASSERT(header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER); - if(!FLAC__bitwriter_write_utf8_uint32(bw, header->number.frame_number)) - return false; + if(header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) { + if(!FLAC__bitwriter_write_utf8_uint32(bw, header->number.frame_number)) + return false; + } + else { + if(!FLAC__bitwriter_write_utf8_uint64(bw, header->number.sample_number)) + return false; + } if(blocksize_hint) if(!FLAC__bitwriter_write_raw_uint32(bw, header->blocksize-1, (blocksize_hint==6)? 8:16)) @@ -388,7 +394,17 @@ FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsign return false; switch(subframe->entropy_coding_method.type) { case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: - if(!add_residual_partitioned_rice_(bw, subframe->residual, residual_samples, subframe->order, subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, subframe->entropy_coding_method.data.partitioned_rice.order)) + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if(!add_residual_partitioned_rice_( + bw, + subframe->residual, + residual_samples, + subframe->order, + subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, + subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, + subframe->entropy_coding_method.data.partitioned_rice.order, + /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 + )) return false; break; default: @@ -424,7 +440,17 @@ FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned r return false; switch(subframe->entropy_coding_method.type) { case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: - if(!add_residual_partitioned_rice_(bw, subframe->residual, residual_samples, subframe->order, subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, subframe->entropy_coding_method.data.partitioned_rice.order)) + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: + if(!add_residual_partitioned_rice_( + bw, + subframe->residual, + residual_samples, + subframe->order, + subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, + subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, + subframe->entropy_coding_method.data.partitioned_rice.order, + /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 + )) return false; break; default: @@ -458,6 +484,7 @@ FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCo return false; switch(method->type) { case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: + case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: if(!FLAC__bitwriter_write_raw_uint32(bw, method->data.partitioned_rice.order, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) return false; break; @@ -467,18 +494,24 @@ FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCo return true; } -FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order) +FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order, const FLAC__bool is_extended) { + const unsigned plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; + const unsigned pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; + if(partition_order == 0) { unsigned i; - if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)) - return false; - if(rice_parameters[0] < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { + if(raw_bits[0] == 0) { + if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[0], plen)) + return false; if(!FLAC__bitwriter_write_rice_signed_block(bw, residual, residual_samples, rice_parameters[0])) return false; } else { + FLAC__ASSERT(rice_parameters[0] == 0); + if(!FLAC__bitwriter_write_raw_uint32(bw, pesc, plen)) + return false; if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) return false; for(i = 0; i < residual_samples; i++) { @@ -493,17 +526,19 @@ FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 unsigned partition_samples; const unsigned default_partition_samples = (residual_samples+predictor_order) >> partition_order; for(i = 0; i < (1u< -#endif - -#include -#include -#include -#include -#include -#include - -static int execit(char *prog, char *args); -static int forkit(char *prog, char *args); - -int main(int argc, char *argv[]) -{ - int flac_return_val = 0, opt_arg = 1, from_arg = -1, to_arg = -1, flac_level = 5, i; - char prog[MAX_PATH], cmdline[MAX_PATH*2], from[MAX_PATH], to[MAX_PATH], macdir[MAX_PATH], options[256], *p; - enum { WAVPACK, RKAU, SHORTEN } codec; - - /* get the directory where MAC external codecs reside */ - if(0 != (p = strrchr(argv[0],'\\'))) { - strcpy(macdir, argv[0]); - *(strrchr(macdir,'\\')+1) = '\0'; - } - else { - strcpy(macdir, ""); - } - - /* determine which codec we were called as and parse the options */ - if(p == 0) - p = argv[0]; - else - p++; - if(0 == strnicmp(p, "short", 5)) { - codec = SHORTEN; - } - else if(0 == strnicmp(p, "rkau", 4)) { - codec = RKAU; - if(argv[1][0] == '-' && argv[1][1] == 'l') { - opt_arg = 2; - switch(argv[1][2]) { - case '1': flac_level = 1; break; - case '2': flac_level = 5; break; - case '3': flac_level = 8; break; - } - } - } - else if(0 == strnicmp(p, "wavpack", 7)) { - codec = WAVPACK; - if(argv[1][0] == '-') { - opt_arg = 2; - switch(argv[1][1]) { - case 'f': flac_level = 1; break; - case 'h': flac_level = 8; break; - default: opt_arg = 1; - } - } - } - else { - return -5; - } - - /* figure out which arguments are the source and destination files */ - for(i = 1; i < argc; i++) - if(argv[i][0] != '-') { - from_arg = i++; - break; - } - for( ; i < argc; i++) - if(argv[i][0] != '-') { - to_arg = i++; - break; - } - if(to_arg < 0) - return -4; - - /* build the command to call flac with */ - sprintf(prog, "%sflac.exe", macdir); - sprintf(options, "-%d", flac_level); - for(i = opt_arg; i < argc; i++) - if(argv[i][0] == '-') { - strcat(options, " "); - strcat(options, argv[i]); - } - sprintf(cmdline, "\"%s\" %s -o \"%s\" \"%s\"", prog, options, argv[to_arg], argv[from_arg]); - - flac_return_val = execit(prog, cmdline); - - /* - * Now that flac has finished, we need to fork a process that will rename - * the resulting file with the correct extension once MAC has moved it to - * it's final resting place. - */ - if(0 == flac_return_val) { - /* get the destination directory, if any */ - if(0 != (p = strchr(argv[to_arg],'\\'))) { - strcpy(from, argv[to_arg]); - *(strrchr(from,'\\')+1) = '\0'; - } - else { - strcpy(from, ""); - } - - /* for the full 'from' and 'to' paths for the renamer process */ - p = strrchr(argv[from_arg],'\\'); - strcat(from, p? p+1 : argv[from_arg]); - strcpy(to, from); - if(0 == strchr(from,'.')) - return -3; - switch(codec) { - case SHORTEN: strcpy(strrchr(from,'.'), ".shn"); break; - case WAVPACK: strcpy(strrchr(from,'.'), ".wv"); break; - case RKAU: strcpy(strrchr(from,'.'), ".rka"); break; - } - strcpy(strrchr(to,'.'), ".flac"); - - sprintf(prog, "%sflac_ren.exe", macdir); - sprintf(cmdline, "\"%s\" \"%s\" \"%s\"", prog, from, to); - - flac_return_val = forkit(prog, cmdline); - } - - return flac_return_val; -} - -int execit(char *prog, char *args) -{ - BOOL ok; - STARTUPINFO startup_info; - PROCESS_INFORMATION proc_info; - - GetStartupInfo(&startup_info); - - ok = CreateProcess( - prog, - args, - 0, /*process security attributes*/ - 0, /*thread security attributes*/ - FALSE, - 0, /*dwCreationFlags*/ - 0, /*environment*/ - 0, /*lpCurrentDirectory*/ - &startup_info, - &proc_info - ); - if(ok) { - DWORD dw; - dw = WaitForSingleObject(proc_info.hProcess, INFINITE); - ok = (dw != 0xFFFFFFFF); - CloseHandle(proc_info.hThread); - CloseHandle(proc_info.hProcess); - } - - return ok? 0 : -1; -} - -int forkit(char *prog, char *args) -{ - BOOL ok; - STARTUPINFO startup_info; - PROCESS_INFORMATION proc_info; - - GetStartupInfo(&startup_info); - - ok = CreateProcess( - prog, - args, - 0, /*process security attributes*/ - 0, /*thread security attributes*/ - FALSE, - DETACHED_PROCESS, /*dwCreationFlags*/ - 0, /*environment*/ - 0, /*lpCurrentDirectory*/ - &startup_info, - &proc_info - ); - if(ok) { - CloseHandle(proc_info.hThread); - CloseHandle(proc_info.hProcess); - } - - return ok? 0 : -2; -} diff --git a/src/FLAC/src/monkeys_audio_utilities/flac_ren/Makefile.am b/src/FLAC/src/monkeys_audio_utilities/flac_ren/Makefile.am deleted file mode 100644 index 57c6a7c5..00000000 --- a/src/FLAC/src/monkeys_audio_utilities/flac_ren/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -# flac_ren - renamer part of utility to add FLAC support to Monkey's Audio -# Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -EXTRA_DIST = \ - main.c diff --git a/src/FLAC/src/monkeys_audio_utilities/flac_ren/main.c b/src/FLAC/src/monkeys_audio_utilities/flac_ren/main.c deleted file mode 100644 index fa849836..00000000 --- a/src/FLAC/src/monkeys_audio_utilities/flac_ren/main.c +++ /dev/null @@ -1,39 +0,0 @@ -/* flac_ren - renamer part of utility to add FLAC support to Monkey's Audio - * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include - -int main(int argc, char *argv[]) -{ - struct stat s; - - /* wait till the 'from' file has reached its final destination */ - do { - Sleep(2000); - } while(stat(argv[1], &s) < 0); - - /* now rename it */ - return rename(argv[1], argv[2]); -} diff --git a/src/FLAC/src/share/grabbag/cuesheet.c b/src/FLAC/src/share/grabbag/cuesheet.c index a30fa033..1220b74b 100644 --- a/src/FLAC/src/share/grabbag/cuesheet.c +++ b/src/FLAC/src/share/grabbag/cuesheet.c @@ -398,9 +398,21 @@ static FLAC__bool local__cuesheet_parse_(FILE *file, const char **error_message, *error_message = "TRACK number must be greater than 0"; return false; } - if(is_cdda && in_track_num > 99) { - *error_message = "CD-DA TRACK number must be between 1 and 99, inclusive"; - return false; + if(is_cdda) { + if(in_track_num > 99) { + *error_message = "CD-DA TRACK number must be between 1 and 99, inclusive"; + return false; + } + } + else { + if(in_track_num == 255) { + *error_message = "TRACK number 255 is reserved for the lead-out"; + return false; + } + else if(in_track_num > 255) { + *error_message = "TRACK number must be between 1 and 254, inclusive"; + return false; + } } if(is_cdda && cs->num_tracks > 0 && in_track_num != cs->tracks[cs->num_tracks-1].number + 1) { *error_message = "CD-DA TRACK numbers must be sequential"; @@ -503,7 +515,7 @@ static FLAC__bool local__cuesheet_parse_(FILE *file, const char **error_message, } if(!has_forced_leadout) { - forced_leadout_track_num = is_cdda? 170 : cs->num_tracks; + forced_leadout_track_num = is_cdda? 170 : 255; forced_leadout_track_offset = lead_out_offset; } if(!FLAC__metadata_object_cuesheet_insert_blank_track(cuesheet, cs->num_tracks)) { diff --git a/src/FLAC/src/share/grabbag/file.c b/src/FLAC/src/share/grabbag/file.c index a481f743..d073c4bf 100644 --- a/src/FLAC/src/share/grabbag/file.c +++ b/src/FLAC/src/share/grabbag/file.c @@ -42,8 +42,8 @@ #include /* for strrchr() */ #if defined _WIN32 && !defined __CYGWIN__ // for GetFileInformationByHandle() etc -#include -#include +#include +#include #endif #include "share/grabbag.h" diff --git a/src/FLAC/src/share/grabbag/picture.c b/src/FLAC/src/share/grabbag/picture.c index 68e1f51d..d3e0e180 100644 --- a/src/FLAC/src/share/grabbag/picture.c +++ b/src/FLAC/src/share/grabbag/picture.c @@ -20,6 +20,7 @@ # include #endif +#include "share/alloc.h" #include "share/grabbag.h" #include "FLAC/assert.h" #include @@ -29,7 +30,7 @@ /* slightly different that strndup(): this always copies 'size' bytes starting from s into a NUL-terminated string. */ static char *local__strndup_(const char *s, size_t size) { - char *x = (char*)malloc(size+1); + char *x = (char*)safe_malloc_add_2op_(size, /*+*/1); if(x) { memcpy(x, s, size); x[size] = '\0'; @@ -357,7 +358,7 @@ FLAC__StreamMetadata *grabbag__picture_parse_specification(const char *spec, con if(size < 0) *error_message = error_messages[5]; else { - FLAC__byte *buffer = (FLAC__byte*)malloc(size); + FLAC__byte *buffer = (FLAC__byte*)safe_malloc_(size); if(0 == buffer) *error_message = error_messages[0]; else { diff --git a/src/FLAC/src/share/utf8/charset.c b/src/FLAC/src/share/utf8/charset.c index 1610ad22..5bff506c 100644 --- a/src/FLAC/src/share/utf8/charset.c +++ b/src/FLAC/src/share/utf8/charset.c @@ -35,6 +35,7 @@ #include +#include "alloc.h" #include "charset.h" #include "charmaps.h" @@ -493,7 +494,7 @@ int charset_convert(const char *fromcode, const char *tocode, if (!charset1 || !charset2 ) return -1; - tobuf = (char *)malloc(fromlen * charset2->max + 1); + tobuf = (char *)safe_malloc_mul2add_(fromlen, /*times*/charset2->max, /*+*/1); if (!tobuf) return -2; diff --git a/src/FLAC/src/share/utf8/iconvert.c b/src/FLAC/src/share/utf8/iconvert.c index 37f16a89..f0311ee0 100644 --- a/src/FLAC/src/share/utf8/iconvert.c +++ b/src/FLAC/src/share/utf8/iconvert.c @@ -29,6 +29,7 @@ #include #include "iconvert.h" +#include "share/alloc.h" /* * Convert data from one encoding to another. Return: @@ -81,7 +82,7 @@ int iconvert(const char *fromcode, const char *tocode, * This is deliberately not a config option as people often * change their iconv library without rebuilding applications. */ - tocode1 = (char *)malloc(strlen(tocode) + 11); + tocode1 = (char *)safe_malloc_add_2op_(strlen(tocode), /*+*/11); if (!tocode1) goto fail; @@ -119,6 +120,8 @@ int iconvert(const char *fromcode, const char *tocode, break; if (obl < 6) { /* Enlarge the buffer */ + if(utflen*2 < utflen) /* overflow check */ + goto fail; utflen *= 2; newbuf = (char *)realloc(utfbuf, utflen); if (!newbuf) @@ -145,7 +148,7 @@ int iconvert(const char *fromcode, const char *tocode, iconv_close(cd1); return ret; } - newbuf = (char *)realloc(utfbuf, (ob - utfbuf) + 1); + newbuf = (char *)safe_realloc_add_2op_(utfbuf, (ob - utfbuf), /*+*/1); if (!newbuf) goto fail; ob = (ob - utfbuf) + newbuf; @@ -196,7 +199,7 @@ int iconvert(const char *fromcode, const char *tocode, outlen += ob - tbuf; /* Convert from UTF-8 for real */ - outbuf = (char *)malloc(outlen + 1); + outbuf = (char *)safe_malloc_add_2op_(outlen, /*+*/1); if (!outbuf) goto fail; ib = utfbuf; diff --git a/src/FLAC/src/share/utf8/utf8.c b/src/FLAC/src/share/utf8/utf8.c index f2bf5704..867511da 100644 --- a/src/FLAC/src/share/utf8/utf8.c +++ b/src/FLAC/src/share/utf8/utf8.c @@ -2,6 +2,8 @@ * Copyright (C) 2001 Peter Harris * Copyright (C) 2001 Edmund Grimley Evans * + * Buffer overflow checking added: Josh Coalson, 9/9/2007 + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -28,6 +30,7 @@ #include #include +#include "alloc.h" #include "utf8.h" #include "charset.h" @@ -43,7 +46,8 @@ static unsigned char *make_utf8_string(const wchar_t *unicode) { - int size = 0, index = 0, out_index = 0; + size_t size = 0, n; + int index = 0, out_index = 0; unsigned char *out; unsigned short c; @@ -51,16 +55,19 @@ static unsigned char *make_utf8_string(const wchar_t *unicode) c = unicode[index++]; while(c) { if(c < 0x0080) { - size += 1; + n = 1; } else if(c < 0x0800) { - size += 2; + n = 2; } else { - size += 3; + n = 3; } + if(size+n < size) /* overflow check */ + return NULL; + size += n; c = unicode[index++]; - } + } - out = malloc(size + 1); + out = safe_malloc_add_2op_(size, /*+*/1); if (out == NULL) return NULL; index = 0; @@ -87,7 +94,8 @@ static unsigned char *make_utf8_string(const wchar_t *unicode) static wchar_t *make_unicode_string(const unsigned char *utf8) { - int size = 0, index = 0, out_index = 0; + size_t size = 0; + int index = 0, out_index = 0; wchar_t *out; unsigned char c; @@ -101,11 +109,15 @@ static wchar_t *make_unicode_string(const unsigned char *utf8) } else { index += 1; } - size += 1; + if(size + 1 == 0) /* overflow check */ + return NULL; + size++; c = utf8[index++]; - } + } - out = malloc((size + 1) * sizeof(wchar_t)); + if(size + 1 == 0) /* overflow check */ + return NULL; + out = safe_malloc_mul_2op_(size+1, /*times*/sizeof(wchar_t)); if (out == NULL) return NULL; index = 0; @@ -147,7 +159,10 @@ int utf8_encode(const char *from, char **to) return -1; } - unicode = calloc(wchars + 1, sizeof(unsigned short)); + if(wchars < 0) /* underflow check */ + return -1; + + unicode = safe_calloc_((size_t)wchars + 1, sizeof(unsigned short)); if(unicode == NULL) { fprintf(stderr, "Out of memory processing string to UTF8\n"); @@ -190,6 +205,9 @@ int utf8_decode(const char *from, char **to) chars = WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); + if(chars < 0) /* underflow check */ + return -1; + if(chars == 0) { fprintf(stderr, "Unicode translation error %d\n", GetLastError()); @@ -197,7 +215,7 @@ int utf8_decode(const char *from, char **to) return -1; } - *to = calloc(chars + 1, sizeof(unsigned char)); + *to = safe_calloc_((size_t)chars + 1, sizeof(unsigned char)); if(*to == NULL) { fprintf(stderr, "Out of memory processing string to local charset\n"); @@ -277,7 +295,7 @@ static int convert_string(const char *fromcode, const char *tocode, if (ret != -1) return ret; - s = malloc(fromlen + 1); + s = safe_malloc_add_2op_(fromlen, /*+*/1); if (!s) return -1; strcpy(s, from); diff --git a/src/FLAC/src/test_libFLAC/decoders.c b/src/FLAC/src/test_libFLAC/decoders.c index 9e77caca..1d731cd4 100644 --- a/src/FLAC/src/test_libFLAC/decoders.c +++ b/src/FLAC/src/test_libFLAC/decoders.c @@ -66,7 +66,7 @@ static off_t flacfilesize_; static const char *flacfilename(FLAC__bool is_ogg) { - return is_ogg? "metadata.ogg" : "metadata.flac"; + return is_ogg? "metadata.oga" : "metadata.flac"; } static FLAC__bool die_(const char *msg) diff --git a/src/FLAC/src/test_libFLAC/encoders.c b/src/FLAC/src/test_libFLAC/encoders.c index c1de7ba3..5927cb83 100644 --- a/src/FLAC/src/test_libFLAC/encoders.c +++ b/src/FLAC/src/test_libFLAC/encoders.c @@ -51,7 +51,7 @@ static const unsigned num_metadata_ = sizeof(metadata_sequence_) / sizeof(metada static const char *flacfilename(FLAC__bool is_ogg) { - return is_ogg? "metadata.ogg" : "metadata.flac"; + return is_ogg? "metadata.oga" : "metadata.flac"; } static FLAC__bool die_(const char *msg) diff --git a/src/FLAC/src/test_libFLAC/metadata_manip.c b/src/FLAC/src/test_libFLAC/metadata_manip.c index 5f00b8cc..b3875318 100644 --- a/src/FLAC/src/test_libFLAC/metadata_manip.c +++ b/src/FLAC/src/test_libFLAC/metadata_manip.c @@ -73,7 +73,7 @@ static unsigned mc_our_block_number_ = 0; static const char *flacfilename(FLAC__bool is_ogg) { - return is_ogg? "metadata.ogg" : "metadata.flac"; + return is_ogg? "metadata.oga" : "metadata.flac"; } static FLAC__bool die_(const char *msg) @@ -315,7 +315,7 @@ static FLAC__bool write_chain_(FLAC__Metadata_Chain *chain, FLAC__bool use_paddi if(FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) { struct stat stats; - FILE *file, *tempfile; + FILE *file, *tempfile = 0; char *tempfilename; if(preserve_file_stats) { if(!get_file_stats_(filename, &stats)) diff --git a/src/FLAC/src/test_seeking/main.c b/src/FLAC/src/test_seeking/main.c index 6bcd58db..2559b89a 100644 --- a/src/FLAC/src/test_seeking/main.c +++ b/src/FLAC/src/test_seeking/main.c @@ -75,6 +75,21 @@ static FLAC__bool die_s_(const char *msg, const FLAC__StreamDecoder *decoder) return false; } +static unsigned local_rand_(void) +{ +#if !defined _MSC_VER && !defined __MINGW32__ +#define RNDFUNC random +#else +#define RNDFUNC rand +#endif + /* every RAND_MAX I've ever seen is 2^15-1 or 2^31-1, so a little hackery here: */ + if (RAND_MAX > 32767) + return RNDFUNC(); + else /* usually MSVC, some solaris */ + return (RNDFUNC()<<15) | RNDFUNC(); +#undef RNDFUNC +} + static off_t get_filesize_(const char *srcpath) { struct stat srcstat; @@ -88,7 +103,7 @@ static off_t get_filesize_(const char *srcpath) static FLAC__bool read_pcm_(FLAC__int32 *pcm[], const char *rawfilename, const char *flacfilename) { FILE *f; - unsigned channels, bps = 0, samples, i, j; + unsigned channels = 0, bps = 0, samples, i, j; off_t rawfilesize = get_filesize_(rawfilename); if (rawfilesize < 0) { @@ -298,12 +313,6 @@ static FLAC__bool seek_barrage(FLAC__bool is_ogg, const char *filename, off_t fi printf("file's total_samples is %I64u\n", decoder_client_data.total_samples); #else printf("file's total_samples is %llu\n", (unsigned long long)decoder_client_data.total_samples); -#endif -#if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__ - if (decoder_client_data.total_samples > (FLAC__uint64)RAND_MAX) { - printf("ERROR: must be total_samples < %u\n", (unsigned)RAND_MAX); - return false; - } #endif n = (long int)decoder_client_data.total_samples; @@ -315,10 +324,6 @@ static FLAC__bool seek_barrage(FLAC__bool is_ogg, const char *filename, off_t fi if(n == 0) { /* 8 would imply no compression, 9 guarantees that we will get some samples off the end of the stream to test that case */ n = 9 * filesize / (decoder_client_data.channels * decoder_client_data.bits_per_sample); -#if !defined _MSC_VER && !defined __MINGW32__ - if(n > RAND_MAX) - n = RAND_MAX; -#endif } printf("Begin seek barrage, count=%u\n", count); @@ -339,12 +344,7 @@ static FLAC__bool seek_barrage(FLAC__bool is_ogg, const char *filename, off_t fi pos = n + (i-20); } else { -#if !defined _MSC_VER && !defined __MINGW32__ - pos = (FLAC__uint64)(random() % n); -#else - /* RAND_MAX is only 32767 in my MSVC */ - pos = (FLAC__uint64)((rand()<<15|rand()) % n); -#endif + pos = (FLAC__uint64)(local_rand_() % n); } #ifdef _MSC_VER @@ -386,6 +386,7 @@ static FLAC__bool seek_barrage(FLAC__bool is_ogg, const char *filename, off_t fi printf("OK\n"); fflush(stdout); } + stop_signal_ = false; if(FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_UNINITIALIZED) { if(!FLAC__stream_decoder_finish(decoder)) @@ -480,7 +481,7 @@ int main(int argc, char *argv[]) /* no need to do "decode all" read_mode if PCM checking is available */ if (rawfilename && read_mode > 1) continue; - if (strlen(flacfilename) > 4 && 0 == strcmp(flacfilename+strlen(flacfilename)-4, ".ogg")) { + if (strlen(flacfilename) > 4 && (0 == strcmp(flacfilename+strlen(flacfilename)-4, ".oga") || 0 == strcmp(flacfilename+strlen(flacfilename)-4, ".ogg"))) { #if FLAC__HAS_OGG ok = seek_barrage(/*is_ogg=*/true, flacfilename, flacfilesize, count, samples, read_mode, rawfilename? pcm : 0); #else diff --git a/src/FLAC/src/test_streams/main.c b/src/FLAC/src/test_streams/main.c index f3f14ecf..c335776d 100644 --- a/src/FLAC/src/test_streams/main.c +++ b/src/FLAC/src/test_streams/main.c @@ -36,12 +36,6 @@ #define M_PI 3.14159265358979323846 #endif -#if defined _WIN32 || defined __EMX__ - static const char *mode = "wb"; -#else - static const char *mode = "w"; -#endif - #if !defined _MSC_VER && !defined __MINGW32__ #define GET_RANDOM_BYTE (((unsigned)random()) & 0xff) #else @@ -211,7 +205,7 @@ static FLAC__bool generate_01(void) FILE *f; FLAC__int16 x = -32768; - if(0 == (f = fopen("test01.raw", mode))) + if(0 == (f = fopen("test01.raw", "wb"))) return false; if(!write_little_endian_int16(f, x)) @@ -230,7 +224,7 @@ static FLAC__bool generate_02(void) FILE *f; FLAC__int16 xl = -32768, xr = 32767; - if(0 == (f = fopen("test02.raw", mode))) + if(0 == (f = fopen("test02.raw", "wb"))) return false; if(!write_little_endian_int16(f, xl)) @@ -252,7 +246,7 @@ static FLAC__bool generate_03(void) FLAC__int16 x[] = { -25, 0, 25, 50, 100 }; unsigned i; - if(0 == (f = fopen("test03.raw", mode))) + if(0 == (f = fopen("test03.raw", "wb"))) return false; for(i = 0; i < 5; i++) @@ -273,7 +267,7 @@ static FLAC__bool generate_04(void) FLAC__int16 x[] = { -25, 500, 0, 400, 25, 300, 50, 200, 100, 100 }; unsigned i; - if(0 == (f = fopen("test04.raw", mode))) + if(0 == (f = fopen("test04.raw", "wb"))) return false; for(i = 0; i < 10; i++) @@ -295,7 +289,7 @@ static FLAC__bool generate_fsd8(const char *fn, const int pattern[], unsigned re FLAC__ASSERT(pattern != 0); - if(0 == (f = fopen(fn, mode))) + if(0 == (f = fopen(fn, "wb"))) return false; for(rep = 0; rep < reps; rep++) { @@ -321,7 +315,7 @@ static FLAC__bool generate_fsd16(const char *fn, const int pattern[], unsigned r FLAC__ASSERT(pattern != 0); - if(0 == (f = fopen(fn, mode))) + if(0 == (f = fopen(fn, "wb"))) return false; for(rep = 0; rep < reps; rep++) { @@ -345,7 +339,7 @@ static FLAC__bool generate_wbps16(const char *fn, unsigned samples) FILE *f; unsigned sample; - if(0 == (f = fopen(fn, mode))) + if(0 == (f = fopen(fn, "wb"))) return false; for(sample = 0; sample < samples; sample++) { @@ -372,7 +366,7 @@ static FLAC__bool generate_fsd24(const char *fn, const int pattern[], unsigned r FLAC__ASSERT(pattern != 0); - if(0 == (f = fopen(fn, mode))) + if(0 == (f = fopen(fn, "wb"))) return false; for(rep = 0; rep < reps; rep++) { @@ -400,7 +394,7 @@ static FLAC__bool generate_sine8_1(const char *fn, const double sample_rate, con double theta1, theta2; unsigned i; - if(0 == (f = fopen(fn, mode))) + if(0 == (f = fopen(fn, "wb"))) return false; for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) { @@ -427,7 +421,7 @@ static FLAC__bool generate_sine8_2(const char *fn, const double sample_rate, con double theta1, theta2; unsigned i; - if(0 == (f = fopen(fn, mode))) + if(0 == (f = fopen(fn, "wb"))) return false; for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) { @@ -458,7 +452,7 @@ static FLAC__bool generate_sine16_1(const char *fn, const double sample_rate, co double theta1, theta2; unsigned i; - if(0 == (f = fopen(fn, mode))) + if(0 == (f = fopen(fn, "wb"))) return false; for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) { @@ -485,7 +479,7 @@ static FLAC__bool generate_sine16_2(const char *fn, const double sample_rate, co double theta1, theta2; unsigned i; - if(0 == (f = fopen(fn, mode))) + if(0 == (f = fopen(fn, "wb"))) return false; for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) { @@ -516,7 +510,7 @@ static FLAC__bool generate_sine24_1(const char *fn, const double sample_rate, co double theta1, theta2; unsigned i; - if(0 == (f = fopen(fn, mode))) + if(0 == (f = fopen(fn, "wb"))) return false; for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) { @@ -543,7 +537,7 @@ static FLAC__bool generate_sine24_2(const char *fn, const double sample_rate, co double theta1, theta2; unsigned i; - if(0 == (f = fopen(fn, mode))) + if(0 == (f = fopen(fn, "wb"))) return false; for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) { @@ -569,7 +563,7 @@ static FLAC__bool generate_noise(const char *fn, unsigned bytes) FILE *f; unsigned b; - if(0 == (f = fopen(fn, mode))) + if(0 == (f = fopen(fn, "wb"))) return false; for(b = 0; b < bytes; b++) { @@ -599,7 +593,7 @@ static FLAC__bool generate_raw(const char *filename, unsigned channels, unsigned FILE *f; unsigned i, j; - if(0 == (f = fopen(filename, mode))) + if(0 == (f = fopen(filename, "wb"))) return false; for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) { @@ -632,7 +626,7 @@ static FLAC__bool generate_aiff(const char *filename, unsigned sample_rate, unsi FILE *f; unsigned i, j; - if(0 == (f = fopen(filename, mode))) + if(0 == (f = fopen(filename, "wb"))) return false; if(fwrite("FORM", 1, 4, f) < 4) goto foo; @@ -693,7 +687,7 @@ static FLAC__bool generate_wav(const char *filename, unsigned sample_rate, unsig FILE *f; unsigned i, j; - if(0 == (f = fopen(filename, mode))) + if(0 == (f = fopen(filename, "wb"))) return false; if(fwrite("RIFF", 1, 4, f) < 4) goto foo; @@ -768,14 +762,14 @@ static FLAC__bool generate_wackywavs(void) 4, 0, 0, 0, 'b', 'l', 'a', 'h' }; - if(0 == (f = fopen("wacky1.wav", mode))) + if(0 == (f = fopen("wacky1.wav", "wb"))) return false; if(fwrite(wav, 1, 84, f) < 84) goto foo; fclose(f); wav[4] += 12; - if(0 == (f = fopen("wacky2.wav", mode))) + if(0 == (f = fopen("wacky2.wav", "wb"))) return false; if(fwrite(wav, 1, 96, f) < 96) goto foo; diff --git a/src/OGG/framing.c b/src/OGG/framing.c index 871d6917..0595b955 100644 --- a/src/OGG/framing.c +++ b/src/OGG/framing.c @@ -5,14 +5,14 @@ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * * by the Xiph.Org Foundation http://www.xiph.org/ * * * ******************************************************************** function: code raw [Vorbis] packets into framed OggSquish stream and decode Ogg streams back into raw packets - last mod: $Id: framing.c 9601 2005-07-23 00:19:14Z giles $ + last mod: $Id: framing.c 12446 2007-02-08 22:22:43Z xiphmont $ note: The CRC code is directly derived from public domain code by Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html @@ -268,8 +268,12 @@ void ogg_page_checksum_set(ogg_page *og){ } /* submit data to the internal buffer of the framing engine */ -int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){ - int lacing_vals=op->bytes/255+1,i; +int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count, + long e_o_s, ogg_int64_t granulepos){ + + int bytes = 0, lacing_vals, i; + for (i = 0; i < count; ++i) bytes += (int)iov[i].iov_len; + lacing_vals=bytes/255+1; if(os->body_returned){ /* advance packet data according to the body_returned pointer. We @@ -284,7 +288,7 @@ int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){ } /* make sure we have the buffer storage */ - _os_body_expand(os,op->bytes); + _os_body_expand(os,bytes); _os_lacing_expand(os,lacing_vals); /* Copy in the submitted packet. Yes, the copy is a waste; this is @@ -292,16 +296,18 @@ int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){ will actually be fairly easy to eliminate the extra copy in the future */ - memcpy(os->body_data+os->body_fill,op->packet,op->bytes); - os->body_fill+=op->bytes; + for (i = 0; i < count; ++i) { + memcpy(os->body_data+os->body_fill, iov[i].iov_base, iov[i].iov_len); + os->body_fill += (int)iov[i].iov_len; + } /* Store lacing vals for this packet */ for(i=0;ilacing_vals[os->lacing_fill+i]=255; os->granule_vals[os->lacing_fill+i]=os->granulepos; } - os->lacing_vals[os->lacing_fill+i]=(op->bytes)%255; - os->granulepos=os->granule_vals[os->lacing_fill+i]=op->granulepos; + os->lacing_vals[os->lacing_fill+i]=bytes%255; + os->granulepos=os->granule_vals[os->lacing_fill+i]=granulepos; /* flag the first segment as the beginning of the packet */ os->lacing_vals[os->lacing_fill]|= 0x100; @@ -311,11 +317,18 @@ int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){ /* for the sake of completeness */ os->packetno++; - if(op->e_o_s)os->e_o_s=1; + if(e_o_s)os->e_o_s=1; return(0); } +int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){ + ogg_iovec_t iov; + iov.iov_base = op->packet; + iov.iov_len = op->bytes; + return ogg_stream_iovecin(os, &iov, 1, op->e_o_s, op->granulepos); +} + /* This will flush remaining packets into a page (returning nonzero), even if there is not enough data to trigger a flush normally (undersized page). If there are no packets or partial packets to @@ -624,7 +637,7 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){ if(!next) next=oy->data+oy->fill; - oy->returned=next-oy->data; + oy->returned=(int)(next-oy->data); return(-(next-outerpage)); } diff --git a/src/OGG/include/ogg/ogg.h b/src/OGG/include/ogg/ogg.h index 9082679d..1558290c 100644 --- a/src/OGG/include/ogg/ogg.h +++ b/src/OGG/include/ogg/ogg.h @@ -5,13 +5,13 @@ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * * by the Xiph.Org Foundation http://www.xiph.org/ * * * ******************************************************************** function: toplevel libogg include - last mod: $Id: ogg.h 7188 2004-07-20 07:26:04Z xiphmont $ + last mod: $Id: ogg.h 12446 2007-02-08 22:22:43Z xiphmont $ ********************************************************************/ #ifndef _OGG_H @@ -23,6 +23,11 @@ extern "C" { #include +typedef struct { + void *iov_base; + size_t iov_len; +} ogg_iovec_t; + typedef struct { long endbyte; int endbit; @@ -148,6 +153,8 @@ extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); /* Ogg BITSTREAM PRIMITIVES: encoding **************************/ extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); +extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, + int count, long e_o_s, ogg_int64_t granulepos); extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); diff --git a/src/OGG/include/ogg/os_types.h b/src/OGG/include/ogg/os_types.h index 32dcb8bf..8b7be672 100644 --- a/src/OGG/include/ogg/os_types.h +++ b/src/OGG/include/ogg/os_types.h @@ -11,7 +11,7 @@ ******************************************************************** function: #ifdef jail to whip a few platforms into the UNIX ideal. - last mod: $Id: os_types.h 7524 2004-08-11 04:20:36Z conrad $ + last mod: $Id: os_types.h 11511 2006-06-03 22:30:13Z giles $ ********************************************************************/ #ifndef _OS_TYPES_H @@ -27,19 +27,20 @@ #if defined(_WIN32) # if defined(__CYGWIN__) -# include <_G_config.h> - typedef _G_int64_t ogg_int64_t; - typedef _G_int32_t ogg_int32_t; - typedef _G_uint32_t ogg_uint32_t; - typedef _G_int16_t ogg_int16_t; - typedef _G_uint16_t ogg_uint16_t; +# include + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + typedef uint64_t ogg_uint64_t; # elif defined(__MINGW32__) - typedef short ogg_int16_t; - typedef unsigned short ogg_uint16_t; - typedef int ogg_int32_t; - typedef unsigned int ogg_uint32_t; - typedef long long ogg_int64_t; - typedef unsigned long long ogg_uint64_t; + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; # elif defined(__MWERKS__) typedef long long ogg_int64_t; typedef int ogg_int32_t; diff --git a/src/aiff.c b/src/aiff.c index 63484772..81991b8f 100644 --- a/src/aiff.c +++ b/src/aiff.c @@ -849,6 +849,14 @@ aiff_read_comm_chunk (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt) psf_binheader_readf (psf, "E242b", &(comm_fmt->numChannels), &(comm_fmt->numSampleFrames), &(comm_fmt->sampleSize), &(comm_fmt->sampleRate), SIGNED_SIZEOF (comm_fmt->sampleRate)) ; + if (comm_fmt->size > 0x10000 && (comm_fmt->size & 0xffff) == 0) + { psf_log_printf (psf, " COMM : %d (0x%x) *** should be ", comm_fmt->size, comm_fmt->size) ; + comm_fmt->size = ENDSWAP_INT (comm_fmt->size) ; + psf_log_printf (psf, "%d (0x%x)\n", comm_fmt->size, comm_fmt->size) ; + } + else + psf_log_printf (psf, " COMM : %d\n", comm_fmt->size) ; + if (comm_fmt->size == SIZEOF_AIFF_COMM) comm_fmt->encoding = NONE_MARKER ; else if (comm_fmt->size == SIZEOF_AIFC_COMM_MIN) @@ -865,7 +873,6 @@ aiff_read_comm_chunk (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt) psf->u.scbuf [encoding_len] = 0 ; } ; - psf_log_printf (psf, " COMM : %d\n", comm_fmt->size) ; psf_log_printf (psf, " Sample Rate : %d\n", tenbytefloat2int (comm_fmt->sampleRate)) ; psf_log_printf (psf, " Frames : %u%s\n", comm_fmt->numSampleFrames, (comm_fmt->numSampleFrames == 0 && psf->filelength > 104) ? " (Should not be 0)" : "") ; psf_log_printf (psf, " Channels : %d\n", comm_fmt->numChannels) ; diff --git a/src/au.c b/src/au.c index 3a5f93bd..e5dac5fe 100644 --- a/src/au.c +++ b/src/au.c @@ -435,7 +435,12 @@ au_read_header (SF_PRIVATE *psf) } ; psf_log_printf (psf, " Sample Rate : %d\n", au_fmt.samplerate) ; - psf_log_printf (psf, " Channels : %d\n", au_fmt.channels) ; + if (au_fmt.channels < 1) + { psf_log_printf (psf, " Channels : %d **** should be >= 1\n", au_fmt.channels) ; + return SFE_CHANNEL_COUNT_ZERO ; + } + else + psf_log_printf (psf, " Channels : %d\n", au_fmt.channels) ; psf->blockwidth = psf->sf.channels * psf->bytewidth ; diff --git a/src/common.h b/src/common.h index 11c907ac..775010fc 100644 --- a/src/common.h +++ b/src/common.h @@ -413,6 +413,7 @@ enum SFE_INTERNAL, SFE_BAD_CONTROL_CMD, SFE_BAD_ENDIAN, + SFE_CHANNEL_COUNT_ZERO, SFE_CHANNEL_COUNT, SFE_BAD_RDWR_FORMAT, @@ -523,12 +524,10 @@ enum SFE_MAT4_BAD_NAME, SFE_MAT4_NO_SAMPLERATE, - SFE_MAT4_ZERO_CHANNELS, SFE_MAT5_BAD_ENDIAN, SFE_MAT5_NO_BLOCK, SFE_MAT5_SAMPLE_RATE, - SFE_MAT5_ZERO_CHANNELS, SFE_PVF_NO_PVF1, SFE_PVF_BAD_HEADER, diff --git a/src/create_symbols_file.py b/src/create_symbols_file.py index 8d60df81..27e78f54 100755 --- a/src/create_symbols_file.py +++ b/src/create_symbols_file.py @@ -69,7 +69,6 @@ ALL_SYMBOLS = ( ( "sf_strerror", 50 ), ( "sf_get_string", 60 ), ( "sf_set_string", 61 ), - ( "sf_get_info", 68 ), ( "sf_open_fd", 70 ), ( "sf_open_virtual", 80 ), ( "sf_write_sync", 90 ) diff --git a/src/flac.c b/src/flac.c index 7771e55b..45310b8c 100644 --- a/src/flac.c +++ b/src/flac.c @@ -40,8 +40,7 @@ ** Private static functions. */ -#define ENC_BUFFER_SIZE 4096 -#define RBUFFER_LEN 4096 +#define ENC_BUFFER_SIZE 8192 typedef enum { PFLAC_PCM_SHORT = 50, @@ -170,6 +169,17 @@ flac_buffer_copy (SF_PRIVATE *psf) const FLAC__int32* const *buffer = pflac->wbuffer ; unsigned i = 0, j, offset ; + /* + ** frame->header.blocksize is variable and we're using a constant blocksize + ** of FLAC__MAX_BLOCK_SIZE. + ** Check our assumptions here. + */ + if (frame->header.blocksize > FLAC__MAX_BLOCK_SIZE) + { psf_log_printf (psf, "Ooops : frame->header.blocksize (%d) > FLAC__MAX_BLOCK_SIZE (%d)\n", __func__, __LINE__, frame->header.blocksize, FLAC__MAX_BLOCK_SIZE) ; + psf->error = SFE_INTERNAL ; + return 0 ; + } ; + if (pflac->ptr == NULL) { /* ** Not sure why this code is here and not elsewhere. @@ -177,17 +187,9 @@ flac_buffer_copy (SF_PRIVATE *psf) */ pflac->bufferbackup = SF_TRUE ; for (i = 0 ; i < frame->header.channels ; i++) - { /* - ** frame->header.blocksize is variable so don't use it, use a - ** constant and check it. - */ - if (frame->header.blocksize > RBUFFER_LEN) - { psf_log_printf (psf, "%s %d : frame->header.blocksize > RBUFFER_LEN\n", __func__, __LINE__) ; - return 0 ; - } ; - + { if (pflac->rbuffer [i] == NULL) - pflac->rbuffer [i] = calloc (RBUFFER_LEN, sizeof (FLAC__int32)) ; + pflac->rbuffer [i] = calloc (FLAC__MAX_BLOCK_SIZE, sizeof (FLAC__int32)) ; memcpy (pflac->rbuffer [i], buffer [i], frame->header.blocksize * sizeof (FLAC__int32)) ; } ; diff --git a/src/mat4.c b/src/mat4.c index 3ead0328..f85f96de 100644 --- a/src/mat4.c +++ b/src/mat4.c @@ -276,7 +276,7 @@ mat4_read_header (SF_PRIVATE *psf) if (rows == 0 && cols == 0) { psf_log_printf (psf, "*** Error : zero channel count.\n") ; - return SFE_MAT4_ZERO_CHANNELS ; + return SFE_CHANNEL_COUNT_ZERO ; } ; psf->sf.channels = rows ; diff --git a/src/mat5.c b/src/mat5.c index ecd0039e..b4de610e 100644 --- a/src/mat5.c +++ b/src/mat5.c @@ -448,7 +448,7 @@ mat5_read_header (SF_PRIVATE *psf) if (rows == 0 && cols == 0) { psf_log_printf (psf, "*** Error : zero channel count.\n") ; - return SFE_MAT5_ZERO_CHANNELS ; + return SFE_CHANNEL_COUNT_ZERO ; } ; psf->sf.channels = rows ; diff --git a/src/sndfile.c b/src/sndfile.c index 2b34754f..9e372d54 100644 --- a/src/sndfile.c +++ b/src/sndfile.c @@ -96,6 +96,7 @@ ErrorStruct SndfileErrors [] = { SFE_INTERNAL , "Unspecified internal error." }, { SFE_BAD_CONTROL_CMD , "Bad command passed to function sf_command()." }, { SFE_BAD_ENDIAN , "Bad endian-ness. Try default endian-ness" }, + { SFE_CHANNEL_COUNT_ZERO , "Channel count is zero." }, { SFE_CHANNEL_COUNT , "Too many channels specified." }, { SFE_BAD_SEEK , "Internal psf_fseek() failed." }, @@ -207,12 +208,10 @@ ErrorStruct SndfileErrors [] = { SFE_MAT4_BAD_NAME , "Error in MAT4 file. No variable name." }, { SFE_MAT4_NO_SAMPLERATE , "Error in MAT4 file. No sample rate." }, - { SFE_MAT4_ZERO_CHANNELS , "Error in MAT4 file. Channel count is zero." }, { SFE_MAT5_BAD_ENDIAN , "Error in MAT5 file. Not able to determine endian-ness." }, { SFE_MAT5_NO_BLOCK , "Error in MAT5 file. Bad block structure." }, { SFE_MAT5_SAMPLE_RATE , "Error in MAT5 file. Not able to determine sample rate." }, - { SFE_MAT5_ZERO_CHANNELS , "Error in MAT5 file. Channel count is zero." }, { SFE_PVF_NO_PVF1 , "Error in PVF file. No PVF1 marker." }, { SFE_PVF_BAD_HEADER , "Error in PVF file. Bad header." }, @@ -859,6 +858,12 @@ sf_command (SNDFILE *sndfile, int command, void *data, int datasize) psf->norm_float = (datasize) ? SF_TRUE : SF_FALSE ; return old_value ; + case SFC_GET_CURRENT_SF_INFO : + if (data == NULL || datasize != SIGNED_SIZEOF (SF_INFO)) + return (sf_errno = SFE_BAD_CONTROL_CMD) ; + memcpy (data, &psf->sf, sizeof (SF_INFO)) ; + break ; + case SFC_SET_NORM_DOUBLE : old_value = psf->norm_double ; psf->norm_double = (datasize) ? SF_TRUE : SF_FALSE ; @@ -1240,23 +1245,6 @@ sf_seek (SNDFILE *sndfile, sf_count_t offset, int whence) /*------------------------------------------------------------------------------ */ -int -sf_get_info (SNDFILE * sndfile, SF_INFO * info) -{ SF_PRIVATE *psf ; - - if (info == NULL) - return SF_FALSE ; - if ((psf = (SF_PRIVATE*) sndfile) == NULL) - return SF_FALSE ; - if (psf->Magick != SNDFILE_MAGICK) - return SF_FALSE ; - - /* Need to correct psf->sf.frames ???? */ - memcpy (info, &psf->sf, sizeof (SF_INFO)) ; - - return SF_TRUE ; -} /* sf_get_info */ - const char* sf_get_string (SNDFILE *sndfile, int str_type) { SF_PRIVATE *psf ; diff --git a/src/sndfile.h.in b/src/sndfile.h.in index 6a130139..8ccb0045 100644 --- a/src/sndfile.h.in +++ b/src/sndfile.h.in @@ -30,14 +30,7 @@ #define SNDFILE_1 #include - -/* For the Metrowerks CodeWarrior Pro Compiler (mainly MacOS) */ - -#if (defined (__MWERKS__)) -#include -#else -#include -#endif +#include #ifdef __cplusplus extern "C" { @@ -128,6 +121,8 @@ enum enum { SFC_GET_LIB_VERSION = 0x1000, SFC_GET_LOG_INFO = 0x1001, + SFC_GET_CURRENT_SF_INFO = 0x1002, + SFC_GET_NORM_DOUBLE = 0x1010, SFC_GET_NORM_FLOAT = 0x1011, @@ -290,14 +285,20 @@ enum typedef struct SNDFILE_tag SNDFILE ; -/* The following typedef is system specific and is defined when libsndfile is. -** compiled. sf_count_t can be one of loff_t (Linux), off_t (*BSD), -** off64_t (Solaris), __int64_t (Win32) etc. +/* The following typedef is system specific and is defined when libsndfile is +** compiled. sf_count_t can be one of loff_t (Linux), off_t (*BSD), off64_t +** (Solaris), __int64_t (Win32) etc. On windows, we need to allow the same +** header file to be compiler by both GCC and the microsoft compiler. */ +#ifdef _MSCVER +typedef __int64_t sf_count_t ; +#define SF_COUNT_MAX 0x7fffffffffffffffi64 +#else typedef @TYPEOF_SF_COUNT_T@ sf_count_t ; - #define SF_COUNT_MAX @SF_COUNT_MAX@ +#endif + /* A pointer to a SF_INFO structure is passed to sf_open_read () and filled in. ** On write, the SF_INFO structure is filled in by the user and passed into @@ -521,12 +522,6 @@ int sf_format_check (const SF_INFO *info) ; sf_count_t sf_seek (SNDFILE *sndfile, sf_count_t frames, int whence) ; -/* Retrieve the SF_INFO struct for the given SNDFILE. Returns SF_FALSE on -** failure, SF_TRUE otherwise. -*/ - -int sf_get_info (SNDFILE * sndfile, SF_INFO * info) ; - /* Functions for retrieving and setting string data within sound files. ** Not all file types support this features; AIFF and WAV do. For both ** functions, the str_type parameter must be one of the SF_STR_* values diff --git a/src/voc.c b/src/voc.c index de7abf2f..6948a236 100644 --- a/src/voc.c +++ b/src/voc.c @@ -199,20 +199,26 @@ voc_read_header (SF_PRIVATE *psf) psf->endian = SF_ENDIAN_LITTLE ; while (1) - { offset += psf_binheader_readf (psf, "1", &block_type) ; + { int size ; + short count ; + + block_type = 0 ; + offset += psf_binheader_readf (psf, "1", &block_type) ; switch (block_type) { case VOC_ASCII : - { int size ; + offset += psf_binheader_readf (psf, "e3", &size) ; - offset += psf_binheader_readf (psf, "e3", &size) ; + psf_log_printf (psf, " ASCII : %d\n", size) ; - psf_log_printf (psf, " ASCII : %d\n", size) ; + offset += psf_binheader_readf (psf, "b", psf->header, size) ; + psf->header [size] = 0 ; + psf_log_printf (psf, " text : %s\n", psf->header) ; + continue ; - offset += psf_binheader_readf (psf, "b", psf->header, size) ; - psf->header [size] = 0 ; - psf_log_printf (psf, " text : %s\n", psf->header) ; - } ; + case VOC_REPEAT : + offset += psf_binheader_readf (psf, "e32", &size, &count) ; + psf_log_printf (psf, " Repeat : %d\n", count) ; continue ; case VOC_SOUND_DATA : @@ -242,7 +248,7 @@ voc_read_header (SF_PRIVATE *psf) psf_log_printf (psf, "offset: %d size: %d sum: %d filelength: %D\n", offset, size, offset + size, psf->filelength) ; return SFE_VOC_BAD_SECTIONS ; } - else if (offset + size - 1 < psf->filelength) + else if (psf->filelength - offset - size > 4) { psf_log_printf (psf, "Seems to be a multi-segment file (#1).\n") ; psf_log_printf (psf, "offset: %d size: %d sum: %d filelength: %D\n", offset, size, offset + size, psf->filelength) ; return SFE_VOC_BAD_SECTIONS ; @@ -869,10 +875,3 @@ BLOCK 9 - data block that supersedes blocks 1 and 8. Data is stored left, right ------------------------------------------------------------------------*/ -/* -** Do not edit or modify anything in this comment block. -** The arch-tag line is a file identity tag for the GNU Arch -** revision control system. -** -** arch-tag: 40a50167-a81c-463a-9e1d-3282ff84e09d -*/ diff --git a/src/w64.c b/src/w64.c index 1fd7ddea..73ab00d3 100644 --- a/src/w64.c +++ b/src/w64.c @@ -226,7 +226,7 @@ w64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock) bytesread += psf_binheader_readf (psf, "e8", &chunk_size) ; - if (psf->filelength < chunk_size) + if (psf->filelength != chunk_size) psf_log_printf (psf, "riff : %D (should be %D)\n", chunk_size, psf->filelength) ; else psf_log_printf (psf, "riff : %D\n", chunk_size) ; @@ -399,7 +399,7 @@ w64_write_header (SF_PRIVATE *psf, int calc_length) psf_fseek (psf, 0, SEEK_SET) ; /* riff marker, length, wave and 'fmt ' markers. */ - psf_binheader_writef (psf, "eh8hh", riff_MARKER16, psf->filelength - 8, wave_MARKER16, fmt_MARKER16) ; + psf_binheader_writef (psf, "eh8hh", riff_MARKER16, psf->filelength, wave_MARKER16, fmt_MARKER16) ; subformat = psf->sf.format & SF_FORMAT_SUBMASK ; diff --git a/src/wav.c b/src/wav.c index 01d97dbe..cbe48b3a 100644 --- a/src/wav.c +++ b/src/wav.c @@ -65,6 +65,15 @@ #define elmo_MARKER (MAKE_MARKER ('e', 'l', 'm', 'o')) #define cart_MARKER (MAKE_MARKER ('c', 'a', 'r', 't')) +#define exif_MARKER (MAKE_MARKER ('e', 'x', 'i', 'f')) +#define ever_MARKER (MAKE_MARKER ('e', 'v', 'e', 'r')) +#define etim_MARKER (MAKE_MARKER ('e', 't', 'i', 'm')) +#define ecor_MARKER (MAKE_MARKER ('e', 'c', 'o', 'r')) +#define emdl_MARKER (MAKE_MARKER ('e', 'm', 'd', 'l')) +#define emnt_MARKER (MAKE_MARKER ('e', 'm', 'n', 't')) +#define erel_MARKER (MAKE_MARKER ('e', 'r', 'e', 'l')) +#define eucm_MARKER (MAKE_MARKER ('e', 'u', 'c', 'm')) + #define ISFT_MARKER (MAKE_MARKER ('I', 'S', 'F', 'T')) #define ICRD_MARKER (MAKE_MARKER ('I', 'C', 'R', 'D')) #define ICOP_MARKER (MAKE_MARKER ('I', 'C', 'O', 'P')) @@ -155,6 +164,7 @@ static int wav_command (SF_PRIVATE *psf, int command, void *data, int datasize) static int wav_close (SF_PRIVATE *psf) ; static int wav_subchunk_parse (SF_PRIVATE *psf, int chunk) ; +static int exif_subchunk_parse (SF_PRIVATE *psf, unsigned int length) ; static int wav_read_smpl_chunk (SF_PRIVATE *psf, unsigned int chunklen) ; static int wav_read_acid_chunk (SF_PRIVATE *psf, unsigned int chunklen) ; static int wav_read_bext_chunk (SF_PRIVATE *psf, unsigned int chunklen) ; @@ -1286,7 +1296,7 @@ wav_subchunk_parse (SF_PRIVATE *psf, int chunk) psf_log_printf (psf, " %M\n", chunk) ; break ; - case data_MARKER: + case data_MARKER : psf_log_printf (psf, " %M inside a LIST block??? Backing out.\n", chunk) ; /* Jump back four bytes and return to caller. */ psf_binheader_readf (psf, "j", -4) ; @@ -1353,6 +1363,11 @@ wav_subchunk_parse (SF_PRIVATE *psf, int chunk) psf_log_printf (psf, " %M : %d\n", chunk, dword) ; break ; + case exif_MARKER : + psf_log_printf (psf, " %M\n", chunk) ; + bytesread += exif_subchunk_parse (psf, length - bytesread) ; + break ; + default : psf_binheader_readf (psf, "4", &dword) ; bytesread += sizeof (dword) ; @@ -1598,7 +1613,7 @@ wav_read_acid_chunk (SF_PRIVATE *psf, unsigned int chunklen) return 0 ; } /* wav_read_acid_chunk */ -int +static int wav_read_bext_chunk (SF_PRIVATE *psf, unsigned int chunksize) { SF_BROADCAST_INFO* b ; @@ -1667,10 +1682,81 @@ wav_write_bext_chunk (SF_PRIVATE *psf) return 0 ; } /* wav_write_bext_chunk */ +static int +exif_fill_and_sink (SF_PRIVATE *psf, char* buf, size_t bufsz, size_t toread) +{ + size_t bytesread = 0 ; + + buf [0] = 0 ; + bufsz -= 1 ; + if (toread < bufsz) + bufsz = toread ; + bytesread = psf_binheader_readf (psf, "b", buf, bufsz) ; + buf [bufsz] = 0 ; + + if (bytesread == bufsz && toread > bufsz) + bytesread += psf_binheader_readf (psf, "j", toread - bufsz) ; + + return bytesread ; +} /* exif_fill_and_sink */ + /* -** Do not edit or modify anything in this comment block. -** The arch-tag line is a file identity tag for the GNU Arch -** revision control system. -** -** arch-tag: 9c551689-a1d8-4905-9f56-26a204374f18 +** Exif specification for audio files, at JEITA CP-3451 Exif 2.2 section 5 +** (Exif Audio File Specification) http://www.exif.org/Exif2-2.PDF */ +static int +exif_subchunk_parse (SF_PRIVATE *psf, unsigned int length) +{ + unsigned marker, dword, vmajor = -1, vminor = -1, bytesread = 0 ; + char buf [4096] ; + + while (bytesread < length) + { + bytesread += psf_binheader_readf (psf, "m", &marker) ; + + switch (marker) + { + case 0 : /* camera padding? */ + break ; + + case ever_MARKER : + bytesread += psf_binheader_readf (psf, "j4", 4, &dword) ; + vmajor = 10 * (((dword >> 24) & 0xff) - '0') + (((dword >> 16) & 0xff) - '0') ; + vminor = 10 * (((dword >> 8) & 0xff) - '0') + ((dword & 0xff) - '0') ; + psf_log_printf (psf, " EXIF Version : %u.%02u\n", vmajor, vminor) ; + break ; + + case emnt_MARKER : /* design information: null-terminated string */ + case emdl_MARKER : /* model name ; null-terminated string */ + case ecor_MARKER : /* manufacturer: null-terminated string */ + case etim_MARKER : /* creation time: null-terminated string in the format "hour:minute:second.subsecond" */ + case erel_MARKER : /* relation info: null-terminated string (filename) */ + case eucm_MARKER : /* user comment: 4-byte size follows, then possibly unicode data */ + psf_binheader_readf (psf, "4", &dword) ; + bytesread += sizeof (dword) ; + dword += (dword & 1) ; + + bytesread += exif_fill_and_sink (psf, buf, sizeof (buf), dword) ; + + /* BAD - don't know what's going on here -- maybe a bug in the camera */ + /* field should be NULL-terminated but there's no room for it with the reported number */ + /* example output: emdl : 8 (EX-Z1050) */ + if (marker == emdl_MARKER && dword == strlen (buf) /* should be >= strlen+1*/) + { psf_log_printf (psf, " *** field size too small for string (sinking 2 bytes)\n") ; + bytesread += psf_binheader_readf (psf, "j", 2) ; + } ; + + psf_log_printf (psf, " %M : %d (%s)\n", marker, dword, buf) ; + if (dword > length) + return bytesread ; + break ; + + default : + psf_log_printf (psf, " *** %M (%d): -- ignored --\n", marker, marker) ; + break ; + } ; + } ; + + return bytesread ; +} /* exif_subchunk_parse */ + diff --git a/tests/benchmark-1.0.18pre16-hendrix b/tests/benchmark-1.0.18pre16-hendrix new file mode 100644 index 00000000..951bc56d --- /dev/null +++ b/tests/benchmark-1.0.18pre16-hendrix @@ -0,0 +1,38 @@ +Benchmarking libsndfile-1.0.18pre15 +----------------------------------- +Each test takes a little over 5 seconds. + + Raw write PCM_16 : 103189885 samples per sec + Raw read PCM_16 : 660854036 samples per sec + +Native endian I/O : + Write short to PCM_16 : 95.08% of raw write + Read short from PCM_16 : 96.39% of raw read + Write int to PCM_24 : 54.55% of raw write + Read int from PCM_24 : 28.50% of raw read + Write int to PCM_32 : 46.97% of raw write + Read int from PCM_32 : 39.98% of raw read + Write float to PCM_16 : 60.85% of raw write + Read float from PCM_16 : 27.79% of raw read + Write float to PCM_24 : 46.23% of raw write + Read float from PCM_24 : 22.62% of raw read + Write float to PCM_32 : 35.38% of raw write + Read float from PCM_32 : 24.18% of raw read + Write float to FLOAT : 47.73% of raw write + Read float from FLOAT : 40.62% of raw read + +Endian swapped I/O : + Write short to PCM_16 : 79.98% of raw write + Read short from PCM_16 : 49.27% of raw read + Write int to PCM_24 : 53.80% of raw write + Read int from PCM_24 : 28.50% of raw read + Write int to PCM_32 : 41.68% of raw write + Read int from PCM_32 : 25.89% of raw read + Write float to PCM_16 : 61.03% of raw write + Read float from PCM_16 : 27.74% of raw read + Write float to PCM_24 : 45.10% of raw write + Read float from PCM_24 : 22.43% of raw read + Write float to PCM_32 : 35.24% of raw write + Read float from PCM_32 : 22.37% of raw read + Write float to FLOAT : 42.01% of raw write + Read float from FLOAT : 28.98% of raw read diff --git a/tests/benchmark-1.0.18pre16-mingus b/tests/benchmark-1.0.18pre16-mingus new file mode 100644 index 00000000..fa0584e1 --- /dev/null +++ b/tests/benchmark-1.0.18pre16-mingus @@ -0,0 +1,38 @@ +Benchmarking libsndfile-1.0.18pre15 +----------------------------------- +Each test takes a little over 5 seconds. + + Raw write PCM_16 : 178237074 samples per sec + Raw read PCM_16 : 368885269 samples per sec + +Native endian I/O : + Write short to PCM_16 : 98.84% of raw write + Read short from PCM_16 : 147.10% of raw read + Write int to PCM_24 : 33.74% of raw write + Read int from PCM_24 : 30.82% of raw read + Write int to PCM_32 : 48.34% of raw write + Read int from PCM_32 : 62.43% of raw read + Write float to PCM_16 : 41.86% of raw write + Read float from PCM_16 : 36.73% of raw read + Write float to PCM_24 : 28.38% of raw write + Read float from PCM_24 : 19.50% of raw read + Write float to PCM_32 : 23.68% of raw write + Read float from PCM_32 : 28.76% of raw read + Write float to FLOAT : 47.21% of raw write + Read float from FLOAT : 60.85% of raw read + +Endian swapped I/O : + Write short to PCM_16 : 54.94% of raw write + Read short from PCM_16 : 59.03% of raw read + Write int to PCM_24 : 33.40% of raw write + Read int from PCM_24 : 31.98% of raw read + Write int to PCM_32 : 30.89% of raw write + Read int from PCM_32 : 33.68% of raw read + Write float to PCM_16 : 41.61% of raw write + Read float from PCM_16 : 26.76% of raw read + Write float to PCM_24 : 25.75% of raw write + Read float from PCM_24 : 19.84% of raw read + Write float to PCM_32 : 21.29% of raw write + Read float from PCM_32 : 21.78% of raw read + Write float to FLOAT : 30.82% of raw write + Read float from FLOAT : 35.04% of raw read diff --git a/tests/command_test.c b/tests/command_test.c index 357a713f..a687928b 100644 --- a/tests/command_test.c +++ b/tests/command_test.c @@ -36,14 +36,15 @@ #define BUFFER_LEN (1<<10) #define LOG_BUFFER_SIZE 1024 -static void float_norm_test (const char *filename) ; -static void double_norm_test (const char *filename) ; -static void format_tests (void) ; -static void calc_peak_test (int filetype, const char *filename) ; -static void truncate_test (const char *filename, int filetype) ; -static void instrument_test (const char *filename, int filetype) ; -static void channel_map_test (const char *filename, int filetype) ; -static void broadcast_test (const char *filename, int filetype) ; +static void float_norm_test (const char *filename) ; +static void double_norm_test (const char *filename) ; +static void format_tests (void) ; +static void calc_peak_test (int filetype, const char *filename) ; +static void truncate_test (const char *filename, int filetype) ; +static void instrument_test (const char *filename, int filetype) ; +static void channel_map_test (const char *filename, int filetype) ; +static void broadcast_test (const char *filename, int filetype) ; +static void current_sf_info_test (const char *filename) ; /* Force the start of this buffer to be double aligned. Sparc-solaris will ** choke if its not. @@ -130,6 +131,11 @@ main (int argc, char *argv []) test_count++ ; } ; + if (do_all || strcmp (argv [1], "current_sf_info") == 0) + { current_sf_info_test ("current.wav") ; + test_count++ ; + } ; + if (test_count == 0) { printf ("Mono : ************************************\n") ; printf ("Mono : * No '%s' test defined.\n", argv [1]) ; @@ -870,11 +876,52 @@ channel_map_test (const char *filename, int filetype) puts ("ok") ; } /* channel_map_test */ +static void +current_sf_info_test (const char *filename) +{ SNDFILE *outfile, *infile ; + SF_INFO outinfo, ininfo ; + sf_count_t last_count ; + + print_test_name ("current_sf_info_test", filename) ; + + outinfo.samplerate = 44100 ; + outinfo.format = (SF_FORMAT_WAV | SF_FORMAT_PCM_16) ; + outinfo.channels = 1 ; + outinfo.frames = 0 ; + + outfile = test_open_file_or_die (filename, SFM_WRITE, &outinfo, SF_TRUE, __LINE__) ; + sf_command (outfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, 0) ; + + exit_if_true (outinfo.frames != 0, + "\n\nLine %d : Initial sfinfo.frames is not zero.\n\n", __LINE__ + ) ; + + test_write_double_or_die (outfile, 0, double_data, BUFFER_LEN, __LINE__) ; + sf_command (outfile, SFC_GET_CURRENT_SF_INFO, &outinfo, sizeof (outinfo)) ; + + exit_if_true (outinfo.frames != BUFFER_LEN, + "\n\nLine %d : Initial sfinfo.frames (%ld) should be %d.\n\n", __LINE__, + SF_COUNT_TO_LONG (outinfo.frames), BUFFER_LEN + ) ; + + /* Read file making sure no channel map exists. */ + infile = test_open_file_or_die (filename, SFM_READ, &ininfo, SF_TRUE, __LINE__) ; + + last_count = ininfo.frames ; + + test_write_double_or_die (outfile, 0, double_data, BUFFER_LEN, __LINE__) ; + + sf_command (infile, SFC_GET_CURRENT_SF_INFO, &ininfo, sizeof (ininfo)) ; + + exit_if_true (ininfo.frames != BUFFER_LEN, + "\n\nLine %d : Initial sfinfo.frames (%ld) should be %d.\n\n", __LINE__, + SF_COUNT_TO_LONG (ininfo.frames), BUFFER_LEN + ) ; + + sf_close (outfile) ; + sf_close (infile) ; + + unlink (filename) ; + puts ("ok") ; +} /* current_sf_info_test */ -/* -** Do not edit or modify anything in this comment block. -** The following line is a file identity tag for the GNU Arch -** revision control system. -** -** arch-tag: 59e5d452-8dae-45aa-99aa-b78dc0deba1c -*/ diff --git a/tests/dft_cmp.c b/tests/dft_cmp.c index cf803385..09011d18 100644 --- a/tests/dft_cmp.c +++ b/tests/dft_cmp.c @@ -30,25 +30,49 @@ #define DFT_SPEC_LENGTH (DFT_DATA_LENGTH / 2) static void dft_magnitude (const double *data, double *spectrum) ; -static double calc_max_spectral_difference (double *spec1, double *spec2) ; +static double calc_max_spectral_difference (const double *spec1, const double *spec2) ; /*-------------------------------------------------------------------------------- ** Public functions. */ double -dft_cmp (int linenum, double *orig, double *test, int len, double target_snr, int allow_exit) +dft_cmp_float (int linenum, const float *in_data, const float *test_data, int len, double target_snr, int allow_exit) +{ static double orig [DFT_DATA_LENGTH] ; + static double test [DFT_DATA_LENGTH] ; + unsigned k ; + + if (! orig || ! test) + { printf ("Error (line %d) : dft_cmp_float : Bad input arrays.\n", linenum) ; + return 1 ; + } ; + + if (len != DFT_DATA_LENGTH) + { printf ("Error (line %d) : dft_cmp_float : Bad input array length.\n", linenum) ; + return 1 ; + } ; + + for (k = 0 ; k < ARRAY_LEN (orig) ; k++) + { test [k] = test_data [k] ; + orig [k] = in_data [k] ; + } ; + + return dft_cmp_double (linenum, orig, test, len, target_snr, allow_exit) ; +} /* dft_cmp_float */ + +double +dft_cmp_double (int linenum, const double *orig, const double *test, int len, double target_snr, int allow_exit) { static double orig_spec [DFT_SPEC_LENGTH] ; static double test_spec [DFT_SPEC_LENGTH] ; double snr ; if (! orig || ! test) - { printf ("Error (line % d) : dft_cmp : Bad input arrays.\n", linenum) ; + { printf ("Error (line %d) : dft_cmp_double : Bad input arrays.\n", linenum) ; return 1 ; } ; if (len != DFT_DATA_LENGTH) - { printf ("Error (line % d) : dft_cmp : Bad input array length.\n", linenum) ; + { printf ("Error (line %d) : dft_cmp_double : Bad input array length.\n", linenum) ; return 1 ; } ; @@ -68,7 +92,7 @@ dft_cmp (int linenum, double *orig, double *test, int len, double target_snr, in snr = -500.0 ; return snr ; -} /* dft_cmp */ +} /* dft_cmp_double */ /*-------------------------------------------------------------------------------- ** Quick dirty calculation of magnitude spectrum for real valued data using @@ -112,7 +136,7 @@ dft_magnitude (const double *data, double *spectrum) } /* dft_magnitude */ static double -calc_max_spectral_difference (double *orig, double *test) +calc_max_spectral_difference (const double *orig, const double *test) { double orig_max = 0.0, max_diff = 0.0 ; int k ; @@ -128,10 +152,3 @@ calc_max_spectral_difference (double *orig, double *test) return 20.0 * log10 (max_diff / orig_max) ; } /* calc_max_spectral_difference */ -/* -** Do not edit or modify anything in this comment block. -** The arch-tag line is a file identity tag for the GNU Arch -** revision control system. -** -** arch-tag: cba7ffe2-bafe-44bd-b57a-15def3408410 -*/ diff --git a/tests/dft_cmp.h b/tests/dft_cmp.h index 1fb63c5c..b3d4ca1c 100644 --- a/tests/dft_cmp.h +++ b/tests/dft_cmp.h @@ -1,30 +1,25 @@ /* ** Copyright (C) 2002-2004 Erik de Castro Lopo -** +** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. -** +** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. -** +** ** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software +** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define DFT_DATA_LENGTH (2048) -double dft_cmp (int linenum, double *orig, double *test, int len, double tolerance, int allow_exit) ; +double dft_cmp_float (int linenum, const float *orig, const float *test, int len, double tolerance, int allow_exit) ; + +double dft_cmp_double (int linenum, const double *orig, const double *test, int len, double tolerance, int allow_exit) ; -/* -** Do not edit or modify anything in this comment block. -** The arch-tag line is a file identity tag for the GNU Arch -** revision control system. -** -** arch-tag: 10eac7b2-04ef-4d86-b7c0-8f1de57b12a0 -*/ diff --git a/tests/floating_point_test.tpl b/tests/floating_point_test.tpl index 91ac68c7..16cedc07 100644 --- a/tests/floating_point_test.tpl +++ b/tests/floating_point_test.tpl @@ -40,15 +40,17 @@ static void float_scaled_test (const char *filename, int allow_exit, int replace_float, int filetype, double target_snr) ; static void double_scaled_test (const char *filename, int allow_exit, int replace_float, int filetype, double target_snr) ; -[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type +[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type +]static void [+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test (const char * filename) ; -[+ ENDFOR endian_type +][+ ENDFOR int_type +][+ ENDFOR float_type +[+ ENDFOR endian_type +][+ ENDFOR int_type +][+ ENDFOR float_type +] static double double_data [DFT_DATA_LENGTH] ; -static double test_data [DFT_DATA_LENGTH] ; +static double double_test [DFT_DATA_LENGTH] ; static float float_data [DFT_DATA_LENGTH] ; +static float float_test [DFT_DATA_LENGTH] ; + static double double_data [DFT_DATA_LENGTH] ; static short short_data [DFT_DATA_LENGTH] ; static int int_data [DFT_DATA_LENGTH] ; @@ -162,9 +164,9 @@ main (int argc, char *argv []) putchar ('\n') ; /* Float int tests. */ -[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type +[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type +] [+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test ("[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +].au") ; -[+ ENDFOR endian_type +][+ ENDFOR int_type +][+ ENDFOR float_type +[+ ENDFOR endian_type +][+ ENDFOR int_type +][+ ENDFOR float_type +] return 0 ; @@ -176,20 +178,13 @@ main (int argc, char *argv []) static void float_scaled_test (const char *filename, int allow_exit, int replace_float, int filetype, double target_snr) -{ static float float_orig [DFT_DATA_LENGTH] ; - static float float_test [DFT_DATA_LENGTH] ; - - SNDFILE *file ; +{ SNDFILE *file ; SF_INFO sfinfo ; - int k ; double snr ; print_test_name ("float_scaled_test", filename) ; - gen_windowed_sine_double (double_data, DFT_DATA_LENGTH, 1.0) ; - - for (k = 0 ; k < DFT_DATA_LENGTH ; k++) - float_orig [k] = double_data [k] ; + gen_windowed_sine_float (float_data, DFT_DATA_LENGTH, 1.0) ; sfinfo.samplerate = SAMPLE_RATE ; sfinfo.frames = DFT_DATA_LENGTH ; @@ -199,7 +194,7 @@ float_scaled_test (const char *filename, int allow_exit, int replace_float, int file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ; - test_write_float_or_die (file, 0, float_orig, DFT_DATA_LENGTH, __LINE__) ; + test_write_float_or_die (file, 0, float_data, DFT_DATA_LENGTH, __LINE__) ; sf_close (file) ; @@ -218,10 +213,7 @@ float_scaled_test (const char *filename, int allow_exit, int replace_float, int sf_close (file) ; - for (k = 0 ; k < DFT_DATA_LENGTH ; k++) - test_data [k] = float_test [k] ; - - snr = dft_cmp (__LINE__, double_data, test_data, DFT_DATA_LENGTH, target_snr, allow_exit) ; + snr = dft_cmp_float (__LINE__, float_data, float_test, DFT_DATA_LENGTH, target_snr, allow_exit) ; exit_if_true (snr > target_snr, "% 6.1fdB SNR\n\n Error : should be better than % 6.1fdB\n\n", snr, target_snr) ; @@ -254,7 +246,7 @@ double_scaled_test (const char *filename, int allow_exit, int replace_float, int sf_close (file) ; - memset (test_data, 0, sizeof (test_data)) ; + memset (double_test, 0, sizeof (double_test)) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ; @@ -265,11 +257,11 @@ double_scaled_test (const char *filename, int allow_exit, int replace_float, int check_log_buffer_or_die (file, __LINE__) ; - test_read_double_or_die (file, 0, test_data, DFT_DATA_LENGTH, __LINE__) ; + test_read_double_or_die (file, 0, double_test, DFT_DATA_LENGTH, __LINE__) ; sf_close (file) ; - snr = dft_cmp (__LINE__, double_data, test_data, DFT_DATA_LENGTH, target_snr, allow_exit) ; + snr = dft_cmp_double (__LINE__, double_data, double_test, DFT_DATA_LENGTH, target_snr, allow_exit) ; exit_if_true (snr > target_snr, "% 6.1fdB SNR\n\n Error : should be better than % 6.1fdB\n\n", snr, target_snr) ; @@ -283,7 +275,7 @@ double_scaled_test (const char *filename, int allow_exit, int replace_float, int /*============================================================================== */ -[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type +[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type +] static void [+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test (const char * filename) diff --git a/tests/utils.tpl b/tests/utils.tpl index d7228681..06f607e6 100644 --- a/tests/utils.tpl +++ b/tests/utils.tpl @@ -74,7 +74,7 @@ exit_if_true (int test, const char *format, ...) */ [+ FOR io_type -+]int oct_save_[+ (get "io_element") +] ([+ (get "io_element") +] *a, [+ (get "io_element") +] *b, int len) ; ++]int oct_save_[+ (get "io_element") +] (const [+ (get "io_element") +] *a, const [+ (get "io_element") +] *b, int len) ; [+ ENDFOR io_type +] @@ -261,7 +261,7 @@ static char octfilename [] = "error.dat" ; [+ FOR io_type +]int -oct_save_[+ (get "io_element") +] ([+ (get "io_element") +] *a, [+ (get "io_element") +] *b, int len) +oct_save_[+ (get "io_element") +] (const [+ (get "io_element") +] *a, const [+ (get "io_element") +] *b, int len) { FILE *file ; int k ;