Merge from -mdev branch.

This commit is contained in:
Erik de Castro Lopo 2007-10-21 20:28:27 +10:00
commit eda374c4c0
94 changed files with 3052 additions and 1555 deletions

View File

@ -18,13 +18,13 @@ Makefile
Makefile.in Makefile.in
aclocal.m4 aclocal.m4
autom4te.cache autom4te.cache
compile Cfg/compile
config.guess Cfg/config.guess
config.log config.log
config.status config.status
config.sub Cfg/config.sub
configure configure
depcomp Cfg/depcomp
doc/libsndfile.css doc/libsndfile.css
examples/cooledit-fixer examples/cooledit-fixer
examples/generate examples/generate
@ -35,12 +35,12 @@ examples/sndfile-convert
examples/sndfile-data-trim examples/sndfile-data-trim
examples/sndfile-info examples/sndfile-info
examples/sndfile-play examples/sndfile-play
install-sh Cfg/install-sh
libsndfile-1.0.*pre* libsndfile-1.0.*pre*
libsndfile.spec libsndfile.spec
libtool libtool
ltmain.sh Cfg/ltmain.sh
missing Cfg/missing
regtest/sndfile-regtest regtest/sndfile-regtest
sndfile.pc sndfile.pc
src/*sndfile.def src/*sndfile.def
@ -83,3 +83,4 @@ tests/utils.c
tests/utils.h tests/utils.h
tests/write_read_test.c tests/write_read_test.c
src/FLAC/src/test_libFLAC/matrix src/FLAC/src/test_libFLAC/matrix
*.oct

112
ChangeLog
View File

@ -1,3 +1,115 @@
2007-10-21 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* 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 <erikd AT mega-nerd DOT com>
* 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 <erikd AT mega-nerd DOT com>
* src/w64.c
Fix writing of 'riff' chunk length and check for correct value in parser.
2007-09-20 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* doc/index.html
Link to MP3 FAQ entry.
2007-09-18 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/flac.c
Move the blocksize check to an earlier stage of flac_buffer_copy.
2007-09-12 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/FLAC
Huge merge from FLAC upstream.
2007-09-10 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* examples/*.c
Change license to all example programs to BSD.
2007-09-08 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/FLAC/include/FLAC/metadata.h
Include <sys/types.h> 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 <erikd AT mega-nerd DOT com>
* Makefile.am M4/octave.m4
Fix build when Octave headers are not present.
2007-08-27 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* doc/development.html
Add note about bzr repository directory looking empty.
2007-08-26 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* 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 <erikd AT mega-nerd DOT com>
* acinclude.m4 configure.ac ...
Get rid of acinclude.m4 and replace it with an M4 directory.
2007-08-21 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* 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 <erikd AT mega-nerd DOT com>
* tests/dft_cmp.[ch] tests/floating_point_test.tpl
Clean up floating point tests.
2007-08-14 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/aiff.c
Fix segfault when COMM chunk length is byte swapped.
2007-08-09 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* 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 <erikd AT mega-nerd DOT com>
* src/voc.c
Fix bug in handling file supplied by Matt Olenik.
2007-07-31 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/OGG
Merge from OGG upstream sources.
2007-07-25 Erik de Castro Lopo <erikd AT mega-nerd DOT com> 2007-07-25 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/FLAC * src/FLAC

5
M4/Makefile.am Normal file
View File

@ -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

15
M4/add_cflags.m4 Normal file
View File

@ -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 <stdio.h>],
[puts("Hello, World!"); return 0;],
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no])
CFLAGS="$ac_add_cflags__old_cflags")
])
])# AC_ADD_CFLAGS

124
M4/clip_mode.m4 Normal file
View File

@ -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 <erikd AT mega-nerd DOT com>
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 <math.h>
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 <math.h>
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

159
M4/endian.m4 Normal file
View File

@ -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 <erikd AT mega-nerd DOT com>
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 <endian.h>.
dnl 2) If 1) fails, look in <sys/types.h> and <sys/param.h>.
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 <endian.h> which should set BYTE_ORDER.
[AC_TRY_LINK([
#include <endian.h>
#if BYTE_ORDER != LITTLE_ENDIAN
not big endian
#endif
], return 0 ;,
ac_cv_c_byte_order=little
)]
[AC_TRY_LINK([
#include <endian.h>
#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 <sys/types.h>
#include <sys/param.h>
#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
bogus endian macros
#endif
], return 0 ;,
[AC_TRY_LINK([
#include <sys/types.h>
#include <sys/param.h>
#if BYTE_ORDER != LITTLE_ENDIAN
not big endian
#endif
], return 0 ;,
ac_cv_c_byte_order=little
)]
[AC_TRY_LINK([
#include <sys/types.h>
#include <sys/param.h>
#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

114
M4/extra_largefile.m4 Normal file
View File

@ -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 <eggert@twinsun.com>.
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
])

32
M4/flexible_array.m4 Normal file
View File

@ -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 <erikd AT mega-nerd DOT com>
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 <stdlib.h>
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

38
M4/llrint.m4 Normal file
View File

@ -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 <erikd AT mega-nerd DOT com>
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 <math.h>
#include <stdint.h>
], 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

37
M4/lrint.m4 Normal file
View File

@ -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 <erikd AT mega-nerd DOT com>
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 <math.h>
], 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

37
M4/lrintf.m4 Normal file
View File

@ -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 <erikd AT mega-nerd DOT com>
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 <math.h>
], 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

37
M4/mkoctfile_version.m4 Normal file
View File

@ -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 <erikd AT mega-nerd DOT com>
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

156
M4/octave.m4 Normal file
View File

@ -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 <erikd AT mega-nerd DOT com>
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 <erikd AT mega-nerd DOT com>
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 <erikd AT mega-nerd DOT com>
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

View File

@ -1,11 +1,14 @@
## Process this file with automake to produce Makefile.in ## Process this file with automake to produce Makefile.in
SUBDIRS = man doc Win32 Octave src examples regtest tests if BUILD_OCTAVE_MOD
DIST_SUBDIRS = $(SUBDIRS) octave_dir = Octave
EXTRA_DIST = reconfigure.mk acinclude.m4 libsndfile.spec.in \ endif
sndfile.pc.in Mingw-make-dist.sh
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 pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = sndfile.pc pkgconfig_DATA = sndfile.pc
@ -19,9 +22,3 @@ genfiles :
(cd tests ; make 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

View File

@ -1,14 +1,79 @@
## Process this file with automake to produce Makefile.in ## 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 octconfigdir = $(exec_prefix)/share/octave/site/m
octconfig_DATA = sndfile_load.m sndfile_save.m sndfile_play.m octconfig_DATA = sndfile_load.m sndfile_save.m sndfile_play.m
## Do not edit or modify anything in this comment block. OCTAVE_DEST_MDIR = @OCTAVE_DEST_MDIR@
## The arch-tag line is a file identity tag for the GNU Arch OCTAVE_DEST_ODIR = @OCTAVE_DEST_ODIR@
## revision control system.
##
## arch-tag: 56f1645a-3a13-4846-acc7-8b4abf2904ff
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)

23
Octave/Readme.txt Normal file
View File

@ -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.

214
Octave/format.cc Normal file
View File

@ -0,0 +1,214 @@
/*
** Copyright (C) 2007 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** 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 <string>
#include <vector>
#include <cctype>
#include "sndfile.h"
#include "format.h"
static void
str_split (const std::string & str, const std::string & delim, std::vector <std::string> & 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 <std::string> 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 */

21
Octave/format.h Normal file
View File

@ -0,0 +1,21 @@
/*
** Copyright (C) 2007 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** 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) ;

56
Octave/octave_test.m Normal file
View File

@ -0,0 +1,56 @@
# Copyright (C) 2007 Erik de Castro Lopo <erikd@mega-nerd.com>
#
# 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) ;

63
Octave/octave_test.sh Executable file
View File

@ -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)

103
Octave/sfread.cc Normal file
View File

@ -0,0 +1,103 @@
/*
** Copyright (C) 2007 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** 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 <octave/oct.h>
#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 */

112
Octave/sfwrite.cc Normal file
View File

@ -0,0 +1,112 @@
/*
** Copyright (C) 2007 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** 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 <octave/oct.h>
#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 */

View File

@ -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 <eggert@twinsun.com>.
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 <erikd AT mega-nerd DOT com>
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 <endian.h>.
dnl 2) If 1) fails, look in <sys/types.h> and <sys/param.h>.
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 <endian.h> which should set BYTE_ORDER.
[AC_TRY_LINK([
#include <endian.h>
#if BYTE_ORDER != LITTLE_ENDIAN
not big endian
#endif
], return 0 ;,
ac_cv_c_byte_order=little
)]
[AC_TRY_LINK([
#include <endian.h>
#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 <sys/types.h>
#include <sys/param.h>
#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
bogus endian macros
#endif
], return 0 ;,
[AC_TRY_LINK([
#include <sys/types.h>
#include <sys/param.h>
#if BYTE_ORDER != LITTLE_ENDIAN
not big endian
#endif
], return 0 ;,
ac_cv_c_byte_order=little
)]
[AC_TRY_LINK([
#include <sys/types.h>
#include <sys/param.h>
#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 <erikd AT mega-nerd DOT com>
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 <stdlib.h>
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 <erikd AT mega-nerd DOT com>
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 <math.h>
], 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 <erikd AT mega-nerd DOT com>
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 <math.h>
], 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 <erikd AT mega-nerd DOT com>
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 <math.h>
#include <stdint.h>
], 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 <erikd AT mega-nerd DOT com>
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 <math.h>
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 <math.h>
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 <stdio.h>],
[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

132
autogen.sh Executable file
View File

@ -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)

View File

@ -3,13 +3,20 @@
dnl Require autoconf version dnl Require autoconf version
AC_PREREQ(2.57) 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_CONFIG_SRCDIR([src/sndfile.c])
AC_CANONICAL_TARGET([]) AC_CANONICAL_TARGET([])
AM_INIT_AUTOMAKE($PACKAGE_NAME,$PACKAGE_VERSION) AM_INIT_AUTOMAKE($PACKAGE_NAME,$PACKAGE_VERSION)
AC_CONFIG_HEADERS([src/config.h]) AC_CONFIG_HEADERS([src/config.h])
dnl Add parameters for aclocal
AC_SUBST(ACLOCAL_AMFLAGS, "-I M4")
AC_LANG([C]) AC_LANG([C])
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
@ -33,7 +40,7 @@ SHARED_VERSION_INFO="1:18:0"
AC_PROG_CC AC_PROG_CC
AM_PROG_LIBTOOL AM_PROG_LIBTOOL
AC_CHECK_PROG(autogen, autogen, yes, no) AC_CHECK_PROG(HAVE_AUTOGEN, autogen, yes, no)
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_LN_S AC_PROG_LN_S
@ -43,7 +50,6 @@ AC_HEADER_STDC
AC_CHECK_HEADERS(endian.h) AC_CHECK_HEADERS(endian.h)
AC_CHECK_HEADERS(byteswap.h) AC_CHECK_HEADERS(byteswap.h)
AC_CHECK_HEADERS(locale.h) AC_CHECK_HEADERS(locale.h)
AC_CHECK_HEADERS(inttypes.h)
AC_HEADER_SYS_WAIT AC_HEADER_SYS_WAIT
@ -259,6 +265,13 @@ case "$host_os" in
;; ;;
esac 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). # Check for libsqlite3 (only used in regtest).
@ -466,7 +479,7 @@ if test $ac_cv_sizeof_double != 8 ; then
AC_MSG_WARN([[******************************************************************]]) AC_MSG_WARN([[******************************************************************]])
fi 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/.]]) AC_MSG_WARN([[Touching files in directory tests/.]])
touch tests/*.c tests/*.h touch tests/*.c tests/*.h
fi fi
@ -611,16 +624,13 @@ AC_CONFIG_FILES([ \
src/FLAC/src/share/utf8/Makefile src/FLAC/src/test_libFLAC/Makefile \ 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_libs_common/Makefile src/FLAC/src/test_seeking/Makefile \
src/FLAC/src/test_streams/Makefile src/FLAC/test/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/Makefile src/FLAC/src/test_grabbag/cuesheet/Makefile \
src/FLAC/src/test_grabbag/picture/Makefile \ src/FLAC/src/test_grabbag/picture/Makefile \
\ \
src/OGG/include/ogg/Makefile src/OGG/include/Makefile src/OGG/Makefile \ src/OGG/include/ogg/Makefile src/OGG/include/Makefile src/OGG/Makefile \
man/Makefile examples/Makefile tests/Makefile regtest/Makefile \ man/Makefile examples/Makefile tests/Makefile regtest/Makefile \
doc/Makefile doc/libsndfile.css \ M4/Makefile doc/Makefile Win32/Makefile Octave/Makefile \
Win32/Makefile Octave/Makefile \ doc/libsndfile.css \
Makefile libsndfile.spec sndfile.pc \ Makefile libsndfile.spec sndfile.pc \
]) ])
AC_OUTPUT AC_OUTPUT

View File

@ -33,7 +33,8 @@ it on windows.
</P> </P>
<!-- pepper --> <!-- pepper -->
<P> <P>
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):
<A HREF="http://www.mega-nerd.com/Bzr/libsndfile-pub/"> <A HREF="http://www.mega-nerd.com/Bzr/libsndfile-pub/">
http://www.mega-nerd.com/Bzr/libsndfile-pub/</A> http://www.mega-nerd.com/Bzr/libsndfile-pub/</A>
</P> </P>

View File

@ -282,8 +282,12 @@
<LI> FLAC. <LI> FLAC.
</UL> </UL>
<P> <P>
I have decided that I will not be adding support for MPEG Layer 3 due to the I have decided that I will not be adding support for MPEG Layer 3 (commonly
patent issues surrounding this file format. known as MP3) due to the patent issues surrounding this file format.
See
<a href="http://www.mega-nerd.com/libsndfile/FAQ.html#Q020">
the FAQ</a>
for more.
</P> </P>
<P> <P>
Other file formats may also be added on request. Other file formats may also be added on request.

View File

@ -1,19 +1,33 @@
/* /*
** Copyright (C) 2002-2005 Erik de Castro Lopo <erikd@mega-nerd.com> ** Copyright (C) 2002-2007 Erik de Castro Lopo <erikd@mega-nerd.com>
** **
** This program is free software; you can redistribute it and/or modify ** All rights reserved.
** 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, ** Redistribution and use in source and binary forms, with or without
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** modification, are permitted provided that the following conditions are
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** met:
** GNU General Public License for more details.
** **
** You should have received a copy of the GNU General Public License ** * Redistributions of source code must retain the above copyright
** along with this program; if not, write to the Free Software ** notice, this list of conditions and the following disclaimer.
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** * 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" #include "sfconfig.h"

View File

@ -1,19 +1,33 @@
/* /*
** Copyright (C) 2001-2005 Erik de Castro Lopo <erikd@mega-nerd.com> ** Copyright (C) 2001-2007 Erik de Castro Lopo <erikd@mega-nerd.com>
** **
** This program is free software; you can redistribute it and/or modify ** All rights reserved.
** 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, ** Redistribution and use in source and binary forms, with or without
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** modification, are permitted provided that the following conditions are
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** met:
** GNU General Public License for more details.
** **
** You should have received a copy of the GNU General Public License ** * Redistributions of source code must retain the above copyright
** along with this program; if not, write to the Free Software ** notice, this list of conditions and the following disclaimer.
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** * 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 <stdio.h> #include <stdio.h>

View File

@ -1,19 +1,33 @@
/* /*
** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com> ** Copyright (C) 1999-2007 Erik de Castro Lopo <erikd@mega-nerd.com>
** **
** This program is free software; you can redistribute it and/or modify ** All rights reserved.
** 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, ** Redistribution and use in source and binary forms, with or without
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** modification, are permitted provided that the following conditions are
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** met:
** GNU General Public License for more details.
** **
** You should have received a copy of the GNU General Public License ** * Redistributions of source code must retain the above copyright
** along with this program; if not, write to the Free Software ** notice, this list of conditions and the following disclaimer.
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** * 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 <stdio.h> #include <stdio.h>

View File

@ -1,88 +0,0 @@
/*
** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** 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 <stdio.h>
#include <string.h>
#include <math.h>
#include <sndfile.h>
#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
*/

View File

@ -1,19 +1,33 @@
/* /*
** Copyright (C) 2001-2005 Erik de Castro Lopo <erikd@mega-nerd.com> ** Copyright (C) 2001-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
** **
** This program is free software; you can redistribute it and/or modify ** All rights reserved.
** 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, ** Redistribution and use in source and binary forms, with or without
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** modification, are permitted provided that the following conditions are
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** met:
** GNU General Public License for more details.
** **
** You should have received a copy of the GNU General Public License ** * Redistributions of source code must retain the above copyright
** along with this program; if not, write to the Free Software ** notice, this list of conditions and the following disclaimer.
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** * 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 <stdio.h> #include <stdio.h>

View File

@ -1,22 +1,35 @@
/* /*
** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com> ** Copyright (C) 1999-2007 Erik de Castro Lopo <erikd@mega-nerd.com>
** **
** This program is free software; you can redistribute it and/or modify ** All rights reserved.
** 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, ** Redistribution and use in source and binary forms, with or without
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** modification, are permitted provided that the following conditions are
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** met:
** GNU General Public License for more details.
** **
** You should have received a copy of the GNU General Public License ** * Redistributions of source code must retain the above copyright
** along with this program; if not, write to the Free Software ** notice, this list of conditions and the following disclaimer.
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** * 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 <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

View File

@ -1,19 +1,33 @@
/* /*
** Copyright (C) 2007 Erik de Castro Lopo <erikd@mega-nerd.com> ** Copyright (C) 2007 Erik de Castro Lopo <erikd@mega-nerd.com>
** **
** This program is free software; you can redistribute it and/or modify ** All rights reserved.
** 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, ** Redistribution and use in source and binary forms, with or without
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** modification, are permitted provided that the following conditions are
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** met:
** GNU General Public License for more details.
** **
** You should have received a copy of the GNU General Public License ** * Redistributions of source code must retain the above copyright
** along with this program; if not, write to the Free Software ** notice, this list of conditions and the following disclaimer.
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** * 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.
*/ */

View File

@ -1,19 +1,33 @@
/* /*
** Copyright (C) 1999-2006 Erik de Castro Lopo <erikd@mega-nerd.com> ** Copyright (C) 1999-2007 Erik de Castro Lopo <erikd@mega-nerd.com>
** **
** This program is free software; you can redistribute it and/or modify ** All rights reserved.
** 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, ** Redistribution and use in source and binary forms, with or without
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** modification, are permitted provided that the following conditions are
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** met:
** GNU General Public License for more details.
** **
** You should have received a copy of the GNU General Public License ** * Redistributions of source code must retain the above copyright
** along with this program; if not, write to the Free Software ** notice, this list of conditions and the following disclaimer.
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** * 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 <stdio.h> #include <stdio.h>

View File

@ -1,19 +1,33 @@
/* /*
** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com> ** Copyright (C) 1999-2007 Erik de Castro Lopo <erikd@mega-nerd.com>
** **
** This program is free software; you can redistribute it and/or modify ** All rights reserved.
** 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, ** Redistribution and use in source and binary forms, with or without
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** modification, are permitted provided that the following conditions are
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** met:
** GNU General Public License for more details.
** **
** You should have received a copy of the GNU General Public License ** * Redistributions of source code must retain the above copyright
** along with this program; if not, write to the Free Software ** notice, this list of conditions and the following disclaimer.
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** * 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" #include "sfconfig.h"

View File

@ -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 {} \;

View File

@ -28,9 +28,7 @@
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
flaccincludedir = $(includedir)/FLAC noinst_HEADERS = \
flaccinclude_HEADERS = \
all.h \ all.h \
assert.h \ assert.h \
callback.h \ callback.h \

View File

@ -141,6 +141,11 @@
* encoder, and no metadata interface, you can remove the stream encoder * encoder, and no metadata interface, you can remove the stream encoder
* and the metadata interface, which will greatly reduce the size of the * and the metadata interface, which will greatly reduce the size of the
* library. * 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 /** \defgroup porting Porting Guide for New Versions

View File

@ -32,6 +32,7 @@
#ifndef FLAC__METADATA_H #ifndef FLAC__METADATA_H
#define FLAC__METADATA_H #define FLAC__METADATA_H
#include <sys/types.h> /* for off_t */
#include "export.h" #include "export.h"
#include "callback.h" #include "callback.h"
#include "format.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); 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 /** Get the type of the metadata block at the current position. This
* avoids reading the actual block data which can save time for large * avoids reading the actual block data which can save time for large
* blocks. * blocks.
@ -455,9 +487,52 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIte
* \retval FLAC__MetadataType * \retval FLAC__MetadataType
* The type of the metadata block at the current iterator position. * 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); 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
* <a href="http://flac.sourceforge.net/format.html#metadata_block_header">metadata block header</a>,
* 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 /** Get the metadata block at the current position. You can modify the
* block but must use FLAC__metadata_simple_iterator_set_block() to * block but must use FLAC__metadata_simple_iterator_set_block() to
* write it back to the FLAC file. * 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 * \a iterator has been successfully initialized with
* FLAC__metadata_simple_iterator_init() * FLAC__metadata_simple_iterator_init()
* \retval FLAC__StreamMetadata* * \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); FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator);

View File

@ -5,6 +5,7 @@ AUTOMAKE_OPTIONS = foreign
SUBDIRS = grabbag SUBDIRS = grabbag
EXTRA_DIST = \ EXTRA_DIST = \
alloc.h \
getopt.h \ getopt.h \
grabbag.h \ grabbag.h \
replaygain_analysis.h \ replaygain_analysis.h \

View File

@ -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 <config.h>
#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 <limits.h> /* for SIZE_MAX */
#if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__
#include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */
#endif
#include <stdlib.h> /* 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

View File

@ -24,9 +24,6 @@
*/ */
#include "FLAC/format.h" #include "FLAC/format.h"
#include <stdio.h>
#include <stdlib.h> /* for malloc() */
#include <string.h> /* for memcmp() */
FLAC__bool mutils__compare_block_data_streaminfo(const FLAC__StreamMetadata_StreamInfo *block, const FLAC__StreamMetadata_StreamInfo *blockcopy); FLAC__bool mutils__compare_block_data_streaminfo(const FLAC__StreamMetadata_StreamInfo *block, const FLAC__StreamMetadata_StreamInfo *blockcopy);

View File

@ -18,7 +18,6 @@
SUBDIRS = \ SUBDIRS = \
libFLAC \ libFLAC \
share \ share \
monkeys_audio_utilities \
test_grabbag \ test_grabbag \
test_libs_common \ test_libs_common \
test_libFLAC \ test_libFLAC \

View File

@ -44,6 +44,7 @@
#include "private/bitwriter.h" #include "private/bitwriter.h"
#include "private/crc.h" #include "private/crc.h"
#include "FLAC/assert.h" #include "FLAC/assert.h"
#include "share/alloc.h"
/* Things should be fastest when this matches the machine word size */ /* 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 */ /* 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->capacity);
FLAC__ASSERT(new_capacity >= bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD)); 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) if(new_buffer == 0)
return false; return false;
bw->buffer = new_buffer; bw->buffer = new_buffer;

View File

@ -61,9 +61,9 @@ FLAC_API const char *FLAC__VERSION_STRING = "1.2.0";
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINW32__ #if defined _MSC_VER || defined __BORLANDC__ || defined __MINW32__
/* yet one more hack because of MSVC6: */ /* 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 #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 #endif
FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };

View File

@ -33,7 +33,7 @@ typedef struct {
FLAC__uint32 buf[4]; FLAC__uint32 buf[4];
FLAC__uint32 bytes[2]; FLAC__uint32 bytes[2];
FLAC__byte *internal_buf; FLAC__byte *internal_buf;
unsigned capacity; size_t capacity;
} FLAC__MD5Context; } FLAC__MD5Context;
void FLAC__MD5Init(FLAC__MD5Context *context); void FLAC__MD5Init(FLAC__MD5Context *context);

View File

@ -569,7 +569,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
} }
#else /* fully unrolled version for normal use */ #else /* fully unrolled version for normal use */
{ {
unsigned i; int i;
FLAC__int64 sum; FLAC__int64 sum;
FLAC__ASSERT(order > 0); 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 > 8) {
if(order > 10) { if(order > 10) {
if(order == 12) { if(order == 12) {
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; sum += qlp_coeff[11] * (FLAC__int64)data[i-12];
sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; 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 */ else { /* order == 11 */
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; sum += qlp_coeff[10] * (FLAC__int64)data[i-11];
sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; 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 { else {
if(order == 10) { if(order == 10) {
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; sum += qlp_coeff[9] * (FLAC__int64)data[i-10];
sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; 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 */ else { /* order == 9 */
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; sum += qlp_coeff[8] * (FLAC__int64)data[i-9];
sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; 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) { else if(order > 4) {
if(order > 6) { if(order > 6) {
if(order == 8) { if(order == 8) {
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; 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 */ else { /* order == 7 */
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; 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 { else {
if(order == 6) { if(order == 6) {
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; 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 */ else { /* order == 5 */
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; 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 { else {
if(order > 2) { if(order > 2) {
if(order == 4) { if(order == 4) {
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; 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 */ else { /* order == 3 */
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; 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 { else {
if(order == 2) { if(order == 2) {
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; 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 */ 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); residual[i] = data[i] - (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization);
} }
} }
} }
} }
else { /* order > 12 */ else { /* order > 12 */
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
switch(order) { switch(order) {
case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; 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 */ #else /* fully unrolled version for normal use */
{ {
unsigned i; int i;
FLAC__int64 sum; FLAC__int64 sum;
FLAC__ASSERT(order > 0); 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 > 8) {
if(order > 10) { if(order > 10) {
if(order == 12) { if(order == 12) {
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; sum += qlp_coeff[11] * (FLAC__int64)data[i-12];
sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; 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 */ else { /* order == 11 */
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; sum += qlp_coeff[10] * (FLAC__int64)data[i-11];
sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; 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 { else {
if(order == 10) { if(order == 10) {
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[9] * (FLAC__int64)data[i-10]; sum += qlp_coeff[9] * (FLAC__int64)data[i-10];
sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; 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 */ else { /* order == 9 */
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[8] * (FLAC__int64)data[i-9]; sum += qlp_coeff[8] * (FLAC__int64)data[i-9];
sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; 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) { else if(order > 4) {
if(order > 6) { if(order > 6) {
if(order == 8) { if(order == 8) {
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[7] * (FLAC__int64)data[i-8]; sum += qlp_coeff[7] * (FLAC__int64)data[i-8];
sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; 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 */ else { /* order == 7 */
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[6] * (FLAC__int64)data[i-7]; sum += qlp_coeff[6] * (FLAC__int64)data[i-7];
sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; 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 { else {
if(order == 6) { if(order == 6) {
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[5] * (FLAC__int64)data[i-6]; sum += qlp_coeff[5] * (FLAC__int64)data[i-6];
sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; 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 */ else { /* order == 5 */
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[4] * (FLAC__int64)data[i-5]; sum += qlp_coeff[4] * (FLAC__int64)data[i-5];
sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; 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 { else {
if(order > 2) { if(order > 2) {
if(order == 4) { if(order == 4) {
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[3] * (FLAC__int64)data[i-4]; sum += qlp_coeff[3] * (FLAC__int64)data[i-4];
sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; 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 */ else { /* order == 3 */
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; sum += qlp_coeff[2] * (FLAC__int64)data[i-3];
sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; 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 { else {
if(order == 2) { if(order == 2) {
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[1] * (FLAC__int64)data[i-2];
sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; 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 */ 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); data[i] = residual[i] + (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization);
} }
} }
} }
} }
else { /* order > 12 */ else { /* order > 12 */
for(i = 0; i < data_len; i++) { for(i = 0; i < (int)data_len; i++) {
sum = 0; sum = 0;
switch(order) { switch(order) {
case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32];

View File

@ -6,6 +6,7 @@
#include <string.h> /* for memcpy() */ #include <string.h> /* for memcpy() */
#include "private/md5.h" #include "private/md5.h"
#include "share/alloc.h"
#ifndef FLaC__INLINE #ifndef FLaC__INLINE
#define 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) 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) { if(ctx->capacity < bytes_needed) {
FLAC__byte *tmp = (FLAC__byte*)realloc(ctx->internal_buf, bytes_needed); FLAC__byte *tmp = (FLAC__byte*)realloc(ctx->internal_buf, bytes_needed);
if(0 == tmp) { if(0 == tmp) {
free(ctx->internal_buf); 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; return false;
} }
ctx->internal_buf = tmp; ctx->internal_buf = tmp;

View File

@ -35,6 +35,7 @@
#include "private/memory.h" #include "private/memory.h"
#include "FLAC/assert.h" #include "FLAC/assert.h"
#include "share/alloc.h"
void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) 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 #ifdef FLAC__ALIGN_MALLOC_DATA
/* align on 32-byte (256-bit) boundary */ /* align on 32-byte (256-bit) boundary */
x = malloc(bytes+31); x = safe_malloc_add_2op_(bytes, /*+*/31);
#ifdef SIZEOF_VOIDP #ifdef SIZEOF_VOIDP
#if SIZEOF_VOIDP == 4 #if SIZEOF_VOIDP == 4
/* could do *aligned_address = x + ((unsigned) (32 - (((unsigned)x) & 31))) & 31; */ /* 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; return 0;
#endif #endif
#else #else
x = malloc(bytes); x = safe_malloc_(bytes);
*aligned_address = x; *aligned_address = x;
#endif #endif
return x; 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(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != 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) { if(0 == pu) {
return false; 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(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != 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) { if(0 == pu) {
return false; 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(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != 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) { if(0 == pu) {
return false; return false;
} }
@ -161,7 +171,10 @@ FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned
FLAC__ASSERT(0 != aligned_pointer); FLAC__ASSERT(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != 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) { if(0 == pu) {
return false; 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(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != 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) { if(0 == pu) {
return false; return false;
} }

View File

@ -61,6 +61,7 @@
#include "FLAC/assert.h" #include "FLAC/assert.h"
#include "FLAC/stream_decoder.h" #include "FLAC/stream_decoder.h"
#include "share/alloc.h"
#ifdef max #ifdef max
#undef max #undef max
@ -577,6 +578,22 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIte
return true; 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_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator)
{ {
FLAC__ASSERT(0 != iterator); FLAC__ASSERT(0 != iterator);
@ -585,6 +602,41 @@ FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const
return iterator->type; 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_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator)
{ {
FLAC__StreamMetadata *block = FLAC__metadata_object_new(iterator->type); 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) if(read_cb(block->id, 1, id_bytes, handle) != id_bytes)
return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; 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; block_length -= id_bytes;
if(block_length == 0) { if(block_length == 0) {
@ -2128,7 +2183,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_seektable_cb_(FLAC_
if(block->num_points == 0) if(block->num_points == 0)
block->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; return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
for(i = 0; i < block->num_points; i++) { 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; entry->entry = 0;
} }
else { 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; return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
if(read_cb(entry->entry, 1, entry->length, handle) != entry->length) 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) if(0 != *data)
free(*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; return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
if(*length > 0) { 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; len = FLAC__STREAM_METADATA_PICTURE_TYPE_LEN / 8;
if(read_cb(buffer, 1, len, handle) != len) if(read_cb(buffer, 1, len, handle) != len)
return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; 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) 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; 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"; static const char *tempfile_suffix = ".metadata_edit";
if(0 == tempfile_path_prefix) { 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; *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
return false; return false;
} }
@ -3169,7 +3224,7 @@ FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix
else else
p++; 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; *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
return false; return false;
} }

View File

@ -39,6 +39,7 @@
#include "private/metadata.h" #include "private/metadata.h"
#include "FLAC/assert.h" #include "FLAC/assert.h"
#include "share/alloc.h"
/**************************************************************************** /****************************************************************************
@ -53,14 +54,14 @@
* from != NULL && bytes > 0 * from != NULL && bytes > 0
* to <- copy of from * to <- copy of from
* else ASSERT * 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) static FLAC__bool copy_bytes_(FLAC__byte **to, const FLAC__byte *from, unsigned bytes)
{ {
FLAC__ASSERT(0 != to); FLAC__ASSERT(0 != to);
if(bytes > 0 && 0 != from) { if(bytes > 0 && 0 != from) {
FLAC__byte *x; FLAC__byte *x;
if(0 == (x = (FLAC__byte*)malloc(bytes))) if(0 == (x = (FLAC__byte*)safe_malloc_(bytes)))
return false; return false;
memcpy(x, from, bytes); memcpy(x, from, bytes);
*to = x; *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 */ /* realloc() failure leaves entry unchanged */
static FLAC__bool ensure_null_terminated_(FLAC__byte **entry, unsigned length) 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) { if(0 != x) {
x[length] = '\0'; x[length] = '\0';
*entry = x; *entry = x;
@ -132,7 +133,7 @@ static FLAC__bool copy_vcentry_(FLAC__StreamMetadata_VorbisComment_Entry *to, co
else { else {
FLAC__byte *x; FLAC__byte *x;
FLAC__ASSERT(from->length > 0); 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; return false;
memcpy(x, from->entry, from->length); memcpy(x, from->entry, from->length);
x[from->length] = '\0'; x[from->length] = '\0';
@ -150,7 +151,7 @@ static FLAC__bool copy_track_(FLAC__StreamMetadata_CueSheet_Track *to, const FLA
else { else {
FLAC__StreamMetadata_CueSheet_Index *x; FLAC__StreamMetadata_CueSheet_Index *x;
FLAC__ASSERT(from->num_indices > 0); 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; return false;
memcpy(x, from->indices, from->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index)); memcpy(x, from->indices, from->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index));
to->indices = x; to->indices = x;
@ -172,7 +173,7 @@ static FLAC__StreamMetadata_SeekPoint *seekpoint_array_new_(unsigned num_points)
FLAC__ASSERT(num_points > 0); 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) { if(0 != object_array) {
unsigned i; unsigned i;
@ -205,7 +206,7 @@ static FLAC__StreamMetadata_VorbisComment_Entry *vorbiscomment_entry_array_new_(
{ {
FLAC__ASSERT(num_comments > 0); 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) 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); 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) static FLAC__StreamMetadata_CueSheet_Track *cuesheet_track_array_new_(unsigned num_tracks)
{ {
FLAC__ASSERT(num_tracks > 0); 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) 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: case FLAC__METADATA_TYPE_PADDING:
break; break;
case FLAC__METADATA_TYPE_APPLICATION: 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); 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)) { 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); FLAC__metadata_object_delete(to);
@ -545,6 +550,10 @@ FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMet
break; break;
case FLAC__METADATA_TYPE_SEEKTABLE: case FLAC__METADATA_TYPE_SEEKTABLE:
to->data.seek_table.num_points = object->data.seek_table.num_points; 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))) { 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); FLAC__metadata_object_delete(to);
return 0; return 0;
@ -930,8 +939,12 @@ FLAC_API FLAC__bool FLAC__metadata_object_seektable_resize_points(FLAC__StreamMe
return false; return false;
} }
else { else {
const unsigned old_size = object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint); const size_t 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 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); 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; return false;
} }
else { else {
const unsigned old_size = object->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry); const size_t 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 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); 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 nn = strlen(field_name);
const size_t nv = strlen(field_value); const size_t nv = strlen(field_value);
entry->length = nn + 1 /*=*/ + nv; 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; return false;
memcpy(entry->entry, field_name, nn); memcpy(entry->entry, field_name, nn);
entry->entry[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); FLAC__ASSERT(0 != eq);
if(0 == eq) if(0 == eq)
return false; /* double protection */ 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; return false;
if(0 == (*field_value = (char*)malloc(nv+1))) { if(0 == (*field_value = (char*)safe_malloc_add_2op_(nv, /*+*/1))) {
free(*field_name); free(*field_name);
return false; return false;
} }
@ -1465,8 +1482,12 @@ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_resize_indices(FLAC__St
return false; return false;
} }
else { else {
const unsigned old_size = track->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index); const size_t 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 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); FLAC__ASSERT(track->num_indices > 0);
@ -1549,8 +1570,12 @@ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMet
return false; return false;
} }
else { else {
const unsigned old_size = object->data.cue_sheet.num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track); const size_t 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 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); 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 */ /* do the copy first so that if we fail we leave the object untouched */
if(copy) { 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)) if(!copy_bytes_((FLAC__byte**)(&object->data.picture.mime_type), (FLAC__byte*)mime_type, new_length+1))
return false; 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 */ /* do the copy first so that if we fail we leave the object untouched */
if(copy) { if(copy) {
if(new_length >= SIZE_MAX) /* overflow check */
return false;
if(!copy_bytes_(&object->data.picture.description, description, new_length+1)) if(!copy_bytes_(&object->data.picture.description, description, new_length+1))
return false; return false;
} }

View File

@ -36,6 +36,7 @@
#include <stdlib.h> /* for malloc() */ #include <stdlib.h> /* for malloc() */
#include <string.h> /* for memcmp(), memcpy() */ #include <string.h> /* for memcmp(), memcpy() */
#include "FLAC/assert.h" #include "FLAC/assert.h"
#include "share/alloc.h"
#include "private/ogg_helper.h" #include "private/ogg_helper.h"
#include "protected/stream_encoder.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 */ /* 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; encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
return false; 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 */ /* 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; encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
return false; return false;
} }

View File

@ -53,6 +53,7 @@
#endif #endif
#endif #endif
#include "FLAC/assert.h" #include "FLAC/assert.h"
#include "share/alloc.h"
#include "protected/stream_decoder.h" #include "protected/stream_decoder.h"
#include "private/bitreader.h" #include "private/bitreader.h"
#include "private/bitmath.h" #include "private/bitmath.h"
@ -181,7 +182,7 @@ typedef struct FLAC__StreamDecoderPrivate {
FLAC__StreamMetadata seek_table; FLAC__StreamMetadata seek_table;
FLAC__bool metadata_filter[128]; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */ FLAC__bool metadata_filter[128]; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */
FLAC__byte *metadata_filter_ids; 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__Frame frame;
FLAC__bool cached; /* true if there is a byte in lookahead */ FLAC__bool cached; /* true if there is a byte in lookahead */
FLAC__CPUInfo cpuinfo; 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); FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { 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; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; 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); FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { 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; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; return false;
} }
@ -1287,9 +1288,11 @@ FILE *get_binary_stdin_(void)
*/ */
#if defined _MSC_VER || defined __MINGW32__ #if defined _MSC_VER || defined __MINGW32__
_setmode(_fileno(stdin), _O_BINARY); _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... */ /* almost certainly not needed for any modern Cygwin, but let's be safe... */
setmode(_fileno(stdin), _O_BINARY); setmode(_fileno(stdin), _O_BINARY);
#elif defined __EMX__
setmode(fileno(stdin), O_BINARY);
#endif #endif
return stdin; 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 * (at negative indices) for alignment purposes; we use 4
* to keep the data well-aligned. * 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) { if(tmp == 0) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; 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) FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id)
{ {
unsigned i; size_t i;
FLAC__ASSERT(0 != decoder); FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_); 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)) 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 */ 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; 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)) 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) if(!decoder->private_->is_seeking && decoder->private_->metadata_callback)
decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data); 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) { switch(type) {
case FLAC__METADATA_TYPE_PADDING: case FLAC__METADATA_TYPE_PADDING:
break; 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; 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) */ /* 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; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; 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)) if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length))
return false; /* read_callback_ sets the state for us */ return false; /* read_callback_ sets the state for us */
if(obj->vendor_string.length > 0) { 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; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; return false;
} }
@ -1728,7 +1736,7 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre
/* read comments */ /* read comments */
if(obj->num_comments > 0) { 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; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; 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)) if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length))
return false; /* read_callback_ sets the state for us */ return false; /* read_callback_ sets the state for us */
if(obj->comments[i].length > 0) { 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; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; return false;
} }
@ -1783,7 +1791,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet
obj->num_tracks = x; obj->num_tracks = x;
if(obj->num_tracks > 0) { 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; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; return false;
} }
@ -1816,7 +1824,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet
track->num_indices = (FLAC__byte)x; track->num_indices = (FLAC__byte)x;
if(track->num_indices > 0) { 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; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; return false;
} }
@ -1853,7 +1861,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta
/* read MIME type */ /* read MIME type */
if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN)) 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 */ 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; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; return false;
} }
@ -1866,7 +1874,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta
/* read description */ /* read description */
if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN)) 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 */ 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; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; return false;
} }
@ -1895,7 +1903,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta
/* read data */ /* read data */
if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN)) 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 */ 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; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; return false;
} }
@ -2043,6 +2051,8 @@ FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FL
} }
if(!read_zero_padding_(decoder)) if(!read_zero_padding_(decoder))
return false; 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 * 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[0][i] = (mid + side) >> 1;
decoder->private_->output[1][i] = (mid - side) >> 1; decoder->private_->output[1][i] = (mid - side) >> 1;
#else #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... */ 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[0][i] = (mid + decoder->private_->output[1][i]) >> 1;
decoder->private_->output[1][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_pos = 0, right_pos = stream_length;
FLAC__uint64 left_sample = 0, right_sample = FLAC__stream_decoder_get_total_samples(decoder); 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__uint64 pos = 0; /* only initialized to avoid compiler warning */
FLAC__bool did_a_seek; FLAC__bool did_a_seek;
unsigned iteration = 0; unsigned iteration = 0;

View File

@ -54,6 +54,7 @@
#endif #endif
#include "FLAC/assert.h" #include "FLAC/assert.h"
#include "FLAC/stream_decoder.h" #include "FLAC/stream_decoder.h"
#include "share/alloc.h"
#include "protected/stream_encoder.h" #include "protected/stream_encoder.h"
#include "private/bitwriter.h" #include "private/bitwriter.h"
#include "private/bitmath.h" #include "private/bitmath.h"
@ -198,6 +199,7 @@ static unsigned evaluate_fixed_subframe_(
unsigned subframe_bps, unsigned subframe_bps,
unsigned order, unsigned order,
unsigned rice_parameter, unsigned rice_parameter,
unsigned rice_parameter_limit,
unsigned min_partition_order, unsigned min_partition_order,
unsigned max_partition_order, unsigned max_partition_order,
FLAC__bool do_escape_coding, FLAC__bool do_escape_coding,
@ -219,6 +221,7 @@ static unsigned evaluate_lpc_subframe_(
unsigned order, unsigned order,
unsigned qlp_coeff_precision, unsigned qlp_coeff_precision,
unsigned rice_parameter, unsigned rice_parameter,
unsigned rice_parameter_limit,
unsigned min_partition_order, unsigned min_partition_order,
unsigned max_partition_order, unsigned max_partition_order,
FLAC__bool do_escape_coding, FLAC__bool do_escape_coding,
@ -244,12 +247,13 @@ static unsigned find_best_partition_order_(
unsigned residual_samples, unsigned residual_samples,
unsigned predictor_order, unsigned predictor_order,
unsigned rice_parameter, unsigned rice_parameter,
unsigned rice_parameter_limit,
unsigned min_partition_order, unsigned min_partition_order,
unsigned max_partition_order, unsigned max_partition_order,
unsigned bps, unsigned bps,
FLAC__bool do_escape_coding, FLAC__bool do_escape_coding,
unsigned rice_parameter_search_dist, unsigned rice_parameter_search_dist,
FLAC__EntropyCodingMethod_PartitionedRice *best_partitioned_rice FLAC__EntropyCodingMethod *best_ecm
); );
static void precompute_partition_info_sums_( static void precompute_partition_info_sums_(
@ -280,6 +284,7 @@ static FLAC__bool set_partitioned_rice_(
const unsigned residual_samples, const unsigned residual_samples,
const unsigned predictor_order, const unsigned predictor_order,
const unsigned suggested_rice_parameter, const unsigned suggested_rice_parameter,
const unsigned rice_parameter_limit,
const unsigned rice_parameter_search_dist, const unsigned rice_parameter_search_dist,
const unsigned partition_order, const unsigned partition_order,
const FLAC__bool search_for_escapes, 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_; encoder->private_->verify.input_fifo.size = encoder->protected_->blocksize+OVERREAD_;
for(i = 0; i < encoder->protected_->channels; i++) { 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; encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_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) { if(num_blocks) {
FLAC__StreamMetadata **m; 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; return false;
memcpy(m, metadata, sizeof(m[0]) * num_blocks); memcpy(m, metadata, sizeof(m[0]) * num_blocks);
encoder->protected_->metadata = m; encoder->protected_->metadata = m;
@ -3197,6 +3202,8 @@ FLAC__bool process_subframe_(
unsigned rice_parameter; unsigned rice_parameter;
unsigned _candidate_bits, _best_bits; unsigned _candidate_bits, _best_bits;
unsigned _best_subframe; 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); 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 */ 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 #endif
rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */ 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 #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 #endif
rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; rice_parameter = rice_parameter_limit - 1;
} }
_candidate_bits = _candidate_bits =
evaluate_fixed_subframe_( evaluate_fixed_subframe_(
@ -3276,6 +3283,7 @@ FLAC__bool process_subframe_(
subframe_bps, subframe_bps,
fixed_order, fixed_order,
rice_parameter, rice_parameter,
rice_parameter_limit,
min_partition_order, min_partition_order,
max_partition_order, max_partition_order,
encoder->protected_->do_escape_coding, encoder->protected_->do_escape_coding,
@ -3330,11 +3338,11 @@ FLAC__bool process_subframe_(
continue; /* don't even try */ 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 = (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 */ 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 #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 #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) { if(encoder->protected_->do_qlp_coeff_prec_search) {
min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION; min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION;
@ -3363,6 +3371,7 @@ FLAC__bool process_subframe_(
lpc_order, lpc_order,
qlp_coeff_precision, qlp_coeff_precision,
rice_parameter, rice_parameter,
rice_parameter_limit,
min_partition_order, min_partition_order,
max_partition_order, max_partition_order,
encoder->protected_->do_escape_coding, encoder->protected_->do_escape_coding,
@ -3502,6 +3511,7 @@ unsigned evaluate_fixed_subframe_(
unsigned subframe_bps, unsigned subframe_bps,
unsigned order, unsigned order,
unsigned rice_parameter, unsigned rice_parameter,
unsigned rice_parameter_limit,
unsigned min_partition_order, unsigned min_partition_order,
unsigned max_partition_order, unsigned max_partition_order,
FLAC__bool do_escape_coding, FLAC__bool do_escape_coding,
@ -3530,12 +3540,13 @@ unsigned evaluate_fixed_subframe_(
residual_samples, residual_samples,
order, order,
rice_parameter, rice_parameter,
rice_parameter_limit,
min_partition_order, min_partition_order,
max_partition_order, max_partition_order,
subframe_bps, subframe_bps,
do_escape_coding, do_escape_coding,
rice_parameter_search_dist, rice_parameter_search_dist,
&subframe->data.fixed.entropy_coding_method.data.partitioned_rice &subframe->data.fixed.entropy_coding_method
); );
subframe->data.fixed.order = order; subframe->data.fixed.order = order;
@ -3564,6 +3575,7 @@ unsigned evaluate_lpc_subframe_(
unsigned order, unsigned order,
unsigned qlp_coeff_precision, unsigned qlp_coeff_precision,
unsigned rice_parameter, unsigned rice_parameter,
unsigned rice_parameter_limit,
unsigned min_partition_order, unsigned min_partition_order,
unsigned max_partition_order, unsigned max_partition_order,
FLAC__bool do_escape_coding, FLAC__bool do_escape_coding,
@ -3611,12 +3623,13 @@ unsigned evaluate_lpc_subframe_(
residual_samples, residual_samples,
order, order,
rice_parameter, rice_parameter,
rice_parameter_limit,
min_partition_order, min_partition_order,
max_partition_order, max_partition_order,
subframe_bps, subframe_bps,
do_escape_coding, do_escape_coding,
rice_parameter_search_dist, rice_parameter_search_dist,
&subframe->data.lpc.entropy_coding_method.data.partitioned_rice &subframe->data.lpc.entropy_coding_method
); );
subframe->data.lpc.order = order; subframe->data.lpc.order = order;
@ -3669,16 +3682,18 @@ unsigned find_best_partition_order_(
unsigned residual_samples, unsigned residual_samples,
unsigned predictor_order, unsigned predictor_order,
unsigned rice_parameter, unsigned rice_parameter,
unsigned rice_parameter_limit,
unsigned min_partition_order, unsigned min_partition_order,
unsigned max_partition_order, unsigned max_partition_order,
unsigned bps, unsigned bps,
FLAC__bool do_escape_coding, FLAC__bool do_escape_coding,
unsigned rice_parameter_search_dist, unsigned rice_parameter_search_dist,
FLAC__EntropyCodingMethod_PartitionedRice *best_partitioned_rice FLAC__EntropyCodingMethod *best_ecm
) )
{ {
unsigned residual_bits, best_residual_bits = 0; unsigned residual_bits, best_residual_bits = 0;
unsigned best_parameters_index = 0; unsigned best_parameters_index = 0;
unsigned best_partition_order = 0;
const unsigned blocksize = residual_samples + predictor_order; 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); 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, residual_samples,
predictor_order, predictor_order,
rice_parameter, rice_parameter,
rice_parameter_limit,
rice_parameter_search_dist, rice_parameter_search_dist,
(unsigned)partition_order, (unsigned)partition_order,
do_escape_coding, do_escape_coding,
@ -3719,20 +3735,37 @@ unsigned find_best_partition_order_(
if(best_residual_bits == 0 || residual_bits < best_residual_bits) { if(best_residual_bits == 0 || residual_bits < best_residual_bits) {
best_residual_bits = residual_bits; best_residual_bits = residual_bits;
best_parameters_index = !best_parameters_index; best_parameters_index = !best_parameters_index;
best_partitioned_rice->order = partition_order; best_partition_order = partition_order;
} }
} }
} }
/* best_ecm->data.partitioned_rice.order = best_partition_order;
* We are allowed to de-const the pointer based on our special knowledge;
* it is const to the outside world.
*/
{ {
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)); * We are allowed to de-const the pointer based on our special
memcpy(best_partitioned_rice_contents->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, sizeof(unsigned)*(1<<(best_partitioned_rice->order))); * knowledge; it is const to the outside world.
memcpy(best_partitioned_rice_contents->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(unsigned)*(1<<(best_partitioned_rice->order))); */
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<<best_partition_order); partition++) {
if(prc->parameters[partition] >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
best_ecm->type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2;
break;
}
}
} }
return best_residual_bits; return best_residual_bits;
@ -3885,7 +3918,7 @@ static FLaC__INLINE unsigned count_rice_bits_in_partition_(
) )
{ {
unsigned i, partition_bits = 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 */ (1+rice_parameter) * partition_samples /* 1 for unary stop bit + rice_parameter for the binary portion */
; ;
for(i = 0; i < partition_samples; i++) for(i = 0; i < partition_samples; i++)
@ -3900,7 +3933,7 @@ static FLaC__INLINE unsigned count_rice_bits_in_partition_(
) )
{ {
return 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 */ (1+rice_parameter) * partition_samples + /* 1 for unary stop bit + rice_parameter for the binary portion */
( (
rice_parameter? rice_parameter?
@ -3927,6 +3960,7 @@ FLAC__bool set_partitioned_rice_(
const unsigned residual_samples, const unsigned residual_samples,
const unsigned predictor_order, const unsigned predictor_order,
const unsigned suggested_rice_parameter, const unsigned suggested_rice_parameter,
const unsigned rice_parameter_limit,
const unsigned rice_parameter_search_dist, const unsigned rice_parameter_search_dist,
const unsigned partition_order, const unsigned partition_order,
const FLAC__bool search_for_escapes, const FLAC__bool search_for_escapes,
@ -3944,7 +3978,8 @@ FLAC__bool set_partitioned_rice_(
(void)rice_parameter_search_dist; (void)rice_parameter_search_dist;
#endif #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)); FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order));
parameters = partitioned_rice_contents->parameters; parameters = partitioned_rice_contents->parameters;
@ -3959,11 +3994,11 @@ FLAC__bool set_partitioned_rice_(
else else
min_rice_parameter = suggested_rice_parameter - rice_parameter_search_dist; min_rice_parameter = suggested_rice_parameter - rice_parameter_search_dist;
max_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 #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 #endif
max_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; max_rice_parameter = rice_parameter_limit - 1;
} }
} }
else else
@ -3986,12 +4021,14 @@ FLAC__bool set_partitioned_rice_(
} }
#endif #endif
if(search_for_escapes) { 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) { if(partition_bits <= best_partition_bits) {
raw_bits[0] = raw_bits_per_partition[0]; 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; best_partition_bits = partition_bits;
} }
else
raw_bits[0] = 0;
} }
parameters[0] = best_rice_parameter; parameters[0] = best_rice_parameter;
bits_ += best_partition_bits; 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) 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 #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 #endif
rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; rice_parameter = rice_parameter_limit - 1;
} }
best_partition_bits = (unsigned)(-1); best_partition_bits = (unsigned)(-1);
@ -4035,11 +4072,11 @@ FLAC__bool set_partitioned_rice_(
else else
min_rice_parameter = rice_parameter - rice_parameter_search_dist; min_rice_parameter = rice_parameter - rice_parameter_search_dist;
max_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 #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 #endif
max_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; max_rice_parameter = rice_parameter_limit - 1;
} }
} }
else else
@ -4060,12 +4097,14 @@ FLAC__bool set_partitioned_rice_(
} }
#endif #endif
if(search_for_escapes) { 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) { if(partition_bits <= best_partition_bits) {
raw_bits[partition] = raw_bits_per_partition[partition]; 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; best_partition_bits = partition_bits;
} }
else
raw_bits[partition] = 0;
} }
parameters[partition] = best_rice_parameter; parameters[partition] = best_rice_parameter;
bits_ += best_partition_bits; bits_ += best_partition_bits;

View File

@ -45,7 +45,7 @@
#define max(x,y) ((x)>(y)?(x):(y)) #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_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) 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)) if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_RESERVED_LEN))
return false; 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; return false;
FLAC__ASSERT(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE); 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: default:
if(header->blocksize <= 0x100) if(header->blocksize <= 0x100)
blocksize_hint = u = 6; blocksize_hint = u = 6;
else if(header->blocksize <= 0x10000)
blocksize_hint = u = 7;
else else
u = 0; blocksize_hint = u = 7;
break; break;
} }
if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BLOCK_SIZE_LEN)) 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)); FLAC__ASSERT(FLAC__format_sample_rate_is_valid(header->sample_rate));
sample_rate_hint = 0; sample_rate_hint = 0;
switch(header->sample_rate) { switch(header->sample_rate) {
case 8000: u = 4; break; case 88200: u = 1; break;
case 16000: u = 5; break; case 176400: u = 2; break;
case 22050: u = 6; break; case 192000: u = 3; break;
case 24000: u = 7; break; case 8000: u = 4; break;
case 32000: u = 8; break; case 16000: u = 5; break;
case 44100: u = 9; break; case 22050: u = 6; break;
case 48000: u = 10; break; case 24000: u = 7; break;
case 96000: u = 11; break; case 32000: u = 8; break;
case 44100: u = 9; break;
case 48000: u = 10; break;
case 96000: u = 11; break;
default: default:
if(header->sample_rate <= 255000 && header->sample_rate % 1000 == 0) if(header->sample_rate <= 255000 && header->sample_rate % 1000 == 0)
sample_rate_hint = u = 12; 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)) if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_ZERO_PAD_LEN))
return false; return false;
FLAC__ASSERT(header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER); if(header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) {
if(!FLAC__bitwriter_write_utf8_uint32(bw, header->number.frame_number)) if(!FLAC__bitwriter_write_utf8_uint32(bw, header->number.frame_number))
return false; return false;
}
else {
if(!FLAC__bitwriter_write_utf8_uint64(bw, header->number.sample_number))
return false;
}
if(blocksize_hint) if(blocksize_hint)
if(!FLAC__bitwriter_write_raw_uint32(bw, header->blocksize-1, (blocksize_hint==6)? 8:16)) 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; return false;
switch(subframe->entropy_coding_method.type) { switch(subframe->entropy_coding_method.type) {
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: 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; return false;
break; break;
default: default:
@ -424,7 +440,17 @@ FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned r
return false; return false;
switch(subframe->entropy_coding_method.type) { switch(subframe->entropy_coding_method.type) {
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: 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; return false;
break; break;
default: default:
@ -458,6 +484,7 @@ FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCo
return false; return false;
switch(method->type) { switch(method->type) {
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: 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)) if(!FLAC__bitwriter_write_raw_uint32(bw, method->data.partitioned_rice.order, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
return false; return false;
break; break;
@ -467,18 +494,24 @@ FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCo
return true; 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) { if(partition_order == 0) {
unsigned i; unsigned i;
if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)) if(raw_bits[0] == 0) {
return false; if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[0], plen))
if(rice_parameters[0] < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { return false;
if(!FLAC__bitwriter_write_rice_signed_block(bw, residual, residual_samples, rice_parameters[0])) if(!FLAC__bitwriter_write_rice_signed_block(bw, residual, residual_samples, rice_parameters[0]))
return false; return false;
} }
else { 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)) if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN))
return false; return false;
for(i = 0; i < residual_samples; i++) { 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; unsigned partition_samples;
const unsigned default_partition_samples = (residual_samples+predictor_order) >> partition_order; const unsigned default_partition_samples = (residual_samples+predictor_order) >> partition_order;
for(i = 0; i < (1u<<partition_order); i++) { for(i = 0; i < (1u<<partition_order); i++) {
if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[i], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN))
return false;
partition_samples = default_partition_samples; partition_samples = default_partition_samples;
if(i == 0) if(i == 0)
partition_samples -= predictor_order; partition_samples -= predictor_order;
k += partition_samples; k += partition_samples;
if(rice_parameters[i] < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { if(raw_bits[i] == 0) {
if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[i], plen))
return false;
if(!FLAC__bitwriter_write_rice_signed_block(bw, residual+k_last, k-k_last, rice_parameters[i])) if(!FLAC__bitwriter_write_rice_signed_block(bw, residual+k_last, k-k_last, rice_parameters[i]))
return false; return false;
} }
else { else {
if(!FLAC__bitwriter_write_raw_uint32(bw, pesc, plen))
return false;
if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[i], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[i], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN))
return false; return false;
for(j = k_last; j < k; j++) { for(j = k_last; j < k; j++) {

View File

@ -1,18 +0,0 @@
# FLAC - Free Lossless Audio Codec
# Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson
#
# This file is part the FLAC project. FLAC is comprised of several
# components distributed under difference licenses. The codec libraries
# are distributed under Xiph.Org's BSD-like license (see the file
# COPYING.Xiph in this distribution). All other programs, libraries, and
# plugins are distributed under the GPL (see COPYING.GPL). The documentation
# is distributed under the Gnu FDL (see COPYING.FDL). Each file in the
# FLAC distribution contains at the top the terms under which it may be
# distributed.
#
# Since this particular file is relevant to all components of FLAC,
# it may be distributed under the Xiph.Org license, which is the least
# restrictive of those mentioned above. See the file COPYING.Xiph in this
# distribution.
SUBDIRS = flac_mac flac_ren

View File

@ -1,19 +0,0 @@
# flac_mac - wedge 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

View File

@ -1,208 +0,0 @@
/* flac_mac - wedge 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.
*/
/*
* This program can be used to allow FLAC to masquerade as one of the other
* supported lossless codecs in Monkey's Audio. See the documentation for
* how to do this.
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<wtypes.h>
#include<process.h>
#include<winbase.h>
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;
}

View File

@ -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

View File

@ -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 <config.h>
#endif
#include <io.h>
#include <sys/stat.h>
#include <wtypes.h>
#include <winbase.h>
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]);
}

View File

@ -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"; *error_message = "TRACK number must be greater than 0";
return false; return false;
} }
if(is_cdda && in_track_num > 99) { if(is_cdda) {
*error_message = "CD-DA TRACK number must be between 1 and 99, inclusive"; if(in_track_num > 99) {
return false; *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) { 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"; *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) { 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; forced_leadout_track_offset = lead_out_offset;
} }
if(!FLAC__metadata_object_cuesheet_insert_blank_track(cuesheet, cs->num_tracks)) { if(!FLAC__metadata_object_cuesheet_insert_blank_track(cuesheet, cs->num_tracks)) {

View File

@ -42,8 +42,8 @@
#include <string.h> /* for strrchr() */ #include <string.h> /* for strrchr() */
#if defined _WIN32 && !defined __CYGWIN__ #if defined _WIN32 && !defined __CYGWIN__
// for GetFileInformationByHandle() etc // for GetFileInformationByHandle() etc
#include <Windows.h> #include <windows.h>
#include <Winbase.h> #include <winbase.h>
#endif #endif
#include "share/grabbag.h" #include "share/grabbag.h"

View File

@ -20,6 +20,7 @@
# include <config.h> # include <config.h>
#endif #endif
#include "share/alloc.h"
#include "share/grabbag.h" #include "share/grabbag.h"
#include "FLAC/assert.h" #include "FLAC/assert.h"
#include <stdio.h> #include <stdio.h>
@ -29,7 +30,7 @@
/* slightly different that strndup(): this always copies 'size' bytes starting from s into a NUL-terminated string. */ /* 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) 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) { if(x) {
memcpy(x, s, size); memcpy(x, s, size);
x[size] = '\0'; x[size] = '\0';
@ -357,7 +358,7 @@ FLAC__StreamMetadata *grabbag__picture_parse_specification(const char *spec, con
if(size < 0) if(size < 0)
*error_message = error_messages[5]; *error_message = error_messages[5];
else { else {
FLAC__byte *buffer = (FLAC__byte*)malloc(size); FLAC__byte *buffer = (FLAC__byte*)safe_malloc_(size);
if(0 == buffer) if(0 == buffer)
*error_message = error_messages[0]; *error_message = error_messages[0];
else { else {

View File

@ -35,6 +35,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "alloc.h"
#include "charset.h" #include "charset.h"
#include "charmaps.h" #include "charmaps.h"
@ -493,7 +494,7 @@ int charset_convert(const char *fromcode, const char *tocode,
if (!charset1 || !charset2 ) if (!charset1 || !charset2 )
return -1; return -1;
tobuf = (char *)malloc(fromlen * charset2->max + 1); tobuf = (char *)safe_malloc_mul2add_(fromlen, /*times*/charset2->max, /*+*/1);
if (!tobuf) if (!tobuf)
return -2; return -2;

View File

@ -29,6 +29,7 @@
#include <string.h> #include <string.h>
#include "iconvert.h" #include "iconvert.h"
#include "share/alloc.h"
/* /*
* Convert data from one encoding to another. Return: * 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 * This is deliberately not a config option as people often
* change their iconv library without rebuilding applications. * change their iconv library without rebuilding applications.
*/ */
tocode1 = (char *)malloc(strlen(tocode) + 11); tocode1 = (char *)safe_malloc_add_2op_(strlen(tocode), /*+*/11);
if (!tocode1) if (!tocode1)
goto fail; goto fail;
@ -119,6 +120,8 @@ int iconvert(const char *fromcode, const char *tocode,
break; break;
if (obl < 6) { if (obl < 6) {
/* Enlarge the buffer */ /* Enlarge the buffer */
if(utflen*2 < utflen) /* overflow check */
goto fail;
utflen *= 2; utflen *= 2;
newbuf = (char *)realloc(utfbuf, utflen); newbuf = (char *)realloc(utfbuf, utflen);
if (!newbuf) if (!newbuf)
@ -145,7 +148,7 @@ int iconvert(const char *fromcode, const char *tocode,
iconv_close(cd1); iconv_close(cd1);
return ret; return ret;
} }
newbuf = (char *)realloc(utfbuf, (ob - utfbuf) + 1); newbuf = (char *)safe_realloc_add_2op_(utfbuf, (ob - utfbuf), /*+*/1);
if (!newbuf) if (!newbuf)
goto fail; goto fail;
ob = (ob - utfbuf) + newbuf; ob = (ob - utfbuf) + newbuf;
@ -196,7 +199,7 @@ int iconvert(const char *fromcode, const char *tocode,
outlen += ob - tbuf; outlen += ob - tbuf;
/* Convert from UTF-8 for real */ /* Convert from UTF-8 for real */
outbuf = (char *)malloc(outlen + 1); outbuf = (char *)safe_malloc_add_2op_(outlen, /*+*/1);
if (!outbuf) if (!outbuf)
goto fail; goto fail;
ib = utfbuf; ib = utfbuf;

View File

@ -2,6 +2,8 @@
* Copyright (C) 2001 Peter Harris <peter.harris@hummingbird.com> * Copyright (C) 2001 Peter Harris <peter.harris@hummingbird.com>
* Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org> * Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org>
* *
* Buffer overflow checking added: Josh Coalson, 9/9/2007
*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@ -28,6 +30,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "alloc.h"
#include "utf8.h" #include "utf8.h"
#include "charset.h" #include "charset.h"
@ -43,7 +46,8 @@
static unsigned char *make_utf8_string(const wchar_t *unicode) 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 char *out;
unsigned short c; unsigned short c;
@ -51,16 +55,19 @@ static unsigned char *make_utf8_string(const wchar_t *unicode)
c = unicode[index++]; c = unicode[index++];
while(c) { while(c) {
if(c < 0x0080) { if(c < 0x0080) {
size += 1; n = 1;
} else if(c < 0x0800) { } else if(c < 0x0800) {
size += 2; n = 2;
} else { } else {
size += 3; n = 3;
} }
if(size+n < size) /* overflow check */
return NULL;
size += n;
c = unicode[index++]; c = unicode[index++];
} }
out = malloc(size + 1); out = safe_malloc_add_2op_(size, /*+*/1);
if (out == NULL) if (out == NULL)
return NULL; return NULL;
index = 0; 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) 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; wchar_t *out;
unsigned char c; unsigned char c;
@ -101,11 +109,15 @@ static wchar_t *make_unicode_string(const unsigned char *utf8)
} else { } else {
index += 1; index += 1;
} }
size += 1; if(size + 1 == 0) /* overflow check */
return NULL;
size++;
c = utf8[index++]; 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) if (out == NULL)
return NULL; return NULL;
index = 0; index = 0;
@ -147,7 +159,10 @@ int utf8_encode(const char *from, char **to)
return -1; 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) if(unicode == NULL)
{ {
fprintf(stderr, "Out of memory processing string to UTF8\n"); 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, chars = WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode,
-1, NULL, 0, NULL, NULL); -1, NULL, 0, NULL, NULL);
if(chars < 0) /* underflow check */
return -1;
if(chars == 0) if(chars == 0)
{ {
fprintf(stderr, "Unicode translation error %d\n", GetLastError()); fprintf(stderr, "Unicode translation error %d\n", GetLastError());
@ -197,7 +215,7 @@ int utf8_decode(const char *from, char **to)
return -1; return -1;
} }
*to = calloc(chars + 1, sizeof(unsigned char)); *to = safe_calloc_((size_t)chars + 1, sizeof(unsigned char));
if(*to == NULL) if(*to == NULL)
{ {
fprintf(stderr, "Out of memory processing string to local charset\n"); 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) if (ret != -1)
return ret; return ret;
s = malloc(fromlen + 1); s = safe_malloc_add_2op_(fromlen, /*+*/1);
if (!s) if (!s)
return -1; return -1;
strcpy(s, from); strcpy(s, from);

View File

@ -66,7 +66,7 @@ static off_t flacfilesize_;
static const char *flacfilename(FLAC__bool is_ogg) 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) static FLAC__bool die_(const char *msg)

View File

@ -51,7 +51,7 @@ static const unsigned num_metadata_ = sizeof(metadata_sequence_) / sizeof(metada
static const char *flacfilename(FLAC__bool is_ogg) 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) static FLAC__bool die_(const char *msg)

View File

@ -73,7 +73,7 @@ static unsigned mc_our_block_number_ = 0;
static const char *flacfilename(FLAC__bool is_ogg) 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) 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)) { if(FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) {
struct stat stats; struct stat stats;
FILE *file, *tempfile; FILE *file, *tempfile = 0;
char *tempfilename; char *tempfilename;
if(preserve_file_stats) { if(preserve_file_stats) {
if(!get_file_stats_(filename, &stats)) if(!get_file_stats_(filename, &stats))

View File

@ -75,6 +75,21 @@ static FLAC__bool die_s_(const char *msg, const FLAC__StreamDecoder *decoder)
return false; 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) static off_t get_filesize_(const char *srcpath)
{ {
struct stat srcstat; 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) static FLAC__bool read_pcm_(FLAC__int32 *pcm[], const char *rawfilename, const char *flacfilename)
{ {
FILE *f; FILE *f;
unsigned channels, bps = 0, samples, i, j; unsigned channels = 0, bps = 0, samples, i, j;
off_t rawfilesize = get_filesize_(rawfilename); off_t rawfilesize = get_filesize_(rawfilename);
if (rawfilesize < 0) { 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); printf("file's total_samples is %I64u\n", decoder_client_data.total_samples);
#else #else
printf("file's total_samples is %llu\n", (unsigned long long)decoder_client_data.total_samples); 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 #endif
n = (long int)decoder_client_data.total_samples; 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) { 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 */ /* 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); 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); 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); pos = n + (i-20);
} }
else { else {
#if !defined _MSC_VER && !defined __MINGW32__ pos = (FLAC__uint64)(local_rand_() % n);
pos = (FLAC__uint64)(random() % n);
#else
/* RAND_MAX is only 32767 in my MSVC */
pos = (FLAC__uint64)((rand()<<15|rand()) % n);
#endif
} }
#ifdef _MSC_VER #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"); printf("OK\n");
fflush(stdout); fflush(stdout);
} }
stop_signal_ = false;
if(FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_UNINITIALIZED) { if(FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_UNINITIALIZED) {
if(!FLAC__stream_decoder_finish(decoder)) 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 */ /* no need to do "decode all" read_mode if PCM checking is available */
if (rawfilename && read_mode > 1) if (rawfilename && read_mode > 1)
continue; 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 #if FLAC__HAS_OGG
ok = seek_barrage(/*is_ogg=*/true, flacfilename, flacfilesize, count, samples, read_mode, rawfilename? pcm : 0); ok = seek_barrage(/*is_ogg=*/true, flacfilename, flacfilesize, count, samples, read_mode, rawfilename? pcm : 0);
#else #else

View File

@ -36,12 +36,6 @@
#define M_PI 3.14159265358979323846 #define M_PI 3.14159265358979323846
#endif #endif
#if defined _WIN32 || defined __EMX__
static const char *mode = "wb";
#else
static const char *mode = "w";
#endif
#if !defined _MSC_VER && !defined __MINGW32__ #if !defined _MSC_VER && !defined __MINGW32__
#define GET_RANDOM_BYTE (((unsigned)random()) & 0xff) #define GET_RANDOM_BYTE (((unsigned)random()) & 0xff)
#else #else
@ -211,7 +205,7 @@ static FLAC__bool generate_01(void)
FILE *f; FILE *f;
FLAC__int16 x = -32768; FLAC__int16 x = -32768;
if(0 == (f = fopen("test01.raw", mode))) if(0 == (f = fopen("test01.raw", "wb")))
return false; return false;
if(!write_little_endian_int16(f, x)) if(!write_little_endian_int16(f, x))
@ -230,7 +224,7 @@ static FLAC__bool generate_02(void)
FILE *f; FILE *f;
FLAC__int16 xl = -32768, xr = 32767; FLAC__int16 xl = -32768, xr = 32767;
if(0 == (f = fopen("test02.raw", mode))) if(0 == (f = fopen("test02.raw", "wb")))
return false; return false;
if(!write_little_endian_int16(f, xl)) 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 }; FLAC__int16 x[] = { -25, 0, 25, 50, 100 };
unsigned i; unsigned i;
if(0 == (f = fopen("test03.raw", mode))) if(0 == (f = fopen("test03.raw", "wb")))
return false; return false;
for(i = 0; i < 5; i++) 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 }; FLAC__int16 x[] = { -25, 500, 0, 400, 25, 300, 50, 200, 100, 100 };
unsigned i; unsigned i;
if(0 == (f = fopen("test04.raw", mode))) if(0 == (f = fopen("test04.raw", "wb")))
return false; return false;
for(i = 0; i < 10; i++) 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); FLAC__ASSERT(pattern != 0);
if(0 == (f = fopen(fn, mode))) if(0 == (f = fopen(fn, "wb")))
return false; return false;
for(rep = 0; rep < reps; rep++) { 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); FLAC__ASSERT(pattern != 0);
if(0 == (f = fopen(fn, mode))) if(0 == (f = fopen(fn, "wb")))
return false; return false;
for(rep = 0; rep < reps; rep++) { for(rep = 0; rep < reps; rep++) {
@ -345,7 +339,7 @@ static FLAC__bool generate_wbps16(const char *fn, unsigned samples)
FILE *f; FILE *f;
unsigned sample; unsigned sample;
if(0 == (f = fopen(fn, mode))) if(0 == (f = fopen(fn, "wb")))
return false; return false;
for(sample = 0; sample < samples; sample++) { 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); FLAC__ASSERT(pattern != 0);
if(0 == (f = fopen(fn, mode))) if(0 == (f = fopen(fn, "wb")))
return false; return false;
for(rep = 0; rep < reps; rep++) { 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; double theta1, theta2;
unsigned i; unsigned i;
if(0 == (f = fopen(fn, mode))) if(0 == (f = fopen(fn, "wb")))
return false; return false;
for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) { 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; double theta1, theta2;
unsigned i; unsigned i;
if(0 == (f = fopen(fn, mode))) if(0 == (f = fopen(fn, "wb")))
return false; return false;
for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) { 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; double theta1, theta2;
unsigned i; unsigned i;
if(0 == (f = fopen(fn, mode))) if(0 == (f = fopen(fn, "wb")))
return false; return false;
for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) { 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; double theta1, theta2;
unsigned i; unsigned i;
if(0 == (f = fopen(fn, mode))) if(0 == (f = fopen(fn, "wb")))
return false; return false;
for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) { 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; double theta1, theta2;
unsigned i; unsigned i;
if(0 == (f = fopen(fn, mode))) if(0 == (f = fopen(fn, "wb")))
return false; return false;
for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) { 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; double theta1, theta2;
unsigned i; unsigned i;
if(0 == (f = fopen(fn, mode))) if(0 == (f = fopen(fn, "wb")))
return false; return false;
for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) { 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; FILE *f;
unsigned b; unsigned b;
if(0 == (f = fopen(fn, mode))) if(0 == (f = fopen(fn, "wb")))
return false; return false;
for(b = 0; b < bytes; b++) { for(b = 0; b < bytes; b++) {
@ -599,7 +593,7 @@ static FLAC__bool generate_raw(const char *filename, unsigned channels, unsigned
FILE *f; FILE *f;
unsigned i, j; unsigned i, j;
if(0 == (f = fopen(filename, mode))) if(0 == (f = fopen(filename, "wb")))
return false; return false;
for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) { 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; FILE *f;
unsigned i, j; unsigned i, j;
if(0 == (f = fopen(filename, mode))) if(0 == (f = fopen(filename, "wb")))
return false; return false;
if(fwrite("FORM", 1, 4, f) < 4) if(fwrite("FORM", 1, 4, f) < 4)
goto foo; goto foo;
@ -693,7 +687,7 @@ static FLAC__bool generate_wav(const char *filename, unsigned sample_rate, unsig
FILE *f; FILE *f;
unsigned i, j; unsigned i, j;
if(0 == (f = fopen(filename, mode))) if(0 == (f = fopen(filename, "wb")))
return false; return false;
if(fwrite("RIFF", 1, 4, f) < 4) if(fwrite("RIFF", 1, 4, f) < 4)
goto foo; goto foo;
@ -768,14 +762,14 @@ static FLAC__bool generate_wackywavs(void)
4, 0, 0, 0, 'b', 'l', 'a', 'h' 4, 0, 0, 0, 'b', 'l', 'a', 'h'
}; };
if(0 == (f = fopen("wacky1.wav", mode))) if(0 == (f = fopen("wacky1.wav", "wb")))
return false; return false;
if(fwrite(wav, 1, 84, f) < 84) if(fwrite(wav, 1, 84, f) < 84)
goto foo; goto foo;
fclose(f); fclose(f);
wav[4] += 12; wav[4] += 12;
if(0 == (f = fopen("wacky2.wav", mode))) if(0 == (f = fopen("wacky2.wav", "wb")))
return false; return false;
if(fwrite(wav, 1, 96, f) < 96) if(fwrite(wav, 1, 96, f) < 96)
goto foo; goto foo;

View File

@ -5,14 +5,14 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * 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/ * * by the Xiph.Org Foundation http://www.xiph.org/ *
* * * *
******************************************************************** ********************************************************************
function: code raw [Vorbis] packets into framed OggSquish stream and function: code raw [Vorbis] packets into framed OggSquish stream and
decode Ogg streams back into raw packets 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 note: The CRC code is directly derived from public domain code by
Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html 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 */ /* submit data to the internal buffer of the framing engine */
int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){ int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count,
int lacing_vals=op->bytes/255+1,i; 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){ if(os->body_returned){
/* advance packet data according to the body_returned pointer. We /* 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 */ /* make sure we have the buffer storage */
_os_body_expand(os,op->bytes); _os_body_expand(os,bytes);
_os_lacing_expand(os,lacing_vals); _os_lacing_expand(os,lacing_vals);
/* Copy in the submitted packet. Yes, the copy is a waste; this is /* 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 will actually be fairly easy to eliminate the extra copy in the
future */ future */
memcpy(os->body_data+os->body_fill,op->packet,op->bytes); for (i = 0; i < count; ++i) {
os->body_fill+=op->bytes; 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 */ /* Store lacing vals for this packet */
for(i=0;i<lacing_vals-1;i++){ for(i=0;i<lacing_vals-1;i++){
os->lacing_vals[os->lacing_fill+i]=255; os->lacing_vals[os->lacing_fill+i]=255;
os->granule_vals[os->lacing_fill+i]=os->granulepos; os->granule_vals[os->lacing_fill+i]=os->granulepos;
} }
os->lacing_vals[os->lacing_fill+i]=(op->bytes)%255; os->lacing_vals[os->lacing_fill+i]=bytes%255;
os->granulepos=os->granule_vals[os->lacing_fill+i]=op->granulepos; os->granulepos=os->granule_vals[os->lacing_fill+i]=granulepos;
/* flag the first segment as the beginning of the packet */ /* flag the first segment as the beginning of the packet */
os->lacing_vals[os->lacing_fill]|= 0x100; 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 */ /* for the sake of completeness */
os->packetno++; os->packetno++;
if(op->e_o_s)os->e_o_s=1; if(e_o_s)os->e_o_s=1;
return(0); 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), /* This will flush remaining packets into a page (returning nonzero),
even if there is not enough data to trigger a flush normally even if there is not enough data to trigger a flush normally
(undersized page). If there are no packets or partial packets to (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) if(!next)
next=oy->data+oy->fill; next=oy->data+oy->fill;
oy->returned=next-oy->data; oy->returned=(int)(next-oy->data);
return(-(next-outerpage)); return(-(next-outerpage));
} }

View File

@ -5,13 +5,13 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * 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/ * * by the Xiph.Org Foundation http://www.xiph.org/ *
* * * *
******************************************************************** ********************************************************************
function: toplevel libogg include 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 #ifndef _OGG_H
@ -23,6 +23,11 @@ extern "C" {
#include <ogg/os_types.h> #include <ogg/os_types.h>
typedef struct {
void *iov_base;
size_t iov_len;
} ogg_iovec_t;
typedef struct { typedef struct {
long endbyte; long endbyte;
int endbit; int endbit;
@ -148,6 +153,8 @@ extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);
/* Ogg BITSTREAM PRIMITIVES: encoding **************************/ /* Ogg BITSTREAM PRIMITIVES: encoding **************************/
extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); 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_pageout(ogg_stream_state *os, ogg_page *og);
extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og);

View File

@ -11,7 +11,7 @@
******************************************************************** ********************************************************************
function: #ifdef jail to whip a few platforms into the UNIX ideal. 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 #ifndef _OS_TYPES_H
@ -27,19 +27,20 @@
#if defined(_WIN32) #if defined(_WIN32)
# if defined(__CYGWIN__) # if defined(__CYGWIN__)
# include <_G_config.h> # include <stdint.h>
typedef _G_int64_t ogg_int64_t; typedef int16_t ogg_int16_t;
typedef _G_int32_t ogg_int32_t; typedef uint16_t ogg_uint16_t;
typedef _G_uint32_t ogg_uint32_t; typedef int32_t ogg_int32_t;
typedef _G_int16_t ogg_int16_t; typedef uint32_t ogg_uint32_t;
typedef _G_uint16_t ogg_uint16_t; typedef int64_t ogg_int64_t;
typedef uint64_t ogg_uint64_t;
# elif defined(__MINGW32__) # elif defined(__MINGW32__)
typedef short ogg_int16_t; typedef short ogg_int16_t;
typedef unsigned short ogg_uint16_t; typedef unsigned short ogg_uint16_t;
typedef int ogg_int32_t; typedef int ogg_int32_t;
typedef unsigned int ogg_uint32_t; typedef unsigned int ogg_uint32_t;
typedef long long ogg_int64_t; typedef long long ogg_int64_t;
typedef unsigned long long ogg_uint64_t; typedef unsigned long long ogg_uint64_t;
# elif defined(__MWERKS__) # elif defined(__MWERKS__)
typedef long long ogg_int64_t; typedef long long ogg_int64_t;
typedef int ogg_int32_t; typedef int ogg_int32_t;

View File

@ -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), psf_binheader_readf (psf, "E242b", &(comm_fmt->numChannels), &(comm_fmt->numSampleFrames),
&(comm_fmt->sampleSize), &(comm_fmt->sampleRate), SIGNED_SIZEOF (comm_fmt->sampleRate)) ; &(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) if (comm_fmt->size == SIZEOF_AIFF_COMM)
comm_fmt->encoding = NONE_MARKER ; comm_fmt->encoding = NONE_MARKER ;
else if (comm_fmt->size == SIZEOF_AIFC_COMM_MIN) 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->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, " 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, " 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) ; psf_log_printf (psf, " Channels : %d\n", comm_fmt->numChannels) ;

View File

@ -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, " 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 ; psf->blockwidth = psf->sf.channels * psf->bytewidth ;

View File

@ -413,6 +413,7 @@ enum
SFE_INTERNAL, SFE_INTERNAL,
SFE_BAD_CONTROL_CMD, SFE_BAD_CONTROL_CMD,
SFE_BAD_ENDIAN, SFE_BAD_ENDIAN,
SFE_CHANNEL_COUNT_ZERO,
SFE_CHANNEL_COUNT, SFE_CHANNEL_COUNT,
SFE_BAD_RDWR_FORMAT, SFE_BAD_RDWR_FORMAT,
@ -523,12 +524,10 @@ enum
SFE_MAT4_BAD_NAME, SFE_MAT4_BAD_NAME,
SFE_MAT4_NO_SAMPLERATE, SFE_MAT4_NO_SAMPLERATE,
SFE_MAT4_ZERO_CHANNELS,
SFE_MAT5_BAD_ENDIAN, SFE_MAT5_BAD_ENDIAN,
SFE_MAT5_NO_BLOCK, SFE_MAT5_NO_BLOCK,
SFE_MAT5_SAMPLE_RATE, SFE_MAT5_SAMPLE_RATE,
SFE_MAT5_ZERO_CHANNELS,
SFE_PVF_NO_PVF1, SFE_PVF_NO_PVF1,
SFE_PVF_BAD_HEADER, SFE_PVF_BAD_HEADER,

View File

@ -69,7 +69,6 @@ ALL_SYMBOLS = (
( "sf_strerror", 50 ), ( "sf_strerror", 50 ),
( "sf_get_string", 60 ), ( "sf_get_string", 60 ),
( "sf_set_string", 61 ), ( "sf_set_string", 61 ),
( "sf_get_info", 68 ),
( "sf_open_fd", 70 ), ( "sf_open_fd", 70 ),
( "sf_open_virtual", 80 ), ( "sf_open_virtual", 80 ),
( "sf_write_sync", 90 ) ( "sf_write_sync", 90 )

View File

@ -40,8 +40,7 @@
** Private static functions. ** Private static functions.
*/ */
#define ENC_BUFFER_SIZE 4096 #define ENC_BUFFER_SIZE 8192
#define RBUFFER_LEN 4096
typedef enum typedef enum
{ PFLAC_PCM_SHORT = 50, { PFLAC_PCM_SHORT = 50,
@ -170,6 +169,17 @@ flac_buffer_copy (SF_PRIVATE *psf)
const FLAC__int32* const *buffer = pflac->wbuffer ; const FLAC__int32* const *buffer = pflac->wbuffer ;
unsigned i = 0, j, offset ; 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) if (pflac->ptr == NULL)
{ /* { /*
** Not sure why this code is here and not elsewhere. ** Not sure why this code is here and not elsewhere.
@ -177,17 +187,9 @@ flac_buffer_copy (SF_PRIVATE *psf)
*/ */
pflac->bufferbackup = SF_TRUE ; pflac->bufferbackup = SF_TRUE ;
for (i = 0 ; i < frame->header.channels ; i++) 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) 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)) ; memcpy (pflac->rbuffer [i], buffer [i], frame->header.blocksize * sizeof (FLAC__int32)) ;
} ; } ;

View File

@ -276,7 +276,7 @@ mat4_read_header (SF_PRIVATE *psf)
if (rows == 0 && cols == 0) if (rows == 0 && cols == 0)
{ psf_log_printf (psf, "*** Error : zero channel count.\n") ; { psf_log_printf (psf, "*** Error : zero channel count.\n") ;
return SFE_MAT4_ZERO_CHANNELS ; return SFE_CHANNEL_COUNT_ZERO ;
} ; } ;
psf->sf.channels = rows ; psf->sf.channels = rows ;

View File

@ -448,7 +448,7 @@ mat5_read_header (SF_PRIVATE *psf)
if (rows == 0 && cols == 0) if (rows == 0 && cols == 0)
{ psf_log_printf (psf, "*** Error : zero channel count.\n") ; { psf_log_printf (psf, "*** Error : zero channel count.\n") ;
return SFE_MAT5_ZERO_CHANNELS ; return SFE_CHANNEL_COUNT_ZERO ;
} ; } ;
psf->sf.channels = rows ; psf->sf.channels = rows ;

View File

@ -96,6 +96,7 @@ ErrorStruct SndfileErrors [] =
{ SFE_INTERNAL , "Unspecified internal error." }, { SFE_INTERNAL , "Unspecified internal error." },
{ SFE_BAD_CONTROL_CMD , "Bad command passed to function sf_command()." }, { SFE_BAD_CONTROL_CMD , "Bad command passed to function sf_command()." },
{ SFE_BAD_ENDIAN , "Bad endian-ness. Try default endian-ness" }, { 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_CHANNEL_COUNT , "Too many channels specified." },
{ SFE_BAD_SEEK , "Internal psf_fseek() failed." }, { 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_BAD_NAME , "Error in MAT4 file. No variable name." },
{ SFE_MAT4_NO_SAMPLERATE , "Error in MAT4 file. No sample rate." }, { 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_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_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_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_NO_PVF1 , "Error in PVF file. No PVF1 marker." },
{ SFE_PVF_BAD_HEADER , "Error in PVF file. Bad header." }, { 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 ; psf->norm_float = (datasize) ? SF_TRUE : SF_FALSE ;
return old_value ; 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 : case SFC_SET_NORM_DOUBLE :
old_value = psf->norm_double ; old_value = psf->norm_double ;
psf->norm_double = (datasize) ? SF_TRUE : SF_FALSE ; 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* const char*
sf_get_string (SNDFILE *sndfile, int str_type) sf_get_string (SNDFILE *sndfile, int str_type)
{ SF_PRIVATE *psf ; { SF_PRIVATE *psf ;

View File

@ -30,14 +30,7 @@
#define SNDFILE_1 #define SNDFILE_1
#include <stdio.h> #include <stdio.h>
#include <sys/types.h>
/* For the Metrowerks CodeWarrior Pro Compiler (mainly MacOS) */
#if (defined (__MWERKS__))
#include <unix.h>
#else
#include <sys/types.h>
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -128,6 +121,8 @@ enum
enum enum
{ SFC_GET_LIB_VERSION = 0x1000, { SFC_GET_LIB_VERSION = 0x1000,
SFC_GET_LOG_INFO = 0x1001, SFC_GET_LOG_INFO = 0x1001,
SFC_GET_CURRENT_SF_INFO = 0x1002,
SFC_GET_NORM_DOUBLE = 0x1010, SFC_GET_NORM_DOUBLE = 0x1010,
SFC_GET_NORM_FLOAT = 0x1011, SFC_GET_NORM_FLOAT = 0x1011,
@ -290,14 +285,20 @@ enum
typedef struct SNDFILE_tag SNDFILE ; typedef struct SNDFILE_tag SNDFILE ;
/* The following typedef is system specific and is defined when libsndfile is. /* 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), ** compiled. sf_count_t can be one of loff_t (Linux), off_t (*BSD), off64_t
** off64_t (Solaris), __int64_t (Win32) etc. ** (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 ; typedef @TYPEOF_SF_COUNT_T@ sf_count_t ;
#define SF_COUNT_MAX @SF_COUNT_MAX@ #define SF_COUNT_MAX @SF_COUNT_MAX@
#endif
/* A pointer to a SF_INFO structure is passed to sf_open_read () and filled in. /* 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 ** 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) ; 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. /* Functions for retrieving and setting string data within sound files.
** Not all file types support this features; AIFF and WAV do. For both ** 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 ** functions, the str_type parameter must be one of the SF_STR_* values

View File

@ -199,20 +199,26 @@ voc_read_header (SF_PRIVATE *psf)
psf->endian = SF_ENDIAN_LITTLE ; psf->endian = SF_ENDIAN_LITTLE ;
while (1) 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) switch (block_type)
{ case VOC_ASCII : { 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) ; case VOC_REPEAT :
psf->header [size] = 0 ; offset += psf_binheader_readf (psf, "e32", &size, &count) ;
psf_log_printf (psf, " text : %s\n", psf->header) ; psf_log_printf (psf, " Repeat : %d\n", count) ;
} ;
continue ; continue ;
case VOC_SOUND_DATA : 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) ; psf_log_printf (psf, "offset: %d size: %d sum: %d filelength: %D\n", offset, size, offset + size, psf->filelength) ;
return SFE_VOC_BAD_SECTIONS ; 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, "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) ; psf_log_printf (psf, "offset: %d size: %d sum: %d filelength: %D\n", offset, size, offset + size, psf->filelength) ;
return SFE_VOC_BAD_SECTIONS ; return SFE_VOC_BAD_SECTIONS ;
@ -869,10 +875,3 @@ BLOCK 9 - data block that supersedes blocks 1 and 8.
Data is stored left, right 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
*/

View File

@ -226,7 +226,7 @@ w64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
bytesread += psf_binheader_readf (psf, "e8", &chunk_size) ; 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) ; psf_log_printf (psf, "riff : %D (should be %D)\n", chunk_size, psf->filelength) ;
else else
psf_log_printf (psf, "riff : %D\n", chunk_size) ; 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) ; psf_fseek (psf, 0, SEEK_SET) ;
/* riff marker, length, wave and 'fmt ' markers. */ /* 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 ; subformat = psf->sf.format & SF_FORMAT_SUBMASK ;

100
src/wav.c
View File

@ -65,6 +65,15 @@
#define elmo_MARKER (MAKE_MARKER ('e', 'l', 'm', 'o')) #define elmo_MARKER (MAKE_MARKER ('e', 'l', 'm', 'o'))
#define cart_MARKER (MAKE_MARKER ('c', 'a', 'r', 't')) #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 ISFT_MARKER (MAKE_MARKER ('I', 'S', 'F', 'T'))
#define ICRD_MARKER (MAKE_MARKER ('I', 'C', 'R', 'D')) #define ICRD_MARKER (MAKE_MARKER ('I', 'C', 'R', 'D'))
#define ICOP_MARKER (MAKE_MARKER ('I', 'C', 'O', 'P')) #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_close (SF_PRIVATE *psf) ;
static int wav_subchunk_parse (SF_PRIVATE *psf, int chunk) ; 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_smpl_chunk (SF_PRIVATE *psf, unsigned int chunklen) ;
static int wav_read_acid_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) ; 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) ; psf_log_printf (psf, " %M\n", chunk) ;
break ; break ;
case data_MARKER: case data_MARKER :
psf_log_printf (psf, " %M inside a LIST block??? Backing out.\n", chunk) ; psf_log_printf (psf, " %M inside a LIST block??? Backing out.\n", chunk) ;
/* Jump back four bytes and return to caller. */ /* Jump back four bytes and return to caller. */
psf_binheader_readf (psf, "j", -4) ; 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) ; psf_log_printf (psf, " %M : %d\n", chunk, dword) ;
break ; break ;
case exif_MARKER :
psf_log_printf (psf, " %M\n", chunk) ;
bytesread += exif_subchunk_parse (psf, length - bytesread) ;
break ;
default : default :
psf_binheader_readf (psf, "4", &dword) ; psf_binheader_readf (psf, "4", &dword) ;
bytesread += sizeof (dword) ; bytesread += sizeof (dword) ;
@ -1598,7 +1613,7 @@ wav_read_acid_chunk (SF_PRIVATE *psf, unsigned int chunklen)
return 0 ; return 0 ;
} /* wav_read_acid_chunk */ } /* wav_read_acid_chunk */
int static int
wav_read_bext_chunk (SF_PRIVATE *psf, unsigned int chunksize) wav_read_bext_chunk (SF_PRIVATE *psf, unsigned int chunksize)
{ {
SF_BROADCAST_INFO* b ; SF_BROADCAST_INFO* b ;
@ -1667,10 +1682,81 @@ wav_write_bext_chunk (SF_PRIVATE *psf)
return 0 ; return 0 ;
} /* wav_write_bext_chunk */ } /* 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. ** Exif specification for audio files, at JEITA CP-3451 Exif 2.2 section 5
** The arch-tag line is a file identity tag for the GNU Arch ** (Exif Audio File Specification) http://www.exif.org/Exif2-2.PDF
** revision control system.
**
** arch-tag: 9c551689-a1d8-4905-9f56-26a204374f18
*/ */
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 */

View File

@ -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

View File

@ -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

View File

@ -36,14 +36,15 @@
#define BUFFER_LEN (1<<10) #define BUFFER_LEN (1<<10)
#define LOG_BUFFER_SIZE 1024 #define LOG_BUFFER_SIZE 1024
static void float_norm_test (const char *filename) ; static void float_norm_test (const char *filename) ;
static void double_norm_test (const char *filename) ; static void double_norm_test (const char *filename) ;
static void format_tests (void) ; static void format_tests (void) ;
static void calc_peak_test (int filetype, const char *filename) ; static void calc_peak_test (int filetype, const char *filename) ;
static void truncate_test (const char *filename, int filetype) ; static void truncate_test (const char *filename, int filetype) ;
static void instrument_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 channel_map_test (const char *filename, int filetype) ;
static void broadcast_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 /* Force the start of this buffer to be double aligned. Sparc-solaris will
** choke if its not. ** choke if its not.
@ -130,6 +131,11 @@ main (int argc, char *argv [])
test_count++ ; test_count++ ;
} ; } ;
if (do_all || strcmp (argv [1], "current_sf_info") == 0)
{ current_sf_info_test ("current.wav") ;
test_count++ ;
} ;
if (test_count == 0) if (test_count == 0)
{ printf ("Mono : ************************************\n") ; { printf ("Mono : ************************************\n") ;
printf ("Mono : * No '%s' test defined.\n", argv [1]) ; printf ("Mono : * No '%s' test defined.\n", argv [1]) ;
@ -870,11 +876,52 @@ channel_map_test (const char *filename, int filetype)
puts ("ok") ; puts ("ok") ;
} /* channel_map_test */ } /* 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
*/

View File

@ -30,25 +30,49 @@
#define DFT_SPEC_LENGTH (DFT_DATA_LENGTH / 2) #define DFT_SPEC_LENGTH (DFT_DATA_LENGTH / 2)
static void dft_magnitude (const double *data, double *spectrum) ; 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. ** Public functions.
*/ */
double 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 orig_spec [DFT_SPEC_LENGTH] ;
static double test_spec [DFT_SPEC_LENGTH] ; static double test_spec [DFT_SPEC_LENGTH] ;
double snr ; double snr ;
if (! orig || ! test) 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 ; return 1 ;
} ; } ;
if (len != DFT_DATA_LENGTH) 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 ; return 1 ;
} ; } ;
@ -68,7 +92,7 @@ dft_cmp (int linenum, double *orig, double *test, int len, double target_snr, in
snr = -500.0 ; snr = -500.0 ;
return snr ; return snr ;
} /* dft_cmp */ } /* dft_cmp_double */
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
** Quick dirty calculation of magnitude spectrum for real valued data using ** Quick dirty calculation of magnitude spectrum for real valued data using
@ -112,7 +136,7 @@ dft_magnitude (const double *data, double *spectrum)
} /* dft_magnitude */ } /* dft_magnitude */
static double 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 ; { double orig_max = 0.0, max_diff = 0.0 ;
int k ; int k ;
@ -128,10 +152,3 @@ calc_max_spectral_difference (double *orig, double *test)
return 20.0 * log10 (max_diff / orig_max) ; return 20.0 * log10 (max_diff / orig_max) ;
} /* calc_max_spectral_difference */ } /* 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
*/

View File

@ -1,30 +1,25 @@
/* /*
** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com> ** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
** **
** This program is free software; you can redistribute it and/or modify ** 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 ** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or ** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version. ** (at your option) any later version.
** **
** This program is distributed in the hope that it will be useful, ** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details. ** GNU General Public License for more details.
** **
** You should have received a copy of the GNU General Public License ** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software ** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#define DFT_DATA_LENGTH (2048) #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
*/

View File

@ -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 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) ; 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) ; +]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 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_data [DFT_DATA_LENGTH] ;
static float float_test [DFT_DATA_LENGTH] ;
static double double_data [DFT_DATA_LENGTH] ; static double double_data [DFT_DATA_LENGTH] ;
static short short_data [DFT_DATA_LENGTH] ; static short short_data [DFT_DATA_LENGTH] ;
static int int_data [DFT_DATA_LENGTH] ; static int int_data [DFT_DATA_LENGTH] ;
@ -162,9 +164,9 @@ main (int argc, char *argv [])
putchar ('\n') ; putchar ('\n') ;
/* Float int tests. */ /* 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") ; +] [+ (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 ; return 0 ;
@ -176,20 +178,13 @@ main (int argc, char *argv [])
static void static void
float_scaled_test (const char *filename, int allow_exit, int replace_float, int filetype, double target_snr) float_scaled_test (const char *filename, int allow_exit, int replace_float, int filetype, double target_snr)
{ static float float_orig [DFT_DATA_LENGTH] ; { SNDFILE *file ;
static float float_test [DFT_DATA_LENGTH] ;
SNDFILE *file ;
SF_INFO sfinfo ; SF_INFO sfinfo ;
int k ;
double snr ; double snr ;
print_test_name ("float_scaled_test", filename) ; print_test_name ("float_scaled_test", filename) ;
gen_windowed_sine_double (double_data, DFT_DATA_LENGTH, 1.0) ; gen_windowed_sine_float (float_data, DFT_DATA_LENGTH, 1.0) ;
for (k = 0 ; k < DFT_DATA_LENGTH ; k++)
float_orig [k] = double_data [k] ;
sfinfo.samplerate = SAMPLE_RATE ; sfinfo.samplerate = SAMPLE_RATE ;
sfinfo.frames = DFT_DATA_LENGTH ; 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__) ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ; 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) ; sf_close (file) ;
@ -218,10 +213,7 @@ float_scaled_test (const char *filename, int allow_exit, int replace_float, int
sf_close (file) ; sf_close (file) ;
for (k = 0 ; k < DFT_DATA_LENGTH ; k++) snr = dft_cmp_float (__LINE__, float_data, float_test, DFT_DATA_LENGTH, target_snr, allow_exit) ;
test_data [k] = float_test [k] ;
snr = dft_cmp (__LINE__, double_data, test_data, 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) ; 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) ; 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__) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ; 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__) ; 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) ; 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) ; 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 static void
[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test (const char * filename) [+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test (const char * filename)

View File

@ -74,7 +74,7 @@ exit_if_true (int test, const char *format, ...)
*/ */
[+ FOR io_type [+ 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 [+ ENDFOR io_type
+] +]
@ -261,7 +261,7 @@ static char octfilename [] = "error.dat" ;
[+ FOR io_type [+ FOR io_type
+]int +]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 ; { FILE *file ;
int k ; int k ;