-Thu May 21 16:11:03 CDT 2009
+Tue Nov 8 14:58:00 CST 2011
+2011-07-13 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/ogg_vorbis.c
+ Fix return value of SFC_SET_VBR_ENCODING_QUALITY command.
+
+ * doc/command.html
+ Document SFC_SET_VBR_ENCODING_QUALITY, SFC_GET/SET_LOOP_INFO and
+ SFC_GET_INSTRUMENT.
+
+ * NEWS README configure.ac doc/*.html
+ Updates for 1.0.25.
+
+2011-07-07 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sfconfig.h
+ Add handling for HAVE_SYS_WAIT_H.
+
+ * Makefile.am src/Makefile.am tests/Makefile.am
+ Add 'checkprograms' target.
+
+2011-07-05 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/common.h src/sndfile.c
+ Purge SF_ASSERT macro. Use standard C assert instead.
+
+ * src/paf.c src/common.h src/sndfile.c
+ Fix for Secunia Advisory SA45125, heap overflow (heap gets overwritten with
+ byte value of 0) due to integer overflow if PAF file handler.
+
+ * src/ima_adpcm.c src/ms_adpcm.c src/paf.c
+ Use calloc instead of malloc followed by memset.
+
+ * tests/utils.tpl
+ Clean up use of memset.
+
+2011-07-05 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/ogg.c
+ Fix log message.
+
+ * tests/format_check_test.c
+ Fix compiler warnings.
+
+2011-07-04 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sndfile.c
+ Fix error message for erro code SFE_ZERO_MINOR_FORMAT.
+
+ * tests/format_check_test.c
+ Add a test to for SF_FINFO format field validation.
+
+ * src/ogg.c src/ogg_vorbis.c src/ogg.h src/ogg_pcm.c src/ogg_speex.c
+ src/common.h src/Makefile.am
+ Move vorbis specific code to ogg_vorbis.c, add new files for handling PCM
+ and Speex codecs in an Ogg container. The later two are only enabled with
+ ENABLE_EXPERIMENTAL_CODE config variable.
+
+2011-06-28 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/strings.c
+ Clean up and refactor storage of SF_STR_SOFTWARE.
+
+2011-06-23 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sndfile.h.in doc/api.html
+ Fix definition of SF_STR_LAST and update SF_STR_* related docs. Thanks to
+ Tim van der Molen for the patch.
+
+2011-06-21 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * programs/sndfile-interleave.c
+ Fix handling of argc. Thanks to Marius Hennecke.
+
+ * src/wav_w64.c
+ Accept broken WAV files with blockalign == 0. Thanks to Olivier Tristan for
+ providing example files.
+
+ * src/wav.c
+ Jump over 'FLLR' chunks.
+
+2011-06-14 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sndfile.h.in
+ Fix -Wundef warning due to ENABLE_SNDFILE_WINDOWS_PROTOTYPES.
+
+ * configure.ac
+ Add -Wundef to CFLAGS.
+
+ * src/ogg.c
+ Fix -Wunder warning.
+
+2011-05-18 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac
+ Use int64_t instead of off_t when they are the same size.
+
+ * src/Makefile.am tests/Makefile.am
+ Use check_PROGRAMS instead of noinst_PROGRAMS where appropriate.
+
+2011-05-08 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/wav.c
+ Don't allow unknown and/or un-editable chunks to prevent the file from being
+ opened in SFM_RDWR mode.
+
+2011-04-25 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * tests/format_check_test.c
+ Fix segfault in test program.
+
+2011-04-25 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * tests/format_check_test.c
+ New test program to check to make sure that sf_open() and sf_check_format()
+ agree as to what is a valid program.
+
+ * tests/Makefile.am tests/test_wrapper.sh.in
+ Hook into build and test runner.
+
+ * src/sndfile.c
+ Fix some sf_format_check() problems. Thanks to Charles Van Winkle for the
+ notification.
+
+2011-04-06 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/caf.c
+ Add validation to size of 'data' chunk and fix size of written 'data'
+ chunk. Thanks to Michael Pruett for reporting this.
+
+2011-03-28 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/* tests/* programs/*
+ Fix a bunch of compiler warnings with gcc-4.6.
+
+2011-03-25 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * tests/util.tpl
+ Add NOT macro to util.h.
+
+ * src/strings.c
+ Fix handling of SF_STR_SOFTWARE that resulted in a segfault due to calling
+ strlen() on an unterminated string. Thanks to Francois Thibaud for reporting
+ this problem.
+
+ * tests/string_test.c
+ Add test for SF_STR_SOFTWARE segfault bug.
+
+ * configure.ac
+ Sanitize FLAC_CFLAGS value supplied by pkg-config which returns a value of
+ '-I${includedir}/FLAC'. However FLAC also provides an include file
+ <assert.h> which clashes with the Standard C header of the same name. The
+ solution is strip the 'FLAC' part off the end and include all FLAC headers
+ as <FLAC/header.h>.
+
+ * configure.ac src/Makefile.am
+ Use non-recursive make in src/ directory.
+
+2011-03-23 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * NEWS README docs/*.html
+ Updates for 1.0.24 release.
+
+2011-03-22 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac
+ Fix up usage of sed (should not assume GNU sed).
+
+ * M4/add_(c|cxx)flags.m4
+ Test flags in isolation.
+
+ * tests/cpp_test.cc
+ Fix a broken test (test segfaults). Report by Dave Flogeras.
+
+2011-03-21 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * programs/common.[ch]
+ Add function program_name() which returns the program name minus the path
+ from argv [0].
+
+ * programs/*.c programs/Makefile.am
+ Use program_name() where appropriate. Fix build.
+
+2011-03-20 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/wav.c
+ For u-law and A-law files, write an 18 byte 'fmt ' chunk instead of a 16
+ byte one. Win98 accepts files with a 16 but not 18 byte 'fmt' chunk. Later
+ version accept 18 byte but not 16 byte.
+
+2011-03-15 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * doc/FAQ.html
+ Add examples for question 12.
+
+ * doc/libsndfile.css.in
+ Add tweaks for h4 element.
+
+ * doc/api.html
+ Add documentation for virtual I/O functionality. Thanks to Uli Franke.
+
+ * tests/util.tpl
+ Add static inline functions sf_info_clear() and sf_info_setup().
+
+ * tests/(alaw|dwvw|ulaw)_test.c
+ Use functions sf_info_clear() and sf_info_setup().
+
+2011-03-08 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac
+ Fail more gracefully if pkg-config is missing. Suggestion from Brian
+ Willoughby.
+
+2011-02-27 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/common.c
+ Use size_t instead of int for size params with varargs.
+
+2011-02-09 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * doc/index.html
+ Update supported platforms with more Debian platforms and Android.
+
+2011-01-27 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sndfile.hh
+ Add an LPCWSTR version of the SndfileHandle constructor to the SndfileHandle
+ class definition. Thanks to Eric Eizenman for pointing out this was missing.
+
+ * tests/cpp_test.cc
+ Add test for LPCWSTR version of the SndfileHandle constructor.
+
+2011-01-19 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * programs/sndfile-play.c
+ Remove cruft.
+
+2010-12-01 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sndfile.hh
+ Add methods rawHandle() and takeOwnership(). Thanks to Tim Blechmann for
+ the patch.
+
+ * tests/cpp_test.cc
+ Add tests for above two methods. Also supplied by Tim Blechmann.
+
+2010-11-11 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * doc/api.html
+ Add mention of use of sf_strerror() when sf_open() fails.
+
+2010-11-01 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac
+ Make TYPEOF_SF_COUNT_T int64_t where possible. This may fix problems where
+ people are compiling on a 64 bit system with the GCC -m32 flag.
+
+ * src/sndfile.h.in
+ Fix comments on sf_count_t.
+
+2010-10-26 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/aiff.c
+ Handle non-zero offset field in SSND chunk. Thanks to Michael Chinen.
+
+2010-10-20 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac
+ Sed fix for FreeBSD. Thanks Tony Theodore.
+
+2010-10-14 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * shave.in M4/shave.m4
+ Fix shave invocation of windres compiler. Thanks Damien Lespiau (upstream
+ shave author).
+
+ * configure.ac M4/shave.m4 shave-libtool.in shave.in
+ Switch from shave to automake-1.11's AM_SILENT_RULES.
+
+2010-10-13 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * shave-libtool.in shave.in
+ Sync to upstream version.
+
+ * src/rf64.c
+ More work to make the parser more robust and accepting of mal-formed files.
+
+2010-10-12 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/common.h
+ Add functions psf_strlcpy() and psf_strlcat().
+
+ * src/broadcast.c src/sndfile.c src/strings.c src/test_main.c
+ src/test_main.h src/test_strncpy_crlf.c
+ Use functions psf_strlcpy() and psf_strlcat() as appropriate.
+
+ * tests/string_test.c
+ Add tests for SF_STR_GENRE and SF_STR_TRACKNUMBER.
+
+ * src/rf64.c
+ Fix size of 'ds64' chunk when writing RF64.
+
+2010-10-10 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * programs/*.c
+ Add the libsndfile version to the usage message of all programs.
+
+2010-10-10 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac src/version-metadata.rc.in src/Makefile.am
+ Add version string resources to the windows DLL.
+
+ * doc/api.html
+ Update to add missing SF_FORMAT_* values. Closed Debian bug #545257.
+
+ * NEWS README configure.ac doc/*.html
+ Updates for 1.0.23 release.
+
+2010-10-09 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * tests/pedantic-header-test.sh.in
+ Handle unusual values of CC environment variable.
+
+ * src/rf64.c
+ Minor tweaks and additional sanity checking.
+
+ * src/Makefile.am src/binheader_writef_check.py
+ Use python 2.6.
+
+2010-10-08 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sndfile.hh
+ Add a missing 'inline' before a constructor defintion.
+
+2010-10-06 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/common.h
+ Add macro NOT.
+
+ * src/rf64.c
+ Minor tweaks.
+
+ * Makefile.am */Makefile.am
+ Add *~ to CLEANFILES.
+
+2010-10-05 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sndfile.c
+ Fix a typo in the error string for SFE_OPEN_PIPE_RDWR. Thanks to Charles
+ Van Winkle for the report.
+
+2010-10-04 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/flac.c src/ogg.c src/sndfile.h.in src/strings.c src/wav.c
+ Add ability to read/write tracknumber and genre to flac/ogg/wav files.
+ Thanks to Matti Nykyri for the patch.
+
+ * src/common.h src/broadcast.c src/strings.c
+ Add function psf_safe_strncpy() and use where appropriate.
+
+2010-10-04 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * NEWS README configure.ac doc/*.html
+ Updates for 1.0.22 release.
+
+2010-10-03 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/common.h src/broadcast.c src/rf64.c src/sndfile.c src/wav.c
+ Rewrite of SF_BROADCAST_INFO handling.
+
+ * src/test_broadcast_var.c tests/command_test.c
+ Tweak SF_BROADCAST_INFO tests.
+
+ * src/test_broadcast_var.c
+ Fix OSX stack check error.
+
+2010-09-30 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sds.c
+ Set sustain_loop_end to 0 as suggested by Brian Lewis.
+
+2010-09-29 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sds.c
+ Make sure the correct frame count gets written into the header.
+
+ * tests/write_read_test.tpl
+ Don't allow SDS files to have a long frame count.
+
+2010-09-17 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sds.c
+ Apply a pair of patches from Brian Lewis to fix the packet number location
+ and the checksum.
+
+2010-09-10 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/aiff.c src/file_io.c src/ogg.c src/rf64.c src/sndfile.c
+ src/strings.c src/test_audio_detect.c src/test_strncpy_crlf.c
+ src/wav.c tests/pcm_test.tpl
+ Fix a bunch of minor issues found using static analysis.
+
+2010-08-23 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/test_broadcast_var.c
+ New file containing tests for broadcast_set_var().
+
+ * src/Makefile.am src/test_main.[ch]
+ Hook test_broadcast_var.c into tests.
+
+2010-08-22 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/broadcast.c src/common.(c|h)
+ Move function strncpy_crlf() to src/common.c so the function can be tested
+ in isolation.
+
+ * src/test_strncpy_crlf.c
+ New file.
+
+ * src/Makefile.am src/test_main.[ch]
+ Hook test_strncpy_crlf.c into tests.
+
+2010-08-18 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/common.h
+ Move code around to make comments make sense.
+
+ * src/broadcast.c
+ Add debugging code that is disabled by default.
+
+2010-08-02 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/flac.c
+ When the file meta data says the file has zero frames set psf->sf.frames
+ to SF_COUNT_MAX. Fixes Debian bug #590752.
+
+ * programs/sndfile-info.c
+ Print 'unknown' if frame count == SF_COUNT_MAX.
+
+2010-06-27 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sndfile.c
+ Only support writing mono SVX files. Multichannel SVX files are not
+ interleaved and there is no support infrastructure to cache and write
+ multiple channels to create a non-interleaved file.
+
+ * src/file_io.c
+ Don't call close() on a file descriptor of -1. Thanks to Jeremy Friesner
+ for the bug report.
+
+2010-06-09 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/common.h
+ Add macro SF_ASSERT.
+
+ * src/sndfile.c
+ Use SF_ASSERT to ensure sizeof (sf_count_t) == 8.
+
+ * src/svx.c
+ Add support for reading and writing stereo SVX files.
+
+2010-05-07 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac
+ When compiling with x86_64-w64-mingw32-gcc link with -static-libgcc flags.
+
+ * programs/common.c programs/sndfile-metadata-set.c
+ Update metadata after the audio data is copied. Other minor fixes. Patch
+ from Marius Hennecke.
+
+2010-05-04 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/nist.c
+ Fix a regression reported by Hugh Secker-Walker.
+
+ * src/api.html
+ Add comment about sf_open_fd() not working on Windows if the application
+ and the libsndfile DLL are linked to different versions of the Microsoft
+ C runtime DLL.
+
+2010-04-23 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * tests/pedantic-header-test.sh.in
+ Fix 'make distcheck'.
+
+2010-04-21 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * tests/pedantic-header-test.sh.in
+ New file to test whether sndfile.h can be compiled with gcc's -pedantic
+ flag.
+
+ * configure.ac tests/test_wrapper.sh.in
+ Hook pedantic-header-test into test suite.
+
+ * src/sndfile.h.in
+ Fix -pedantic warning.
+
+2010-04-19 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * programs/sndfile-salvage.c programs/Makefile.am
+ New program to salvage the audio data from WAV/WAVEX/AIFF files which are
+ greater than 4Gig in size.
+
+2010-04-09 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * programs/sndfile-convert.c
+ Fix valgrind warning.
+
+2010-04-06 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * programs/sndfile-cmp.c
+ When files differ in the PCM data, also print the difference offset.
+ Minor cleanup.
+
+2010-03-19 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/aiff.c
+ Don't use the 'twos' marker for 24 and 32 bit PCM, use 'in24' and 'in32'
+ instead. Thanks to Paul Davis (Ardour) for this suggestion.
+
+2010-02-28 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac
+ Clean up configure report.
+
+ * tests/utils.tpl
+ Add functions test_read_raw_or_die and test_write_raw_or_die.
+
+ * tests/rdwr_test.(def|tpl) tests/Makefile.am
+ Add new test program and hook into build.
+
+ * src/sndfile.c
+ Fix minor issues with sf_read/write_raw(). Bug reported by Milan Křápek.
+
+ * tests/test_wrapper.sh.in
+ Add rdwr_test to the test wrapper script.
+
+2010-02-22 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac
+ Remove -fpascal-strings from OSX's OS_SPECIFIC_CFLAGS.
+
+ * programs/common.[ch] programs/sndfile-metadata-set.c
+ Apply a patch from Robin Gareus allowing the setting of the time reference
+ field of the BEXT chunk.
+
+2010-02-06 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/ima_adpcm.c
+ Add a fix from Jonatan Liljedahl to handle predictor overflow when decoding
+ IMA4.
+
+2010-01-26 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sndfile.hh
+ Add a constructor which takes an existing file descriptor and then calls
+ sf_open_fd(). Patch from Sakari Bergen.
+
+2010-01-10 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * programs/sndfile-deinterleave.c programs/sndfile-interleave.c
+ Improve usage messages.
+
+2010-01-09 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/id3.c src/Makefile.am
+ Add new file src/id3.c and hook into build.
+
+ * src/sndfile.c src/common.h
+ Detect and skip and ID3 header at the start of the file.
+
+2010-01-07 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * programs/common.c
+ Fix update_strings() copyright, comment, album and license are correctly
+ written. Thanks to Todd Allen for reporting this.
+
+ * man/Makefile.am
+ Change GNU makeism to something more widely supported. Thanks to Christian
+ Weisgerber for reporting this.
+
+ * configure.ac programs/Makefile.am programs/sndfile-play.c
+ Apply patch from Christian Weisgerber and Jacob Meuserto add support for
+ OpenBSD's sndio.
+
+2010-01-05 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * doc/api.html
+ Discourage the use of sf_read/write_raw().
+
+2009-12-28 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac
+ Test for Unix pipe() and waitpid() functions.
+
+ * src/sfconfig.h tests/pipe_test.tpl
+ Disable pipe_test if pipe() and waitpid() aren't available.
+
+2009-12-16 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac src/Makefile.am src/create_symbols_file.py
+ src/make-static-lib-hidden-privates.sh
+ Change name of generated file src/Symbols.linux to Symbols.gnu-binutils and
+ and use the same symbols file for other systems which use GNU binutils like
+ Debian's kfreebsd.
+
+ * M4/shave.m4 shave.in
+ Update shave files from upstream.
+
+2009-12-15 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * man/sndfile-metadata-get.1
+ Fix typo.
+
+ * man/sndfile-interleave.1 man/Makefile.am
+ New man page.
+
+2009-12-13 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/ogg.c
+ When decoding to short or int, clip the decoded signal to [-1.0, 1.0] if
+ its too hot. Thanks to Dmitry Baikov for suggesting this.
+
+ * NEWS README doc/*.html
+ Updates for 1.0.21.
+
+2009-12-09 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * programs/sndfile-jackplay.c man/sndfile-jackplay.1
+ Remove these which will now be in found in the sndfile-tools package.
+
+ * programs/Makefile.am man/Makefile.am
+ Remove build rules for sndfile-jackplay.
+
+ * configure.ac
+ Remove detection of JACK Audio Connect Kit.
+
+ * programs/sndfile-concat.c man/sndfile-concat.1
+ Add new program with man page.
+
+ * man/Makefile.am programs/Makefile.am
+ Hook sndfile-concat into build system.
+
+2009-12-08 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * tests/error_test.c
+ Don't terminate when sf_close() returns zero in error_close_test().
+ It seems that Windows 7 behaves differently from earlier versions of
+ Windows.
+
+2009-12-03 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac M4/*.m4
+ Rename all custom macros from AC_* to MN_*.
+
+ * programs/sndfile-interleave.c
+ Make it actually work.
+
+2009-12-02 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * doc/*.html configure.ac
+ Corrections and clarifications courtesy of Robin Forder.
+
+ * programs/sndfile-convert.c programs/common.[ch]
+ Move some code from convert to common for reuse.
+
+ * programs/sndfile-interleave.c programs/sndfile-interleave.c
+ Add new programs sndfile-interleave and sndfile-deinterleave.
+
+ * programs/Makefile.am
+ Hook new programs into build.
+
+2009-12-01 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/create_symbols_file.py tests/stdio_test.c tests/win32_test.c
+ Minor OS/2 tweaks as suggested by David Yeo.
+
+ * tests/multi_file_test.c
+ Fix file creation flags on windows. Thanks to Bruce Sharpe.
+
+ * src/sf_unistd.h
+ Set all group and other file create permssions to zero.
+
+ * tests/win32_test.c
+ Add a new test.
+
+2009-11-30 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * doc/print.css doc/*.html
+ Add a print stylesheet and update all HTML documents to reference it.
+ Thanks to Aditya Bhargava for suggesting this.
+
+ * doc/index.html
+ Minor corrections.
+
+2009-11-29 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * sndfile.pc.in
+ Add a Libs.private entry to assist with static linking.
+
+2009-11-28 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/make-static-lib-hidden-privates.sh src/Makefile.am
+ Add a script to hide all non-public symbols in the libsndfile.a static
+ library.
+
+2009-11-22 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * tests/locale_test.c
+ Correct usage of ENABLE_SNDFILE_WINDOWS_PROTOTYPES.
+
+2009-11-20 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/windows.c
+ Correct usage of ENABLE_SNDFILE_WINDOWS_PROTOTYPES.
+
+2009-11-16 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * programs/sndfile-convert.c
+ Allow the program to read from stdin by specifying '-' on the command line
+ as the input file.
+
+ * src/sndfile.h.in
+ Hash define ENABLE_SNDFILE_WINDOWS_PROTOTYPES to 1 for greater safety.
+
+ * tests/virtual_io_test.c
+ Add a PAF/PCM_24 test and verify the file length is not negative
+ immediately after openning the file for write.
+
+2009-10-18 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/wav.c
+ When writing loop lengths, adjust the end position by one to make up for
+ Microsoft's screwed up spec. Thanks to Olivier Tristan for the patch.
+
+2009-10-14 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/flac.c
+ Apply patch from Uli Franke allowing FLAC files to be encoded at any sample
+ rate.
+
+2009-10-09 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/nist.c
+ Fix parsing of odd ulaw encoded file provided by Jan Silovsky.
+
+ * configure.ac
+ Insist on libvorbis >= 1.2.3. Earlier verions have bugs that cause the
+ libsndfile test suite to fail on MIPS, PowerPC and others.
+ See: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=549899
+
+2009-10-06 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * man/sndfile-convert.1
+ Fix warning from Debian's lintian checks.
+
+ * man/sndfile-cmp.1 man/sndfile-jackplay.1 man/sndfile-metadata-get.1
+ man/Makefile.am
+ Add three new minimal manpages and hook into build.
+
+2009-10-05 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * tests/test_wrapper.sh.in
+ Don't run cpp_test on x86_64-w64-mingw32.
+
+2009-09-28 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * tests/utils.tpl
+ On windows, make sure the open() function doesn't get called with a third
+ parameter of 0 which fails for no good reason. Also make sure this third
+ parameter doesn't get called with S_IRGRP when compiling for windows because
+ Wine complains.
+
+ * src/sndfile.hh
+ Add a SndfileHandle constructor for windows that takes a 'const wchar_t *'
+ string.
+
+ * doc/FAQ.html
+ Add Q/A : I'm cross compiling libsndfile for another platform. How can I
+ run the test suite?
+
+ * src/create_symbols_file.py src/Makefile.am
+ Add Symbols.static target, a list of symbols, one per line.
+
+2009-09-27 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * tests/test_wrapper.sh.in
+ Update to allow all tests to be gathered up into a testsuite tarball and
+ then be run using this script.
+
+ * build-test-tarball.mk.in
+ Add a Make script to build a tarball of all the test binaries and the test
+ wrapper script. This is useful for cross compiling; you can build the
+ binaries, build test test tarball and transfer the test tarball to the
+ target machine for testing.
+
+2009-09-26 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/common.h src/*.c
+ Modify SF_FILE struct to allow it to carry either 8-bit or 16-bit strings
+ for the file path, directory and name. Fixes for this change throughout.
+
+ * src/windows.c src/Makefile.am
+ New file defining new windows only public function sf_wchar_open() which
+ takes a 'const wchar_t *' string (LPCWSTR) for the file name parameter.
+
+ * src/sndfile.h.in
+ Add SF_CHANNEL_MAP_ABISONIC_* entries.
+ Add windows only defintion for sf_wchar_open().
+
+ * src/create_symbols_file.py
+ Add sf_wchar_open() to the list of public symbols (windows only).
+
+ * tests/locale_test.c
+ Add a wchar_test() to test sf_wchar_open().
+
+2009-09-25 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/common.h src/*.c
+ Split file stuff into PSF_FILE struct within the SF_PRIVATE struct.
+
+2009-09-23 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/aiff.c src/voc.c
+ When a byte is needed, use unsigned char.
+
+ * src/ima_oki_adpcm.c src/broadcast.c src/test_ima_oki_adpcm.c
+ Include sfconfig.h to prevent compile errors with MinGW compilers.
+
+ * configure.ac
+ Remove AM_CONFIG_HEADER due to warnings from autoconf 2.64.
+
+ * tests/locale_test.c
+ Update to work with xx_XX.UTF-8 style locales. Refactoring.
+
+2009-09-22 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac
+ Set __USE_MINGW_ANSI_STDIO to 1 when compiling using MinGW compilers.
+ Remove unneeded AC_SUBST.
+ Report Host CPU/OS/vendor.
+
+2009-09-19 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sndfile.c
+ Fix error message string.
+
+ * src/flac.c
+ Add 88200 to the list of supported sample rates.
+
+ * src/ogg.c
+ Fix compiler warning when using gcc-4.5.0.
+
+ * programs/sndfile-info.c tests/utils.tpl
+ Remove WIN32 snprintf #define.
+
+ * src/ima_adpcm.c
+ Fix minor bug in aiff_ima_encode_block. Thanks to Denis Fileev for finding
+ this.
+
+2009-09-16 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/caf.c
+ Use the correct C99 format specifier for int64_t.
+
+ * M4/endian.m4
+ Fix detection of CPU endian-ness when cross compiling. Thanks to Pierre
+ Ossman for the bug report.
+
+ * src/caf.c src/sndfile.c
+ Fix reading and writing of PEAK chunks in CAF files.
+
+ * tests/peak_chunk_test.c tests/test_wrapper.sh.in
+ Run peak_chunk_test on CAF files.
+
+2009-09-15 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/aiff.c src/wav.c
+ Use the correct C99 format specifier for int64_t.
+
+2009-08-30 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/rf64.c src/sndfile.c src/wav.c src/wav_w64.h
+ Apply a patch (massaged slightly) from Uli Franke adding handling of the
+ BEXT chunk in RF64 files.
+
+ * tests/command_test.c
+ Update channel_map_test() function so WAV test passes.
+
+ * src/rf64.c
+ Add channel mapping and ambisonic support.
+
+ * src/sndfile.h
+ Add comments showing correspondance between libsndfile channel map
+ defintiions and those used by Apple and MS.
+
+ Add handling of reading/writing channel map info.
+
+ * tests/command_test.c tests/test_wrapper.sh.in
+ Update channel map tests.
+
+2009-07-29 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/common.h
+ Add function psf_isprint() a replacement for the standard C isprint()
+ function which ignores any locale settings and treats all input as ASCII.
+
+ * src/(aiff|common|rf64|sd2|strings|svx|wav).c
+ Use psf_isprint() instead of isprint().
+
+2009-07-13 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/command.c
+ Add string descriptions for SF_FORMAT_RF64 and SF_FORMAT_MPC2K.
+
+2009-06-30 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * programs/sndfile-play.c
+ Allow use of Open Sound System audio output under FreeBSD.
+
+2009-06-24 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac
+ Add patch from Conrad Parker to add --disable-jack.
+
+2009-05-28 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/alaw.c src/float32.c src/htk.c src/pcm.c src/sds.c src/ulaw.c
+ Fix bugs where invalid files can cause a divide by zero error (SIGFPE).
+ Thanks to Sami Liedes for reporting this a Debian bug #530831.
+
+2009-05-26 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/chanmap.[ch]
+ New files for channel map decoding/encoding.
+
+2009-05-25 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * configure.ac src/sndfile.h.in
+ Fix MSVC definition of sf_count_t.
+
+2009-05-24 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/wav_w64.[ch]
+ Add wavex_channelmask to WAV_PRIVATE struct and add a function to convert
+ an array of SF_CHANNEL_MASK_* values into a bit mask for use in WAV files.
+
+ * src/wav.c
+ Add ability to write the channel mask.
+
+2009-05-23 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * programs/sndfile-info.c
+ Add -c command line option to dump the channel map information.
+
+ * src/wav_w64.c
+ Don't bail from parser if channel map bitmask is faulty.
+
+ * src/common.h src/sndfile.c
+ Remove error code SFE_W64_BAD_CHANNEL_MAP which is not needed any more.
+
+ * src/sndfile.c
+ On SFC_SET_CHANNEL_MAP_INFO pass the channel map command down to container's
+ command handler.
+
+2009-05-22 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/sndfile.h.in src/common.h src/sndfile.c src/wav_w64.c
+ Apply a patch from Lennart Poettering (PulseAudio) to allow reading of
+ channel data in WAV and W64 files.
+ Add a test for the above.
+
+2009-05-20 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/FAQ.html
+ Update the section about pre-compiled binaries for Win64.
+
+2009-05-14 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/common.h src/test_conversions.c
+ Be more careful when including <stdint.h> so compiling on pre-C99 platforms
+ (hello Slowlaris) might actually work.
+
+ * NEWS README doc/*.html
+ Updates for 1.0.20.
+
+2009-04-21 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/voc.c
+ Fix a bug whereby opening a specially crafted VOC file could result in a
+ heap overflow. Thanks to Tobias Klein (http://www.trapkit.de) for reporting
+ this issue.
+
+ * src/aiff.c
+ Fix potential (heap) buffer overflow when parsing 'MARK' chunk.
+
+2009-04-12 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * tests/stdin_test.c
+ Check psf->error after opening file.
+
+ * src/file_io.c
+ Fix obscure seeking bug reported by Hugh Secker-Walker.
+
+ * tests/utils.tpl
+ Add check of sf_error to test_open_file_or_die().
+
+ * src/sndfile.c
+ Clear error if opening resource fork fails.
+
+2009-04-11 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * tests/alaw_test.c tests/locale_test.c tests/ulaw_test.c
+ Cleanup output.
+
+2009-03-25 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/float32.c
+ Fix f2s_clip_array.
+
+2009-03-24 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/float32.c
+ In host_read_f2s call convert instead of f2s_array.
+
+ * src/ima_adpcm.c
+ Remove dead code.
+
+ * src/test_ima_oki_adpcm.c examples/generate.c tests/dither_test.c
+ tests/dwvw_test.c tests/fix_this.c tests/generate.c
+ tests/multi_file_test.c
+ Minor fixes.
+
+2009-03-23 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * M4/shave.m4 shave.in
+ Pulled update from upstream.
+
+2009-03-19 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * doc/api.html
+ Add pointers to example programs in source code tarball.
+
+2009-03-17 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/common.h
+ Define SF_PLATFORM_S64 for non-gcc compilers with 'long long' type.
+
+ * configure.ac
+ Add documentation for --disable-external-libs and improve error handling
+ for that option.
+
+ * src/sndfile.c src/sndfile.h.in src/create_symbols_file.py
+ Add public function sf_version_string.
+
+ * tests/sfversion.c
+ Test function sf_version_string.
+
+ * M4/shave.m4 shave-libtool.in shave.in
+ Add new files from 'git clone git://git.lespiau.name/shave'.
+
+ * configure.ac
+ Enable shave.
+
+ * src/Makefile.am src/binheader_writef_check.py Octave/*
+ Shave related tweaks.
+
+2009-03-15 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * src/common.h src/caf.c src/sndfile.c
+ Add SF_MAX_CHANNELS (set to 256) and use it.
+
+ * src/sndfile.h.in
+ Check for either _MSCVER or _MSC_VER being defined.
+
+2009-03-04 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+
+ * tests/vorbis_test.c
+ Relax test slighly to allow test to pass on more CPUs etc.
+
2009-03-03 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* configure.ac
* src/wav.c
Handle four zero bytes as a marker within a LIST or INFO chunk.
- Thanks to Rogério Brito for supplying an example file.
+ Thanks to Rogério Brito for supplying an example file.
2009-02-14 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
2008-06-14 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/aiff.c
- Apply a fix from Axel Roebel where if the second loop in the instrument
+ Apply a fix from Axel Röbel where if the second loop in the instrument
chunk is none, the loop mode is written into the first loop.
2008-05-31 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
2008-04-09 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/aiff.c
- Fix up handling of 'APPL' chunk. Thanks to Axel Roebel for bringing up
+ Fix up handling of 'APPL' chunk. Thanks to Axel Röbel for bringing up
this issue.
2008-04-06 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
Allow use of either LGPL v2.1 or LGPL v3.
* tests/header_test.tpl
- Add header_shrink_test from Axel Roebel.
+ Add header_shrink_test from Axel Röbel.
* src/wav.c
- Add fix from Axel Roebel for writing files with float data but no peak
+ Add fix from Axel Röbel for writing files with float data but no peak
chunk (ie peak chunk gets removed after the file is opened).
* src/aiff.c tests/header_test.tpl
2007-04-14 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/GSM610/long_term.c src/macbinary3.c tests/cpp_test.cc
- Add patch from André Pang to clean up compiles on OSX.
+ Add patch from André Pang to clean up compiles on OSX.
* src/wve.c src/common.h src/sndfile.c src/sndfile.h.in
examples/sndfile-convert.c
* src/sndfile.hh
Add a static SndfileHandle::formatCheck method as suggested by Jorge
- Jiménez.
+ Jiménez.
2007-04-09 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* configure.ac
Fix handling of --enable and --disable configure args. Thanks to Diego
- 'Flameeyes' Pettenò who sent the patch.
+ 'Flameeyes' Pettenò who sent the patch.
2006-03-22 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
2006-01-10 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* examples/sndfile-play.c
- Fix calculation of samples remaining in win32 code. Thanks Axel Roebel.
+ Fix calculation of samples remaining in win32 code. Thanks Axel Röbel.
* src/common.h
Make sure length of header buffer can hold header plus strings. Thanks Axel
- Roebel.
+ Röbel.
2006-01-09 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* tests/locale_test.c
Modify the way the unicode strings were encoded so that older compilers
- do not complain. Thanks Axel Roebel.
+ do not complain. Thanks Axel Röbel.
* configure.ac
Bump the version to 1.0.12 for release.
style strings (no terminating character).
* src/aiff.c
- Move to new (correct) AIFF string style. Thanks to Axel Roebel for being
+ Move to new (correct) AIFF string style. Thanks to Axel Röbel for being
so persistent on this issue.
2005-07-11 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
2005-05-10 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/ircam.c
- Fix writing of IRCAM files on big endian systems (thanks to Axel Roebel).
+ Fix writing of IRCAM files on big endian systems (thanks to Axel Röbel).
* src/wav.c
Add workaround for files created by the Peak audio editor on Mac which can
2004-04-03 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* configure.ac
- Improve printout configuration summary (as suggested by Axel Röbel).
+ Improve printout configuration summary (as suggested by Axel Röbel).
* doc/index.html
Add link to pre-release location.
2003-12-07 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/file_io.c
- Axel Roebel pointed out that on Mac OSX a pipe is not considered a fifo
+ Axel Röbel pointed out that on Mac OSX a pipe is not considered a fifo
(S_ISFIFO (st.st_mode) is false) but a socket (S_ISSOCK (st.st_mode) is
true). The test has therefore been changed to is S_ISREG and anything
which which does not return true for S_ISREG is considered a pipe.
* src/aiff.c
Fixed a bug where opening a file with a non-trival header in SFM_RDWR mode
- would over-write part of the header. Thanks to Axel Roebel for pointing
+ would over-write part of the header. Thanks to Axel Röbel for pointing
this out. Axel also provided a patch to fix this but I came up with a
neater and more general solution.
Return error when openning an AIFF file with data after the SSND chunk
- (Thanks Axel Roebel).
+ (Thanks Axel Röbel).
* tests/aiff_rw_test.c
Improvements to test program which will later allow it to be generalised to
* src/common.c src/common.h src/file_io.h
Added is_pipe field to SF_PRIVATE and declaration of psf_is_pipe()
- function. (Axel Roebel)
+ function. (Axel Röbel)
* src/sndfile.c
- Fixed determination of whether the file is a pipe. (Axel Roebel)
+ Fixed determination of whether the file is a pipe. (Axel Röbel)
* src/paf.c
- Force paf24 to start with undefined mode. (Axel Roebel)
+ Force paf24 to start with undefined mode. (Axel Röbel)
* tests/pipe_test.c
Mods to make this test work and actually do the test on RAW files. (Axel
- Roebel).
+ Röbel).
2003-05-05 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/sndfile.c
Fixed a potential bug where psf->sf.seekable was being set to FALSE when
operating on stdin or stdout but then the default initialiser was reseting
- it to TRUE. Thanks to Axel Roebel.
+ it to TRUE. Thanks to Axel Röbel.
* src/aiff.c
Fixed a bug in the header parser where it was not handling an odd length
- COMM chunk correctly. Thanks to Axel Roebel.
+ COMM chunk correctly. Thanks to Axel Röbel.
* src/test_file_io.c
Add more tests.
* src/paf.c src/wav_gsm610.c
Removed two printf()s which had escaped notice for some time (thanks
- Sigbjørn Skjæret).
+ Sigbjørn Skjæret).
2001-07-19 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/sndfile.h
Removed prototype of unimplemented function sf_get_info(). Added prototype
- for sf_error_number() Thanks to Sigbjørn Skjæret for spotting these.
+ for sf_error_number() Thanks to Sigbjørn Skjæret for spotting these.
2000-08-18 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
2000-08-15 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/sndfile.c
- Fixed a leak of FILE* pointers in sf_open_write(). Thanks to Sigbjørn
- Skjæret for spotting this one.
+ Fixed a leak of FILE* pointers in sf_open_write(). Thanks to Sigbjørn
+ Skjæret for spotting this one.
2000-08-13 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/wav.c
Fixed bug in GSM 6.10 handling for big-endian machines. Thanks
- to Sigbjørn Skjæret for reporting this.
+ to Sigbjørn Skjæret for reporting this.
2000-04-25 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* src/aiff.c
Fixed calculation of datalength when reading SSND chunk. Thanks to
- Sigbjørn Skjæret for pointing out this error.
+ Sigbjørn Skjæret for pointing out this error.
1999-07-29 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
-dnl @synopsis AC_ADD_CFLAGS
+dnl @synopsis MN_ADD_CFLAGS
dnl
dnl Add the given option to CFLAGS, if it doesn't break the compiler
-AC_DEFUN([AC_ADD_CFLAGS],
+AC_DEFUN([MN_ADD_CFLAGS],
[AC_MSG_CHECKING([if $CC accepts $1])
ac_add_cflags__old_cflags="$CFLAGS"
- CFLAGS="$CFLAGS $1"
+ CFLAGS="$1"
AC_TRY_LINK([
#include <stdio.h>
],
[puts("Hello, World!"); return 0;],
- AC_MSG_RESULT([yes]),
+ AC_MSG_RESULT([yes])
+ CFLAGS="$ac_add_cflags__old_cflags $1",
AC_MSG_RESULT([no])
- CFLAGS="$ac_add_cflags__old_cflags"
+ CFLAGS="$ac_add_cflags__old_cflags"
)
-])# AC_ADD_CFLAGS
+])# MN_ADD_CFLAGS
-dnl @synopsis AC_ADD_CXXFLAGS
+dnl @synopsis MN_ADD_CXXFLAGS
dnl
dnl Add the given option to CXXFLAGS, if it doesn't break the compiler
-AC_DEFUN([AC_ADD_CXXFLAGS],
+AC_DEFUN([MN_ADD_CXXFLAGS],
[AC_MSG_CHECKING([if $CXX accepts $1])
+ AC_LANG_ASSERT([C++])
ac_add_cxxflags__old_cxxflags="$CXXFLAGS"
- CXXFLAGS="$CXXFLAGS $1"
+ CXXFLAGS="$1"
AC_TRY_LINK([
#include <cstdio>
],
[puts("Hello, World!"); return 0;],
- AC_MSG_RESULT([yes]),
+ AC_MSG_RESULT([yes])
+ CXXFLAGS="$ac_add_cxxflags__old_cxxflags $1",
AC_MSG_RESULT([no])
- CXXFLAGS="$ac_add_cxxflags__old_cxxflags"
+ CXXFLAGS="$ac_add_cxxflags__old_cxxflags"
)
-])# AC_ADD_CXXFLAGS
+])# MN_ADD_CXXFLAGS
-dnl @synopsis AC_C_CLIP_MODE
+dnl @synopsis MN_C_CLIP_MODE
dnl
dnl Determine the clipping mode when converting float to int.
dnl @version 1.0 May 17 2003
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_DEFUN([MN_C_CLIP_MODE],
[AC_CACHE_CHECK(processor clipping capabilities,
ac_cv_c_clip_type,
)
]
-)# AC_C_CLIP_MODE
+)# MN_C_CLIP_MODE
-dnl @synopsis AC_C_FIND_ENDIAN
+dnl @synopsis MN_C_FIND_ENDIAN
dnl
dnl Determine endian-ness of target processor.
dnl @version 1.1 Mar 03 2002
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_DEFUN([MN_C_FIND_ENDIAN],
[AC_CACHE_CHECK(processor byte ordering,
ac_cv_c_byte_order,
[
case "$target_cpu" in
alpha* | i?86* | mipsel* | ia64*)
- ac_cv_c_big_endian=0
- ac_cv_c_little_endian=1
+ ac_cv_c_byte_order=little
;;
m68* | mips* | powerpc* | hppa* | sparc*)
- ac_cv_c_big_endian=1
- ac_cv_c_little_endian=0
+ ac_cv_c_byte_order=big
;;
esac
return (u.c [sizeof (long) - 1] == 1);
}
]], , ac_cv_c_byte_order=big,
- ac_cv_c_byte_order=unknown
)
AC_TRY_RUN(
u.l = 1 ;
return (u.c [0] == 1);
}]], , ac_cv_c_byte_order=little,
- ac_cv_c_byte_order=unknown
)
fi
fi
fi
]
-)# AC_C_FIND_ENDIAN
+)# MN_C_FIND_ENDIAN
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],
+dnl MN_SYS_EXTRA_LARGEFILE_FLAGS(FLAGSNAME)
+AC_DEFUN([MN_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` || {
[ --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)
+ MN_SYS_EXTRA_LARGEFILE_FLAGS(CFLAGS)
+ MN_SYS_EXTRA_LARGEFILE_FLAGS(LDFLAGS)
+ MN_SYS_EXTRA_LARGEFILE_FLAGS(LIBS)
for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do
case "$ac_flag" in
-dnl @synopsis AC_C99_FLEXIBLE_ARRAY
+dnl @synopsis MN_C99_FLEXIBLE_ARRAY
dnl
dnl Dose the compiler support the 1999 ISO C Standard "stuct hack".
dnl @version 1.1 Mar 15 2004
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_DEFUN([MN_C99_FLEXIBLE_ARRAY],
[AC_CACHE_CHECK(C99 struct flexible array support,
ac_cv_c99_flexible_array,
ac_cv_c99_flexible_array=yes,
ac_cv_c99_flexible_array=no
))]
-) # AC_C99_FLEXIBLE_ARRAY
+) # MN_C99_FLEXIBLE_ARRAY
-dnl @synopsis AC_GCC_VERSION
+dnl @synopsis MN_GCC_VERSION
dnl
dnl Find the version of gcc.
dnl @version 1.0 Nov 05 2007
dnl provided "as is" without express or implied warranty.
dnl
-AC_DEFUN([AC_GCC_VERSION],
+AC_DEFUN([MN_GCC_VERSION],
[
if test "x$ac_cv_c_compiler_gnu" = "xyes" ; then
AC_SUBST(GCC_MAJOR_VERSION)
AC_SUBST(GCC_MINOR_VERSION)
-])# AC_GCC_VERSION
+])# MN_GCC_VERSION
-dnl @synopsis AC_C99_FUNC_LLRINT
+dnl @synopsis MN_C99_FUNC_LLRINT
dnl
dnl Check whether C99's llrint function is available.
dnl @version 1.1 Sep 30 2002
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_DEFUN([MN_C99_FUNC_LLRINT],
[AC_CACHE_CHECK(for llrint,
ac_cv_c99_llrint,
[
AC_DEFINE(HAVE_LLRINT, 1,
[Define if you have C99's llrint function.])
fi
-])# AC_C99_FUNC_LLRINT
+])# MN_C99_FUNC_LLRINT
-dnl @synopsis AC_C99_FUNC_LRINT
+dnl @synopsis MN_C99_FUNC_LRINT
dnl
dnl Check whether C99's lrint function is available.
dnl @version 1.3 Feb 12 2002
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_DEFUN([MN_C99_FUNC_LRINT],
[AC_CACHE_CHECK(for lrint,
ac_cv_c99_lrint,
[
AC_DEFINE(HAVE_LRINT, 1,
[Define if you have C99's lrint function.])
fi
-])# AC_C99_FUNC_LRINT
+])# MN_C99_FUNC_LRINT
-dnl @synopsis AC_C99_FUNC_LRINTF
+dnl @synopsis MN_C99_FUNC_LRINTF
dnl
dnl Check whether C99's lrintf function is available.
dnl @version 1.3 Feb 12 2002
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_DEFUN([MN_C99_FUNC_LRINTF],
[AC_CACHE_CHECK(for lrintf,
ac_cv_c99_lrintf,
[
AC_DEFINE(HAVE_LRINTF, 1,
[Define if you have C99's lrintf function.])
fi
-])# AC_C99_FUNC_LRINTF
+])# MN_C99_FUNC_LRINTF
-dnl @synopsis AC_MKOCTFILE_VERSION
+dnl @synopsis OCTAVE_MKOCTFILE_VERSION
dnl
dnl Find the version of mkoctfile.
dnl @version 1.0 Aug 23 2007
dnl provided "as is" without express or implied warranty.
dnl
-AC_DEFUN([AC_MKOCTFILE_VERSION],
+AC_DEFUN([OCTAVE_MKOCTFILE_VERSION],
[
AC_SUBST(MKOCTFILE)
AC_SUBST(MKOCTFILE_VERSION)
-])# AC_MKOCTFILE_VERSION
+])# OCTAVE_MKOCTFILE_VERSION
OCTAVE_BUILD=no
AC_OCTAVE_VERSION
-AC_MKOCTFILE_VERSION
+OCTAVE_MKOCTFILE_VERSION
AC_OCTAVE_CONFIG_VERSION
prog_concat="$ac_cv_prog_HAVE_OCTAVE$ac_cv_prog_HAVE_OCTAVE_CONFIG$ac_cv_prog_HAVE_MKOCTFILE"
-## Process this file with automake to produce Makefile.in\r
-\r
-DISTCHECK_CONFIGURE_FLAGS = --enable-gcc-werror\r
-\r
-if BUILD_OCTAVE_MOD\r
-octave_dir = Octave\r
-endif\r
-\r
-SUBDIRS = M4 Win32 src $(octave_dir) \r
-#man doc examples regtest tests programs\r
-\r
-DIST_SUBDIRS = M4 man doc Win32 src Octave examples regtest tests programs\r
-\r
-EXTRA_DIST = libsndfile.spec.in sndfile.pc.in Mingw-make-dist.sh\r
-\r
-\r
-pkgconfigdir = $(libdir)/pkgconfig\r
-pkgconfig_DATA = sndfile.pc\r
-\r
-m4datadir = $(datadir)/aclocal\r
-\r
-test: check-recursive\r
-\r
-# Target to make autogenerated files.\r
-genfiles :\r
- (cd src ; make genfiles)\r
- (cd tests ; make genfiles)\r
-\r
-\r
+## Process this file with automake to produce Makefile.in
+
+DISTCHECK_CONFIGURE_FLAGS = --enable-gcc-werror
+
+if BUILD_OCTAVE_MOD
+octave_dir = Octave
+endif
+
+SUBDIRS = M4 man doc Win32 src $(octave_dir) examples regtest tests programs
+DIST_SUBDIRS = M4 man doc Win32 src Octave examples regtest tests programs
+
+EXTRA_DIST = libsndfile.spec.in sndfile.pc.in
+
+CLEANFILES = *~
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = sndfile.pc
+
+m4datadir = $(datadir)/aclocal
+
+#===============================================================================
+
+test: check-recursive
+
+# Target to make autogenerated files.
+genfiles :
+ (cd src ; make genfiles)
+ (cd tests ; make genfiles)
+
+checkprograms :
+ (cd src ; make libsndfile.la checkprograms)
+ (cd tests ; make checkprograms)
+
+testprogs :
+ (cd src ; make testprogs)
+ (cd tests ; make testprogs)
+
+
+test-tarball : build-test-tarball.mk
+ make all
+ make -f build-test-tarball.mk
+++ /dev/null
-#!/bin/sh
-
-# Copyright (C) 2006 Erik de Castro Lopo <erikd@mega-nerd.com>
-#
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in
-# the documentation and/or other materials provided with the
-# distribution.
-# * Neither the author nor the names of any contributors may be used
-# to endorse or promote products derived from this software without
-# specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-set -e
-
-function unix_to_dos {
- sed -e "s/\n/\r\n/" $1 > temp_file
- mv -f temp_file $1
-}
-
-if [ $# -lt 1 ] || [ $# -gt 2 ]; then
- echo "Usage : Mingw-make-dist.sh <source tarball>."
- exit 1
- fi
-
-TARGZ=$1
-if [ ! -f $TARGZ ]; then
- echo "Can't find source tarball."
- fi
-
-TARGZ=$1
-if [ ! -f $TARGZ.asc ]; then
- echo "Can't find source tarball signature."
- fi
-
-UNAME=`uname -s`
-if [ x$UNAME != "xMINGW32_NT-5.1" ]; then
- echo "Not able to build Win32 binaries on this platform."
- fi
-
-echo "Building MinGW binary/source zip file."
-
-VERSION=`pwd | sed -e "s#.*/##" | sed -e s/libsndfile-//`
-BUILD=`echo $VERSION | sed -e "s/\./_/g"`
-INSTALL="libsndfile-$BUILD"
-ZIPNAME="$INSTALL.zip"
-
-if [ -z "$BUILD" ]; then
- echo "Bad BUILD variable : '$BUILD'"
- exit 1
- fi
-
-if [ ! -d $INSTALL/ ]; then
- mkdir $INSTALL
- fi
-
-if [ ! -f config.status ]; then
- ./configure --prefix=`pwd`/$INSTALL/
-else
- teststr=`grep "with options" config.status | grep -- --prefix=`
- if [ -z "$teststr" ]; then
- # --disable-static doesn't work.
- ./configure --prefix=`pwd`/$INSTALL/
- fi
- fi
-
-if [ ! -f src/.libs/libsndfile-1.dll ]; then
- make all check
- fi
-
-if [ ! -f $INSTALL/bin/libsndfile-1.dll ]; then
- make install
- rm -f $INSTALL/bin/sndfile-regtest.exe
- strip $INSTALL/bin/*.*
- mv $INSTALL/bin/*.* $INSTALL/include/*.* $INSTALL/
- rmdir $INSTALL/bin
- rm -rf $INSTALL/lib
- rmdir $INSTALL/include
- cp src/libsndfile.def $INSTALL/libsndfile-1.def
- cp Win32/README-precompiled-dll.txt Win32/testprog.c $INSTALL/
- unix_to_dos $INSTALL/libsndfile-1.def
- unix_to_dos $INSTALL/sndfile.h
- unix_to_dos $INSTALL/README-precompiled-dll.txt
- unix_to_dos $INSTALL/testprog.c
- fi
-
-if [ ! -f $INSTALL/libsndfile-$VERSION.tar.gz ]; then
- cp $TARGZ $INSTALL/
- if [ -f $TARGZ.asc ]; then
- cp $TARGZ.asc $INSTALL/
- fi
- fi
-
-if [ ! -f $ZIPNAME ]; then
- zip -r $ZIPNAME $INSTALL/
- fi
-
+Version 1.0.25 (2011-07-13)
+ * Fix for Secunia Advisory SA45125, heap overflow in PAF file handler.
+ * Accept broken WAV files with blockalign == 0.
+ * Minor bug fixes and improvements.
+
+Version 1.0.24 (2011-03-23)
+ * WAV files now have an 18 byte u-law and A-law fmt chunk.
+ * Document virtual I/O functionality.
+ * Two new methods rawHandle() and takeOwnership() in sndfile.hh.
+ * AIFF fix for non-zero offset value in SSND chunk.
+ * Minor bug fixes and improvements.
+
+Version 1.0.23 (2010-10-10)
+ * Add version metadata to Windows DLL.
+ * Add a missing 'inline' to sndfile.hh.
+ * Update docs.
+ * Minor bug fixes and improvements.
+
+Version 1.0.22 (2010-10-04)
+ * Couple of fixes for SDS file writer.
+ * Fixes arising from static analysis.
+ * Handle FLAC files with ID3 meta data at start of file.
+ * Handle FLAC files which report zero length.
+ * Other minor bug fixes and improvements.
+
+Version 1.0.21 (2009-12-13)
+ * Add a couple of new binary programs to programs/ dir.
+ * Remove sndfile-jackplay (now in sndfile-tools package).
+ * Add windows only function sf_wchar_open().
+ * Bunch of minor bug fixes.
+
+Version 1.0.20 (2009-05-14)
+ * Fix potential heap overflow in VOC file parser (Tobias Klein, http://www.trapkit.de/).
+
Version 1.0.19 (2009-03-02)
* Fix for CVE-2009-0186 (Alin Rad Pop, Secunia Research).
* Huge number of minor bug fixes as a result of static analysis.
noinst_DATA = $(oct_module_files)
+# Used by shave which cleans up automake generated Makefile output.
+V = @
+Q = $(V:1=)
+QUIET_GEN = $(Q:@=@echo ' GEN '$@;)
+
+
# Use Octave's mkoctfile to do all the heavy lifting. Unfortunately, its
# a little dumb so we need to guide it carefully.
sndfile.oct : sndfile.o
- $(MKOCTFILE) -v $(INCLUDES) $(top_builddir)/Octave/$+ -L$(SNDFILEDIR)/.libs -L$(SNDFILEDIR) -lsndfile -o $(top_builddir)/Octave/$@
+ $(QUIET_GEN) $(MKOCTFILE) -v $(INCLUDES) $(top_builddir)/Octave/$+ -L$(SNDFILEDIR)/.libs -L$(SNDFILEDIR) -lsndfile -o $(top_builddir)/Octave/$@ > /dev/null
sndfile.o : sndfile.cc
- $(MKOCTFILE) -v $(INCLUDES) -c $+ -o $(top_builddir)/Octave/$@
+ $(QUIET_GEN) $(MKOCTFILE) -v $(INCLUDES) -c $+ -o $(top_builddir)/Octave/$@ > /dev/null
# Allow for the test being run in the build dir, but the test script
# being located in the source dir.
-# Copyright (C) 2007 Erik de Castro Lopo <erikd@mega-nerd.com>
+# Copyright (C) 2007-2011 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
# These tests are nowhere near comprehensive.
-printf ("\n\n\n\n\n\n\n") ;
-
-printf (" Running Octave tests : ") ;
+printf (" Running Octave tests : ") ;
fflush (stdout) ;
filename = "whatever" ;
printf ("ok") ;
-printf ("\n\n\n\n\n\n\n") ;
-
unlink (filename) ;
elif [ -f "../src/libsndfile.dylib" ]; then
libsndfile_lib_location="../src/"
else
- echo
echo
echo "Not able to find the libsndfile shared lib we've just built."
echo "This may cause the following test to fail."
echo
- echo
fi
libsndfile_lib_location=`(cd $libsndfile_lib_location && pwd)`
/*
-** Copyright (C) 2007 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2007-2011 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
case SF_FORMAT_G723_40 : return "g723_40" ;
default : break ;
} ;
-
+
return "unknown" ;
} /* string_of_minor_format */
-## Copyright (C) 2002 Erik de Castro Lopo
+## Copyright (C) 2002-2011 Erik de Castro Lopo
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
wavedata = -1 ;
-eval (sprintf ('load -f %s', filename)) ;
+eval (sprintf ('load -f %s', filename)) ;
if (samplerate > 0),
fs = samplerate ;
else
error ("Not able to find sample rate.") ;
endif
-
+
if (max (size (wavedata)) > 1),
data = wavedata ;
else
-## Copyright (C) 2002 Erik de Castro Lopo
+## Copyright (C) 2002-2011 Erik de Castro Lopo
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
-## Copyright (C) 2002 Erik de Castro Lopo
+## Copyright (C) 2002-2011 Erik de Castro Lopo
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
-This is libsndfile, 1.0.19
+This is libsndfile, 1.0.25
libsndfile is a library of C routines for reading and writing
files containing sampled audio data.
+++ /dev/null
-Here's a list of what I (erikd AT mega-nerd DOT com) think needs to be
-done. The list is by no means exhaustive and people are encouraged to
-email me with suggestions.
-
- o Add pipe in/out capabilities. libsndfile should be able to read
- its input from a pipe and write its output to a pipe.
-
- o Add checks of the error state after fseek???? Use ferror ().
-
- o Modify tests/lossy_comp_test.c to add tests for stereo files.
-
- o Testing compilation and correctness on more platforms.
-
- o Improve testing routines. Must test all combinations of inputs
- and outputs.
-
- o Test sf_seek function on write???
-
- o Add more sound file formats. People should contact me with their
- requirements.
-
- o Add support for accessing sound formats with multiple audio
- data sections (ie samples within tracker files, Soundfont II and
- multi-sample sampler formats).
-
- o Add an interface to allow reading and writing of sample loop points
- and other info within AIFF and other file formats. This must be a
- general solution.
-
- o Improve documentation. Is HTML documentation good enough?
-
- o Look into the possibility of optional sample rate convert on file
- read.
-
-As I am the person who knows libsndfile best, I can probably implement
-any new features faster than anybody else (and you can spend your time
-writing applications with libsndfile). All I need is some
-documentation and some sample files. Please contact me before emailing
-me documentation and sample files. I would much rather pull them off
-the web than have them clogging up my email inbox.
-
-
+++ /dev/null
-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>.
-
-
-m4_include([M4/gcc_version.m4])
-m4_include([M4/octave.m4])
-m4_include([M4/mkoctfile_version.m4])
-
-
-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
-
- 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")
-])
-
-
-
-dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
-dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
-dnl also defines GSTUFF_PKG_ERRORS on error
-AC_DEFUN([PKG_CHECK_MODULES], [
- succeeded=no
-
- if test -z "$PKG_CONFIG"; then
- AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
- fi
-
- if test "$PKG_CONFIG" = "no" ; then
- echo "*** The pkg-config script could not be found. Make sure it is"
- echo "*** in your path, or set the PKG_CONFIG environment variable"
- echo "*** to the full path to pkg-config."
- echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
- else
- PKG_CONFIG_MIN_VERSION=0.9.0
- if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
- AC_MSG_CHECKING(for $2)
-
- if $PKG_CONFIG --exists "$2" ; then
- AC_MSG_RESULT(yes)
- succeeded=yes
-
- AC_MSG_CHECKING($1_CFLAGS)
- $1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
- AC_MSG_RESULT($$1_CFLAGS)
-
- AC_MSG_CHECKING($1_LIBS)
- $1_LIBS=`$PKG_CONFIG --libs "$2"`
- AC_MSG_RESULT($$1_LIBS)
- else
- $1_CFLAGS=""
- $1_LIBS=""
- ## If we have a custom action on failure, don't print errors, but
- ## do set a variable so people can do so.
- $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
- ifelse([$4], ,echo $$1_PKG_ERRORS,)
- fi
-
- AC_SUBST($1_CFLAGS)
- AC_SUBST($1_LIBS)
- else
- echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
- echo "*** See http://www.freedesktop.org/software/pkgconfig"
- fi
- fi
-
- if test $succeeded = yes; then
- ifelse([$3], , :, [$3])
- else
- ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4])
- fi
-])
-
-
-
-
-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
-# Copyright (C) 1999-2008 Erik de Castro Lopo (erikd AT mega-nerd DOT com).
+# Copyright (C) 1999-2011 Erik de Castro Lopo (erikd AT mega-nerd DOT com).
dnl Require autoconf version
AC_PREREQ(2.57)
-AC_INIT([libsndfile],[1.0.19],[erikd@mega-nerd.com])
+AC_INIT([libsndfile],[1.0.25],[sndfile@mega-nerd.com],
+ [libsndfile],[http://www.mega-nerd.com/libsndfile/])
# Put config stuff in Cfg.
AC_CONFIG_AUX_DIR(Cfg)
-CFLAGS="$CFLAGS $CONFIGURE_CFLAGS"
-CXXFLAGS="$CXXFLAGS $CONFIGURE_CXXFLAGS"
-LDFLAGS="$LDFLAGS $CONFIGURE_LDFLAGS"
-
AC_CONFIG_SRCDIR([src/sndfile.c])
AC_CANONICAL_TARGET([])
-AM_INIT_AUTOMAKE
AC_CONFIG_MACRO_DIR([M4])
-
AC_CONFIG_HEADERS([src/config.h])
+AM_INIT_AUTOMAKE($PACKAGE_NAME,$PACKAGE_VERSION)
+AM_SILENT_RULES([yes])
+
dnl Add parameters for aclocal
AC_SUBST(ACLOCAL_AMFLAGS, "-I M4")
AC_LANG([C])
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_CXX
+AC_PROG_SED
+
+# Do not check for F77.
+define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl
+
+AM_PROG_LIBTOOL
+LT_PROG_RC
+
+AC_CHECK_PROG(HAVE_AUTOGEN, autogen, yes, no)
+AC_CHECK_PROG(HAVE_WINE, wine, yes, no)
+
+AC_PROG_INSTALL
+AC_PROG_LN_S
+
#------------------------------------------------------------------------------------
# Rules for library version information:
#
# 6. If any interfaces have been removed since the last public release, then set age
# to 0.
-SHARED_VERSION_INFO="1:19:0"
+CLEAN_VERSION=`echo $PACKAGE_VERSION | $SED "s/p.*//"`
+VERSION_MINOR=`echo $CLEAN_VERSION | $SED "s/.*\.//"`
-AC_PROG_CC
-AM_PROG_CC_C_O
-AC_PROG_CXX
-
-# Do not check for F77.
-define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl
-
-AM_PROG_LIBTOOL
-
-AC_CHECK_PROG(HAVE_AUTOGEN, autogen, yes, no)
-AC_CHECK_PROG(HAVE_WINE, wine, yes, no)
+SHARED_VERSION_INFO="1:$VERSION_MINOR:0"
-AC_PROG_INSTALL
-AC_PROG_LN_S
+#------------------------------------------------------------------------------------
AC_HEADER_STDC
#====================================================================================
# Check for support of the struct hack.
-AC_C99_FLEXIBLE_ARRAY
+MN_C99_FLEXIBLE_ARRAY
if test x$ac_cv_c99_flexible_array = xyes ; then
AC_DEFINE([HAVE_FLEXIBLE_ARRAY],1, [Set to 1 if the compile supports the struct hack.])
AC_HELP_STRING([--disable-alsa], [disable use of ALSA]))
AC_ARG_ENABLE(external-libs,
- AC_HELP_STRING([--disable-external-libs], [disable use of FLAC, Ogg and Vorbis]))
+ AC_HELP_STRING([--disable-external-libs], [disable use of FLAC, Ogg and Vorbis [[default=no]]]))
AC_ARG_ENABLE(octave,
AC_HELP_STRING([--enable-octave], [disable building of GNU Octave module]))
#====================================================================================
# Check types and their sizes.
+AC_CHECK_SIZEOF(wchar_t,4)
AC_CHECK_SIZEOF(short,2)
AC_CHECK_SIZEOF(int,4)
AC_CHECK_SIZEOF(long,4)
AC_CHECK_SIZEOF(off_t,1) # Fake default value.
case "$host_os" in
- mingw*)
+ mingw32msvc | mingw32)
TYPEOF_SF_COUNT_T="__int64"
SF_COUNT_MAX="0x7FFFFFFFFFFFFFFFLL"
SIZEOF_SF_COUNT_T=8
+ AC_DEFINE([__USE_MINGW_ANSI_STDIO],1,[Set to 1 to use C99 printf/snprintf in MinGW.])
;;
*)
if test "x$ac_cv_sizeof_off_t" = "x8" ; then
# If sizeof (off_t) is 8, no further checking is needed.
- TYPEOF_SF_COUNT_T="off_t"
+ TYPEOF_SF_COUNT_T="int64_t"
SF_COUNT_MAX="0x7FFFFFFFFFFFFFFFLL"
SIZEOF_SF_COUNT_T=8
else
TYPEOF_SF_COUNT_T="unknown"
if test "x$ac_cv_sizeof_loff_t" = "x8" ; then
- TYPEOF_SF_COUNT_T="loff_t"
+ TYPEOF_SF_COUNT_T="int64_t"
SIZEOF_SF_COUNT_T=8
elif test "x$ac_cv_sizeof_off64_t" = "x8" ; then
- TYPEOF_SF_COUNT_T="off64_t"
+ TYPEOF_SF_COUNT_T="int64_t"
SIZEOF_SF_COUNT_T=8
fi
AC_CHECK_SIZEOF(off_t,1) # Fake default value.
if test "x$ac_cv_sizeof_off_t" = "x8" ; then
+ TYPEOF_SF_COUNT_T="int64_t"
SF_COUNT_MAX="0x7FFFFFFFFFFFFFFFLL"
elif test "x$ac_cv_sizeof_off_t" = "x$pre_largefile_sizeof_off_t" ; then
AC_MSG_WARN([[This machine does not seem to support 64 bit file offsets.]])
#====================================================================================
# Determine endian-ness of target processor.
-AC_C_FIND_ENDIAN
+MN_C_FIND_ENDIAN
AC_DEFINE_UNQUOTED(CPU_IS_BIG_ENDIAN, ${ac_cv_c_big_endian},
[Target processor is big endian.])
AC_CHECK_FUNCS(gmtime gmtime_r localtime localtime_r gettimeofday)
AC_CHECK_FUNCS(mmap getpagesize)
AC_CHECK_FUNCS(setlocale)
+AC_CHECK_FUNCS(pipe waitpid)
AC_CHECK_LIB([m],floor)
AC_CHECK_FUNCS(floor ceil fmod)
-AC_C99_FUNC_LRINT
-AC_C99_FUNC_LRINTF
+MN_C99_FUNC_LRINT
+MN_C99_FUNC_LRINTF
#====================================================================================
# Check for requirements for building plugins for other languages/enviroments.
# Check for pkg-config outside the if statement.
PKG_PROG_PKG_CONFIG
-#if test x$enable_external_libs = xno ; then
- AC_MSG_WARN([[*** External libs (FLAC, Ogg, Vorbis) disabled. ***]])
-#else
-# PKG_CHECK_MOD_VERSION(FLAC, flac >= 1.2.1, ac_cv_flac=yes, ac_cv_flac=no)
-# PKG_CHECK_MOD_VERSION(OGG, ogg >= 1.1.3, ac_cv_ogg=yes, ac_cv_ogg=no)
+if test -n "$PKG_CONFIG" ; then
+ if test x$enable_external_libs = xno ; then
+ AC_MSG_WARN([[*** External libs (FLAC, Ogg, Vorbis) disabled. ***]])
+ else
+ PKG_CHECK_MOD_VERSION(FLAC, flac >= 1.2.1, ac_cv_flac=yes, ac_cv_flac=no)
+
+ # Make sure the FLAC_CFLAGS value is sane.
+ FLAC_CFLAGS=`echo $FLAC_CLFAGS | $SED "s/FLAC$//"`
- # Vorbis versions earlier than 1.2.1 are not const correct at the API level.
- # Vorbis 1.2.2 adds vorbis_version_string.
-# PKG_CHECK_MOD_VERSION(VORBIS, vorbis >= 1.2.0, ac_cv_vorbis=yes, ac_cv_vorbis=no)
-# PKG_CHECK_MOD_VERSION(VORBISENC, vorbisenc >= 1.2.0, ac_cv_vorbisenc=yes, ac_cv_vorbisenc=no)
-# fi
+ PKG_CHECK_MOD_VERSION(OGG, ogg >= 1.1.3, ac_cv_ogg=yes, ac_cv_ogg=no)
-HAVE_VORBIS_VERSION_STRING=0
-if test x$ac_cv_flac$ac_cv_ogg$ac_cv_vorbis$ac_cv_vorbisenc = "xyesyesyesyes" ; then
+ if test x$enable_experimental = xyes ; then
+ PKG_CHECK_MOD_VERSION(SPEEX, speex >= 1.2, ac_cv_speex=yes, ac_cv_speex=no)
+ else
+ SPEEX_CFLAGS=""
+ SPEEX_LIBS=""
+ fi
- save_LIBS="$LIBS"
- LIBS="$VORBIS_LIBS $LIBS"
- AC_CHECK_LIB(vorbis, vorbis_version_string, HAVE_VORBIS_VERSION_STRING=1)
- LIBS="$save_LIBS"
+ # Vorbis versions earlier than 1.2.3 have bugs that cause the libsndfile
+ # test suite to fail on MIPS, PowerPC and others.
+ # See: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=549899
+ PKG_CHECK_MOD_VERSION(VORBIS, vorbis >= 1.2.3, ac_cv_vorbis=yes, ac_cv_vorbis=no)
+ PKG_CHECK_MOD_VERSION(VORBISENC, vorbisenc >= 1.2.3, ac_cv_vorbisenc=yes, ac_cv_vorbisenc=no)
+ enable_external_libs=yes
+ fi
- HAVE_EXTERNAL_LIBS=1
- enable_external_libs=yes
+ if test x$ac_cv_flac$ac_cv_ogg$ac_cv_vorbis$ac_cv_vorbisenc = "xyesyesyesyes" ; then
+ HAVE_EXTERNAL_LIBS=1
+ enable_external_libs=yes
- EXTERNAL_CFLAGS="$FLAC_CFLAGS $OGG_CFLAGS $VORBISENC_CFLAGS"
- EXTERNAL_LIBS="$FLAC_LIBS $VORBISENC_LIBS"
-else
- enable_external_libs=no
+ EXTERNAL_CFLAGS="$FLAC_CFLAGS $OGG_CFLAGS $VORBISENC_CFLAGS $SPEEX_CFLAGS"
+ EXTERNAL_LIBS="$FLAC_LIBS $VORBISENC_LIBS $SPEEX_LIBS"
+ else
+ echo
+ AC_MSG_WARN([[*** One or more of the external libraries (ie libflac, libogg and]])
+ AC_MSG_WARN([[*** libvorbis) is either missing (possibly only the development]])
+ AC_MSG_WARN([[*** headers) or is of an unsupported version.]])
+ AC_MSG_WARN([[***]])
+ AC_MSG_WARN([[*** Unfortunately, for ease of maintenance, the external libs]])
+ AC_MSG_WARN([[*** are an all or nothing affair.]])
+ echo
+ enable_external_libs=no
+ fi
fi
AC_DEFINE_UNQUOTED([HAVE_EXTERNAL_LIBS], $HAVE_EXTERNAL_LIBS, [Will be set to 1 if flac, ogg and vorbis are available.])
-AC_DEFINE_UNQUOTED([HAVE_VORBIS_VERSION_STRING], $HAVE_VORBIS_VERSION_STRING, [Set to 1 if we have vorbis_version_string.])
#====================================================================================
# Check for libsqlite3 (only used in regtest).
ac_cv_sqlite3=no
-#if test x$enable_sqlite != xno ; then
-# PKG_CHECK_MOD_VERSION(SQLITE3, sqlite3 >= 3.2, ac_cv_sqlite3=yes, ac_cv_sqlite3=no)
-# fi
+if test x$enable_sqlite != xno ; then
+ PKG_CHECK_MOD_VERSION(SQLITE3, sqlite3 >= 3.2, ac_cv_sqlite3=yes, ac_cv_sqlite3=no)
+ fi
if test x$ac_cv_sqlite3 = "xyes" ; then
HAVE_SQLITE3=1
AC_DEFINE_UNQUOTED([HAVE_SQLITE3],$HAVE_SQLITE3,[Set to 1 if you have libsqlite3.])
-#====================================================================================
-# Check for JACK (only used for examples/sndfile-jackplay).
-
-#PKG_CHECK_MOD_VERSION(JACK, jack >= 0.100, ac_cv_jack=yes, ac_cv_jack=no)
-
-if test x$ac_cv_jack = "xyes" ; then
- HAVE_JACK=1
-else
- HAVE_JACK=0
- fi
-
-AC_DEFINE_UNQUOTED([HAVE_JACK],$HAVE_JACK,[Set to 1 if you have JACK.])
-
#====================================================================================
# Determine if the processor can do clipping on float to int conversions.
if test x$enable_cpu_clip != "xno" ; then
- AC_C_CLIP_MODE
+ MN_C_CLIP_MODE
else
echo "checking processor clipping capabilities... disabled"
ac_cv_c_clip_positive=0
case "$host_os" in
darwin* | rhapsody*)
os_is_macosx=1
- OS_SPECIFIC_CFLAGS="-fpascal-strings -I/Developer/Headers/FlatCarbon"
+ OS_SPECIFIC_CFLAGS="-I/Developer/Headers/FlatCarbon"
OS_SPECIFIC_LINKS="-framework CoreAudio"
;;
mingw*)
AC_DEFINE_UNQUOTED(OS_IS_MACOSX, ${os_is_macosx}, [Set to 1 if compiling for MacOSX])
AC_DEFINE_UNQUOTED(USE_WINDOWS_API, ${use_windows_api}, [Set to 1 to use the native windows API])
+AM_CONDITIONAL(USE_WIN_VERSION_FILE, test ${use_windows_api} -eq 1)
+
#====================================================================================
# Check for ALSA.
fi
fi
+#====================================================================================
+# Check for OpenBSD's sndio.
+
+SNDIO_LIBS=""
+AC_CHECK_HEADERS(sndio.h)
+if test x$ac_cv_header_sndio_h = xyes ; then
+ SNDIO_LIBS="-lsndio"
+ fi
+
#====================================================================================
# Test for sanity when cross-compiling.
COMPILER_IS_GCC=0
if test x$ac_cv_c_compiler_gnu = xyes ; then
- AC_ADD_CFLAGS(-std=gnu99)
+ MN_ADD_CFLAGS(-std=gnu99)
- AC_GCC_VERSION
+ MN_GCC_VERSION
if test "x$GCC_MAJOR_VERSION$GCC_MINOR_VERSION" = "x42" ; then
-# AC_MSG_WARN([****************************************************************])
-# AC_MSG_WARN([** GCC version 4.2 warns about the inline keyword for no good **])
-# AC_MSG_WARN([** reason but the maintainers do not see it as a bug. **])
-# AC_MSG_WARN([** See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33995 **])
-# AC_MSG_WARN([** Using -fgnu-inline to avoid this stupidity. **])
-# AC_MSG_WARN([****************************************************************])
- AC_ADD_CFLAGS([-fgnu89-inline])
+ AC_MSG_WARN([****************************************************************])
+ AC_MSG_WARN([** GCC version 4.2 warns about the inline keyword for no good **])
+ AC_MSG_WARN([** reason but the maintainers do not see it as a bug. **])
+ AC_MSG_WARN([** See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33995 **])
+ AC_MSG_WARN([** Using -fgnu-inline to avoid this stupidity. **])
+ AC_MSG_WARN([****************************************************************])
+ MN_ADD_CFLAGS([-fgnu89-inline])
fi
CFLAGS="$CFLAGS -Wall"
CXXFLAGS="$CXXFLAGS -Wall"
-# AC_ADD_CFLAGS([-Wextra])
+ MN_ADD_CFLAGS([-Wextra])
AC_LANG_PUSH([C++])
-# AC_ADD_CXXFLAGS([-Wextra])
+ MN_ADD_CXXFLAGS([-Wextra])
AC_LANG_POP([C++])
- AC_ADD_CFLAGS([-Wdeclaration-after-statement])
- AC_ADD_CFLAGS([-Wpointer-arith])
- AC_ADD_CFLAGS([-funsigned-char])
+ MN_ADD_CFLAGS([-Wdeclaration-after-statement])
+ MN_ADD_CFLAGS([-Wpointer-arith])
+ MN_ADD_CFLAGS([-funsigned-char])
if test x$enable_gcc_werror = "xyes" ; then
CFLAGS="-Werror $CFLAGS"
fi
if test x$enable_test_coverage = "xyes" ; then
- # AC_ADD_CFLAGS([-ftest-coverage])
- AC_ADD_CFLAGS([-coverage])
+ # MN_ADD_CFLAGS([-ftest-coverage])
+ MN_ADD_CFLAGS([-coverage])
fi
- CFLAGS="$CFLAGS -Wstrict-prototypes -Wmissing-prototypes -Waggregate-return -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wbad-function-cast -Wwrite-strings "
+ CFLAGS="$CFLAGS -Wstrict-prototypes -Wmissing-prototypes -Waggregate-return -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wbad-function-cast -Wwrite-strings -Wundef "
# -Wundef -Wmissing-declarations -Winline -Wconversion"
- CXXFLAGS="$CXXFLAGS -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Wctor-dtor-privacy -Wnon-virtual-dtor -Woverloaded-virtual -Wreorder -Wsign-promo "
+ CXXFLAGS="$CXXFLAGS -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Wctor-dtor-privacy -Wnon-virtual-dtor -Woverloaded-virtual -Wreorder -Wsign-promo -Wundef "
if test "x$enable_gcc_opt" = "xno" ; then
- temp_CFLAGS=`echo $CFLAGS | sed "s/O2/O0/"`
+ temp_CFLAGS=`echo $CFLAGS | $SED "s/O2/O0/"`
CFLAGS=$temp_CFLAGS
AC_MSG_WARN([[*** Compiler optimisations switched off. ***]])
fi
darwin* | rhapsody*)
# Disable -Wall, -pedantic and -Wshadow for Apple Darwin/Rhapsody.
# System headers on these systems are broken.
- temp_CFLAGS=`echo $CFLAGS | sed "s/-Wall -pedantic//" | sed "s/-Wshadow//" | sed "s/-Waggregate-return//"`
+ temp_CFLAGS=`echo $CFLAGS | $SED "s/-Wall -pedantic//" | $SED "s/-Wshadow//" | $SED "s/-Waggregate-return//"`
CFLAGS=$temp_CFLAGS
SHLIB_VERSION_ARG="-Wl,-exported_symbols_list -Wl,\$(srcdir)/Symbols.darwin"
;;
- linux*)
- SHLIB_VERSION_ARG="-Wl,--version-script=\$(srcdir)/Symbols.linux"
+ linux*|kfreebsd*-gnu*|gnu*)
+ SHLIB_VERSION_ARG="-Wl,--version-script=\$(srcdir)/Symbols.gnu-binutils"
;;
mingw*)
# Linker flag '-Wl,--out-implib' does not work with mingw cross compiler
AC_DEFINE_UNQUOTED([WIN32_TARGET_DLL], ${win32_target_dll}, [Set to 1 if windows DLL is being built.])
AC_DEFINE_UNQUOTED([COMPILER_IS_GCC], ${COMPILER_IS_GCC}, [Set to 1 if the compile is GNU GCC.])
-AC_DEFUN([AX_COMPILER_VENDOR],
-[
-AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,
- [ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=unknown
- # note: don't check for gcc first since some other compilers define __GNUC__
- for ventest in intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do
- vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")"
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[
-#if !($vencpp)
- thisisanerror;
-#endif
-])], [ax_cv_]_AC_LANG_ABBREV[_compiler_vendor=`echo $ventest | cut -d: -f1`; break])
- done
- ])
-])
-
-AX_COMPILER_VENDOR
-
-# Enable 64 bit build
-AC_ARG_ENABLE(64,
-[AC_HELP_STRING([--enable-64],[build with 64 bit support])],[enable_64="$enable_64"],[enable_64="no"])
-
-if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then
- if test "${enable_64}" = "yes"; then
- CFLAGS="$CFLAGS -m64"
- fi
-fi
-
CFLAGS="$CFLAGS $OS_SPECIFIC_CFLAGS"
exit
fi
+HOST_TRIPLET="${host_cpu}-${host_vendor}-${host_os}"
+
+if test "$HOST_TRIPLET" = "x86_64-w64-mingw32" ; then
+ OS_SPECIFIC_LINKS=" -static-libgcc $OS_SPECIFIC_LINKS"
+ fi
+
+WIN_RC_VERSION=`echo $PACKAGE_VERSION | $SED -e "s/p.*//" -e "s/\./,/g"`
+
#-------------------------------------------------------------------------------
+AC_SUBST(HOST_TRIPLET)
+
AC_SUBST(htmldocdir)
AC_SUBST(HTML_BGCOLOUR)
AC_SUBST(HTML_FGCOLOUR)
AC_SUBST(SHLIB_VERSION_ARG)
AC_SUBST(SHARED_VERSION_INFO)
+AC_SUBST(CLEAN_VERSION)
+AC_SUBST(WIN_RC_VERSION)
+
AC_SUBST(OS_SPECIFIC_CFLAGS)
AC_SUBST(OS_SPECIFIC_LINKS)
AC_SUBST(ALSA_LIBS)
-AC_SUBST(ENABLE_EXPERIMENTAL_CODE)
+AC_SUBST(SNDIO_LIBS)
AC_SUBST(EXTERNAL_CFLAGS)
AC_SUBST(EXTERNAL_LIBS)
-AC_SUBST(COMPILER_IS_GCC)
-AC_SUBST(GCC_MAJOR_VERSION)
-
-AC_SUBST(HAVE_JACK)
-
dnl The following line causes the libtool distributed with the source
dnl to be replaced if the build system has a more recent version.
AC_SUBST(LIBTOOL_DEPS)
AC_CONFIG_FILES([ \
- src/sndfile.h src/Makefile src/GSM610/Makefile src/G72x/Makefile \
- man/Makefile examples/Makefile tests/Makefile regtest/Makefile \
- M4/Makefile doc/Makefile Win32/Makefile Octave/Makefile \
- programs/Makefile doc/libsndfile.css \
- Makefile libsndfile.spec sndfile.pc \
- tests/test_wrapper.sh \
+ src/Makefile man/Makefile examples/Makefile tests/Makefile regtest/Makefile \
+ M4/Makefile doc/Makefile Win32/Makefile Octave/Makefile programs/Makefile \
+ Makefile \
+ src/version-metadata.rc tests/test_wrapper.sh tests/pedantic-header-test.sh \
+ doc/libsndfile.css build-test-tarball.mk libsndfile.spec sndfile.pc \
+ src/sndfile.h \
])
AC_OUTPUT
-# Make it executable.
-chmod u+x tests/test_wrapper.sh
+# Make sure these are executable.
+chmod u+x tests/test_wrapper.sh build-test-tarball.mk
#====================================================================================
Configuration summary :
- Version : ............................. ${VERSION}
+ libsndfile version : .................. ${VERSION}
+
+ Host CPU : ............................ ${host_cpu}
+ Host Vendor : ......................... ${host_vendor}
+ Host OS : ............................. ${host_os}
+
Experimental code : ................... ${enable_experimental:-no}
Using ALSA in example programs : ...... ${enable_alsa:-no}
External FLAC/Ogg/Vorbis : ............ ${enable_external_libs:-no}
-
])
+if test -z "$PKG_CONFIG" ; then
+ echo " *****************************************************************"
+ echo " *** The pkg-config program is missing. ***"
+ echo " *** External FLAC/Ogg/Vorbis libs cannot be found without it. ***"
+ echo " *** http://pkg-config.freedesktop.org/wiki/ ***"
+ echo " *****************************************************************"
+ echo
+ fi
+
if test x$ac_cv_c_compiler_gnu = xyes ; then
- echo -e " Tools :\n"
+ echo " Tools :"
+ echo
echo " Compiler is GCC : ..................... ${ac_cv_c_compiler_gnu}"
echo " GCC version : ......................... ${GCC_VERSION}"
if test $GCC_MAJOR_VERSION -lt 3 ; then
- echo -e "\n ** This compiler version allows applications to write"
+ echo "\n"
+ echo " ** This compiler version allows applications to write"
echo " ** to static strings within the library."
echo " ** Compile with GCC version 3.X or above to avoid this problem."
fi
if test x$prefix != "x/usr" ; then
echo "Compiling some other packages against libsndfile may require"
- echo -e "the addition of \"$libdir/pkgconfig\" to the"
- echo -e "PKG_CONFIG_PATH environment variable.\n"
+ echo "the addition of '$libdir/pkgconfig' to the"
+ echo "PKG_CONFIG_PATH environment variable."
+ echo
fi
(cd src && make genfiles)
<META NAME="Author" CONTENT="Erik de Castro Lopo (erikd AT mega-nerd DOT com)">
<META NAME="Description" CONTENT="The libsndfile FAQ.">
<META NAME="Keywords" CONTENT="WAV AIFF AU libsndfile sound audio dsp Linux">
- <LINK REL=StyleSheet HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="print.css" TYPE="text/css" MEDIA="print">
</HEAD>
<BODY>
<H1><B>libsndfile : Frequently Asked Questions.</B></H1>
<P>
-<A HREF="#Q001">Q1 : Do you plan to support XYZ codec in libsndfile?</A><BR>
+<A HREF="#Q001">Q1 : Do you plan to support XYZ codec in libsndfile?</A><BR/>
<A HREF="#Q002">Q2 : In version 0 the SF_INFO struct had a pcmbitwidth field
- but version 1 does not. Why?</A><BR>
-<A HREF="#Q003">Q3 : Compiling is really slow on MacOSX. Why?</A><BR>
+ but version 1 does not. Why?</A><BR/>
+<A HREF="#Q003">Q3 : Compiling is really slow on MacOS X. Why?</A><BR/>
<A HREF="#Q004">Q4 : When trying to compile libsndfile on Solaris I get a "bad
- substitution" error during linking. What can I do to fix this?</A><BR>
-<A HREF="#Q005">Q5 : Why doesn't libsndfile do interleaving/de-interleaving?</A><BR>
-<A HREF="#Q006">Q6 : What's the best format for storing temporary files?</A><BR>
-<A HREF="#Q007">Q7 : On Linux/Unix/MacOSX, what's the best way of detecting the
- presence of libsndfile?</A><BR>
-<A HREF="#Q008">Q8 : But I just want a simple Makefile! What do I do?</A><BR>
+ substitution" error during linking. What can I do to fix this?</A><BR/>
+<A HREF="#Q005">Q5 : Why doesn't libsndfile do interleaving/de-interleaving?</A><BR/>
+<A HREF="#Q006">Q6 : What's the best format for storing temporary files?</A><BR/>
+<A HREF="#Q007">Q7 : On Linux/Unix/MacOS X, what's the best way of detecting the
+ presence of libsndfile?</A><BR/>
+<A HREF="#Q008">Q8 : But I just want a simple Makefile! What do I do?</A><BR/>
<A HREF="#Q009">Q9 : How about adding the ability to write/read sound files to/from
- memory buffers?</A><BR>
+ memory buffers?</A><BR/>
<A HREF="#Q010">Q10 : Reading a 16 bit PCM file as normalised floats and then
- writing them back changes some sample values. Why?</A><BR>
+ writing them back changes some sample values. Why?</A><BR/>
<A HREF="#Q011">Q11 : I'm having problems with u-law encoded WAV files generated by
- libsndfile in Winamp. Why?</A><BR>
-<A HREF="#Q012">Q12 : I'm looking at sf_read*. What are items? What are frames?</A><BR>
+ libsndfile in Winamp. Why?</A><BR/>
+<A HREF="#Q012">Q12 : I'm looking at sf_read*. What are items? What are frames?</A><BR/>
<A HREF="#Q013">Q13 : Why can't libsndfile open this Sound Designer II (SD2)
- file?</A><BR>
+ file?</A><BR/>
<A HREF="#Q014">Q14 : I'd like to statically link libsndfile to my closed source
- application. Can I buy a license so that this is possible?</A><BR>
+ application. Can I buy a license so that this is possible?</A><BR/>
<A HREF="#Q015">Q15 : My program is crashing during a call to a function in libsndfile.
- Is this a bug in libsndfile?</A><BR>
+ Is this a bug in libsndfile?</A><BR/>
<A HREF="#Q016">Q16 : Will you accept a fix for compiling libsndfile with compiler X?
- </A><BR>
+ </A><BR/>
<A HREF="#Q017">Q17 : Can libsndfile read/write files from/to UNIX pipes?
- </A><BR>
-<A HREF="#Q018">Q18 : Is it possible to build a Universal Binary on Mac OSX?
- </A><BR>
+ </A><BR/>
+<A HREF="#Q018">Q18 : Is it possible to build a Universal Binary on Mac OS X?
+ </A><BR/>
<A HREF="#Q019">Q19 : I have project files for Visual Studio / XCode / Whatever. Why
don't you distribute them with libsndfile?
- </A><BR>
+ </A><BR/>
<A HREF="#Q020">Q20 : Why doesn't libsndfile support MP3? Lots of other Open Source
projects support it!
- </A><BR>
+ </A><BR/>
<A HREF="#Q021">Q21 : How do I use libsndfile in a closed source or commercial program
and comply with the license?
- </A><BR>
+ </A><BR/>
<A HREF="#Q022">Q22 : What versions of windows does libsndfile work on?
- </A><BR>
+ </A><BR/>
+<A HREF="#Q023">Q23 : I'm cross compiling libsndfile for another platform. How can I
+ run the test suite?
+ </A><BR/>
<HR>
<!-- ========================================================================= -->
<A NAME="Q001"></A>
-<H2><BR><B>Q1 : Do you plan to support XYZ codec in libsnfile?</B></H2>
+<H2><BR/><B>Q1 : Do you plan to support XYZ codec in libsndfile?</B></H2>
<P>
If source code for XYZ codec is available under a suitable license (LGPL, BSD,
MIT etc) then yes, I'd like to add it.
</P>
<P>
-If suitable documentation is available on how to decode and enocde the format
+If suitable documentation is available on how to decode and encode the format
then maybe, depending on how much work is involved.
</P>
<P>
</P>
<!-- ========================================================================= -->
<A NAME="Q002"></A>
-<H2><BR><B>Q2 : In version 0 the SF_INFO struct had a pcmbitwidth field
+<H2><BR/><B>Q2 : In version 0 the SF_INFO struct had a pcmbitwidth field
but version 1 does not. Why?</B></H2>
<P>
This was dropped for a number of reasons:
<P>
As documented
<A HREF="http://www.mega-nerd.com/libsndfile/api.html#note1">here</A>
-there is now a well defined behavior which ensures that no matter what the
+there is now a well defined behaviour which ensures that no matter what the
bit width of the source file, the scaling always does something sensible.
This makes it safe to read 8, 16, 24 and 32 bit PCM files using sf_read_short()
-and always have the optimal behavior.
+and always have the optimal behaviour.
</P>
<!-- ========================================================================= -->
<A NAME="Q003"></A>
-<H2><BR><B>Q3 : Compiling is really slow on MacOSX. Why?</B></H2>
+<H2><BR/><B>Q3 : Compiling is really slow on MacOS X. Why?</B></H2>
<P>
When you configure and compile libsndfile, it uses the /bin/sh shell for a number
of tasks (ie configure script and libtool).
-Older versions of OSX (10.2?) shipped a a really crappy Bourne shell as /bin/sh
+Older versions of OS X (10.2?) shipped a really crappy Bourne shell as /bin/sh
which resulted in <b>really</b> slow compiles.
-New version of OSX ship GNU BASh as /bin/sh and this answer doesn't apply in that
+Newer version of OS X ship GNU Bash as /bin/sh and this answer doesn't apply in that
case.
</P>
<P>
To fix this I suggest that you install the GNU Bash shell, rename /bin/sh to
-/bin/sh.old and make a softlink from /bin/sh to the bash shell.
+/bin/sh.old and make a symlink from /bin/sh to the bash shell.
Bash is designed to behave as a Bourne shell when is is called as /bin/sh.
</P>
<P>
-When I did this on my iBook running MacOSX, compile times dropped from 13 minutes
+When I did this on my iBook running MacOS X, compile times dropped from 13 minutes
to 3 minutes.
</P>
<!-- ========================================================================= -->
<A NAME="Q004"></A>
-<H2><BR><B>Q4 : When trying to compile libsndfile on Solaris I get a "bad
+<H2><BR/><B>Q4 : When trying to compile libsndfile on Solaris I get a "bad
substitution" error on linking. Why?</B></H2>
<P>
It seems that the Solaris Bourne shell disagrees with GNU libtool.
</P>
<P>
To fix this I suggest that you install the GNU Bash shell, rename /bin/sh to
-/bin/sh.old and make a softlink from /bin/sh to the bash shell.
+/bin/sh.old and make a symlink from /bin/sh to the bash shell.
Bash is designed to behave as a Bourne shell when is is called as /bin/sh.
</P>
<!-- ========================================================================= -->
<A NAME="Q005"></A>
-<H2><BR><B>Q5 : Why doesn't libsndfile do interleaving/de-interleaving?</B></H2>
+<H2><BR/><B>Q5 : Why doesn't libsndfile do interleaving/de-interleaving?</B></H2>
<P>
This problem is bigger than it may seem at first.
</P>
could satisfy most users.
However, for files with more than 2 channels this is unlikely to be the case.
If the user has a 4 channel file and want to play that file on a stereo output
-sound card they either want the first two channels or they want some mixed combination
+sound card they either want the first 2 channels or they want some mixed combination
of the 4 channels.
</P>
<P>
<!-- ========================================================================= -->
<A NAME="Q006"></A>
-<H2><BR><B>Q6 : What's the best format for storing temporary files?</B></H2>
+<H2><BR/><B>Q6 : What's the best format for storing temporary files?</B></H2>
<P>
When you want to store temporary data there are a number of requirements;
<!-- ========================================================================= -->
<A NAME="Q007"></A>
-<H2><BR><B>Q7 : On Linux/Unix/MaxOSX, what's the best way of detecting the presence
+<H2><BR/><B>Q7 : On Linux/Unix/MaxOS X, what's the best way of detecting the presence
of libsndfile using autoconf?</B></H2>
<P>
<!-- ========================================================================= -->
<A NAME="Q008"></A>
-<H2><BR><B>Q8 : But I just want a simple Makefile! What do I do?</B></H2>
+<H2><BR/><B>Q8 : But I just want a simple Makefile! What do I do?</B></H2>
<P>
The <B>pkg-config</B> program makes finding the correct compiler flag values and
<!-- ========================================================================= -->
<A NAME="Q009"></A>
-<H2><BR><B>Q9 : How about adding the ability to write/read sound files to/from
+<H2><BR/><B>Q9 : How about adding the ability to write/read sound files to/from
memory buffers?</B></H2>
<P>
<!-- ========================================================================= -->
<A NAME="Q010"></A>
-<H2><BR><B>Q10 : Reading a 16 bit PCM file as normalised floats and then
+<H2><BR/><B>Q10 : Reading a 16 bit PCM file as normalised floats and then
writing them back changes some sample values. Why?</B></H2>
<P>
<!-- ========================================================================= -->
<A NAME="Q011"></A>
-<H2><BR><B>Q11 : I'm having problems with u-law encoded WAV files generated by
+<H2><BR/><B>Q11 : I'm having problems with u-law encoded WAV files generated by
libsndfile in Winamp. Why?
</B></H2>
<!-- ========================================================================= -->
<A NAME="Q012"></A>
-<H2><BR><B>Q12 : I'm looking at sf_read*. What are items? What are frames?
+<H2><BR/><B>Q12 : I'm looking at sf_read*. What are items? What are frames?
</B></H2>
<P>
-For a sound file with only one channel, a frame is the same as a item.
+An <tt>item</tt>tt> is a single sample of the data type you are reading; ie a
+single <tt>short</tt> value for <tt>sf_read_short</tt> or a single <tt>float</tt>
+for <tt>sf_read_float</tt>.
</P>
+
+For a sound file with only one channel, a frame is the same as a item (ie a
+single sample) while for multi channel sound files, a single frame contains a
+single item for each channel.
+</P>
+
<P>
-For multi channel sound files, a single frame contains a single item for
-each channel.
+Here are two simple, correct examples, both of which are assumed to be working
+on a stereo file, first using items:
</P>
+<PRE>
+ #define CHANNELS 2
+ short data [CHANNELS * 100] ;
+ sf_count items_read = sf_read_short (file, data, 200) ;
+ assert (items_read == 200) ;
+</PRE>
+
+<P>
+and now readng the exact same amount of data using frames:
+</P>
+
+<PRE>
+ #define CHANNELS 2
+ short data [CHANNELS * 100] ;
+ sf_count frames_read = sf_readf_short (file, data, 100) ;
+ assert (frames_read == 100) ;
+</PRE>
+
<!-- ========================================================================= -->
<A NAME="Q013"></A>
-<H2><BR><B>Q13 : Why can't libsndfile open this Sound Designer II (SD2) file?
+<H2><BR/><B>Q13 : Why can't libsndfile open this Sound Designer II (SD2) file?
</B></H2>
<P>
SD2 files are native to the Apple Macintosh platform and use features of
the Mac filesystem (file resource forks) to store the file's sample rate,
number of channels, sample width and more.
-When you look at a file and its resource fork on Mac OSX it looks like
+When you look at a file and its resource fork on Mac OS X it looks like
this:
</P>
<P>
Notice how the file itself looks like a directory containing a single file
named <B>rsrc</B>.
-When libsndfile is compiled for MacOSX, it should open (for write and read)
+When libsndfile is compiled for MacOS X, it should open (for write and read)
SD2 file with resource forks like this without any problems.
It will also handle files with the resource fork in a separate file as
described below.
<P>
However, it is possible to safely move an SD2 file to a Linux or Windows
machine.
-For instance, when an SD2 file is copied from inside MacOSX to a windows
-shared directory or a Samba share (ie Linux), MacOSX is clever enough to
+For instance, when an SD2 file is copied from inside MacOS X to a windows
+shared directory or a Samba share (ie Linux), MacOS X is clever enough to
store the resource fork of the file in a separate hidden file in the
same directory like this:
</P>
<!-- ========================================================================= -->
<A NAME="Q014"></A>
-<H2><BR><B>Q14 : I'd like to statically link libsndfile to my closed source
+<H2><BR/><B>Q14 : I'd like to statically link libsndfile to my closed source
application. Can I buy a license so that this is possible?
</B></H2>
<!-- ========================================================================= -->
<A NAME="Q015"></A>
-<H2><BR><B>Q15 : My program is crashing during a call to a function in libsndfile.
+<H2><BR/><B>Q15 : My program is crashing during a call to a function in libsndfile.
Is this a bug in libsndfile?
</B></H2>
<!-- ========================================================================= -->
<A NAME="Q016"></A>
-<H2><BR><B>Q16 : Will you accept a fix for compiling libsndfile with compiler X?
+<H2><BR/><B>Q16 : Will you accept a fix for compiling libsndfile with compiler X?
</B></H2>
<P>
<!-- ========================================================================= -->
<A NAME="Q017"></A>
-<H2><BR><B>Q17 : Can libsndfile read/write files from/to UNIX pipes?
+<H2><BR/><B>Q17 : Can libsndfile read/write files from/to UNIX pipes?
</B></H2>
<P>
<!-- ========================================================================= -->
<A NAME="Q018"></A>
-<H2><BR><B>Q18 : Is it possible to build a Universal Binary on Mac OSX?
+<H2><BR/><B>Q18 : Is it possible to build a Universal Binary on Mac OS X?
</B></H2>
<P>
<!-- ========================================================================= -->
<A NAME="Q019"></A>
-<H2><BR><B>Q19 : I have project files for Visual Studio / XCode / Whatever. Why
+<H2><BR/><B>Q19 : I have project files for Visual Studio / XCode / Whatever. Why
don't you distribute them with libsndfile?
</B></H2>
<P>
I currently release sources that I personally test on Win32, Linux and
-MacOSX (PowerPC) using the compiler I trust (GNU GCC).
+MacOS X (PowerPC) using the compiler I trust (GNU GCC).
Supporting one compiler on three (actually much more because GCC is available
almost everywhere) platforms is doable without too much pain.
I also release binaries for Win32 with instructions on how to use those
<!-- ========================================================================= -->
<A NAME="Q020"></A>
-<H2><BR><B>Q20 : Why doesn't libsndfile support MP3? Lots of other Open Source
+<H2><BR/><B>Q20 : Why doesn't libsndfile support MP3? Lots of other Open Source
projects support it!
</B></H2>
<!-- ========================================================================= -->
<A NAME="Q021"></A>
-<H2><BR><B>Q21 : How do I use libsndfile in a closed source or commercial program
+<H2><BR/><B>Q21 : How do I use libsndfile in a closed source or commercial program
and comply with the license?
</B></H2>
<ul>
<li>Make sure you are linking to libsndfile as a shared library (Linux and Unix
- systems), Dynamic Link Library (Microsoft Windows) or dynlib (Mac OSX).
+ systems), Dynamic Link Library (Microsoft Windows) or dynlib (Mac OS X).
If you are using some other operating system that doesn't allow dynamically
linked libraries, you will not be able to use libsndfile unless you release
the source code to your program.
<!-- ========================================================================= -->
<A NAME="Q022"></A>
-<H2><BR><B>Q22 : What versions of windows does libsndfile work on?
+<H2><BR/><B>Q22 : What versions of Windows does libsndfile work on?
</B></H2>
<p>
-Currently the precompiled windows binaries are tested in Windows XP.
+Currently the precompiled windows binaries are thoroughly tested on Windows XP.
As such, they should also work on Win2k and Windows Vista.
-They may also work on earlier versions of windows.
+They may also work on earlier versions of Windows.
+</p>
+
+<p>
+Since version 0.1.18 I have also been releasing precompiled binaries for Win64,
+the 64 bit version of Windows.
+These binaries have received much less testing than the 32 bit versions, but
+should work as expected.
+I'd be very interested in receiving feedback on these binaries.
</p>
+<!-- ========================================================================= -->
+<A NAME="Q023"></A>
+<H2><BR/><B>Q23 : I'm cross compiling libsndfile for another platform. How can I
+ run the test suite?
+</B></H2>
+
<p>
-libsndfile does not yet work on 64 bit versions of windows.
-Support for 64 bit versions of WinXP and Vista is likely to be working some
-time late in 2008.
</p>
+
+<p>
+Since version 1.0.21 the top level Makefile has an extra make target,
+'test-tarball'.
+Building this target creates a tarball called called:
+</p>
+
+<center><tt>
+libsndfile-testsuite-${host_triplet}-${version}.tar.gz
+</tt></center>
+
+<p>
+in the top level directory.
+This tarball can then be copied to the target platform.
+Once untarred and test script <tt>test_wrapper.sh</tt> can be run from
+the top level of the extracted tarball.
+</p>
+
<!-- ========================================================================= -->
<HR>
<P>
The libsndfile home page is here :
<A HREF="http://www.mega-nerd.com/libsndfile/">
http://www.mega-nerd.com/libsndfile/</A>.
-<BR>
-Version : 1.0.19
+<BR/>
+Version : 1.0.25
</P>
</BODY>
<HEAD>
<TITLE>
- The libsndfile API.
+ The libsndfile API
</TITLE>
<META NAME="Author" CONTENT="Erik de Castro Lopo (erikd AT mega-nerd DOT com)">
<META NAME="Description" CONTENT="The libsndfile API.">
<META NAME="Keywords" CONTENT="WAV AIFF AU libsndfile sound audio dsp Linux">
- <LINK REL=StyleSheet HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="print.css" TYPE="text/css" MEDIA="print">
</HEAD>
<BODY>
unambiguous.
However, since maintaining the documentation is the least fun part of working
on libsndfile, these docs can and do fall behind the behaviour of library.
- If any errors omissions or ambiguities are found, please notify
- <A HREF="mailto:erikd@zip.com.au">
- Erik de Castro Lopo</a>.
+ If any errors, omissions or ambiguities are found, please notify me (erikd)
+ at mega-nerd dot com.
+</P>
+<!-- pepper -->
+<P>
+ To supplement this reference documentation, there are simple example programs
+ included in the source code tarball.
+ The test suite which is also part of the source code tarball is also a good
+ place to look for the correct usage of the library functions.
</P>
<!-- pepper -->
<P>
</B>
</P>
-<H2><B>SYNOPSIS</B></H2>
+<H2><B>Synopsis</B></H2>
<P>
The functions of libsndfile are defined as follows:
</P>
SNDFILE* <A HREF="#open">sf_open</A> (const char *path, int mode, SF_INFO *sfinfo) ;
SNDFILE* <A HREF="#open_fd">sf_open_fd</A> (int fd, int mode, SF_INFO *sfinfo, int close_desc) ;
-
+ SNDFILE* <A HREF="#open_virtual">sf_open_virtual</A> (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data) ;
int <A HREF="#check">sf_format_check</A> (const SF_INFO *info) ;
sf_count_t <A HREF="#seek">sf_seek</A> (SNDFILE *sndfile, sf_count_t frames, int whence) ;
SF_FORMAT_SD2 = 0x160000, /* Sound Designer 2 */
SF_FORMAT_FLAC = 0x170000, /* FLAC lossless file format */
SF_FORMAT_CAF = 0x180000, /* Core Audio File format */
+ SF_FORMAT_WVE = 0x190000, /* Psion WVE format */
+ SF_FORMAT_OGG = 0x200000, /* Xiph OGG container */
+ SF_FORMAT_MPC2K = 0x210000, /* Akai MPC 2000 sampler */
+ SF_FORMAT_RF64 = 0x220000, /* RF64 WAV file */
/* Subtypes from here on. */
SF_FORMAT_DPCM_8 = 0x0050, /* 8 bit differential PCM (XI only) */
SF_FORMAT_DPCM_16 = 0x0051, /* 16 bit differential PCM (XI only) */
+ SF_FORMAT_VORBIS = 0x0060, /* Xiph Vorbis encoding. */
+
/* Endian-ness options. */
SF_ENDIAN_FILE = 0x00000000, /* Default file endian-ness. */
</P>
<!-- pepper -->
<P>
-On success, the sf_open function returns a non NULL pointer which should be
+On success, the sf_open function returns a non-NULL pointer which should be
passed as the first parameter to all subsequent libsndfile calls dealing with
that audio file.
On fail, the sf_open function returns a NULL pointer.
+An explanation of the error can obtained by passing NULL to
+ <A HREF="#error">sf_strerror</A>.
</P>
<A NAME="open_fd"></A>
SNDFILE* sf_open_fd (int fd, int mode, SF_INFO *sfinfo, int close_desc) ;
</PRE>
+<P>
+<b>Note:</b> On Microsoft Windows, this function does not work if the
+application and the libsndfile DLL are linked to different versions of the
+Microsoft C runtime DLL.
+</P>
<P>
The second open function takes a file descriptor of a file that has already been
opened.
</P>
<P>
-On success, the sf_open_fd function returns a non NULL pointer which should be
+On success, the sf_open_fd function returns a non-NULL pointer which should be
passed as the first parameter to all subsequent libsndfile calls dealing with
that audio file.
On fail, the sf_open_fd function returns a NULL pointer.
</P>
+<A NAME="open_virtual"></A>
+<h3><b>Virtual File Open Function</b></h3>
+<pre>
+ SNDFILE* sf_open_virtual (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data) ;
+</pre>
+<p>
+ Opens a soundfile from a virtual file I/O context which is provided
+ by the caller. This is usually used to interface libsndfile to a stream or buffer
+ based system. Apart from the sfvirtual and the user_data parameters this function behaves
+ like <a href="#open">sf_open</a>.
+</p>
+
+<pre>
+ typedef struct
+ { sf_vio_get_filelen get_filelen ;
+ sf_vio_seek seek ;
+ sf_vio_read read ;
+ sf_vio_write write ;
+ sf_vio_tell tell ;
+ } SF_VIRTUAL_IO ;
+</pre>
+<p>
+Libsndfile calls the callbacks provided by the SF_VIRTUAL_IO structure when opening, reading
+and writing to the virtual file context. The user_data pointer is a user defined context which
+will be available in the callbacks.
+</p>
+<pre>
+ typedef sf_count_t (*sf_vio_get_filelen) (void *user_data) ;
+ typedef sf_count_t (*sf_vio_seek) (sf_count_t offset, int whence, void *user_data) ;
+ typedef sf_count_t (*sf_vio_read) (void *ptr, sf_count_t count, void *user_data) ;
+ typedef sf_count_t (*sf_vio_write) (const void *ptr, sf_count_t count, void *user_data) ;
+ typedef sf_count_t (*sf_vio_tell) (void *user_data) ;
+</pre>
+<h4>sf_vio_get_filelen</h4>
+<pre>
+ typedef sf_count_t (*sf_vio_get_filelen) (void *user_data) ;
+</pre>
+<p>
+The virtual file contex must return the length of the virtual file in bytes.<br>
+</p>
+<h4>sf_vio_seek</h4>
+<pre>
+ typedef sf_count_t (*sf_vio_seek) (sf_count_t offset, int whence, void *user_data) ;
+</pre>
+<p>
+The virtual file context must seek to offset using the seek mode provided by whence which is one of<br>
+</p>
+<pre>
+ SEEK_CUR
+ SEEK_SET
+ SEEK_END
+</pre>
+<p>
+The return value must contain the new offset in the file.
+</p>
+<h4>sf_vio_read</h4>
+<pre>
+ typedef sf_count_t (*sf_vio_read) (void *ptr, sf_count_t count, void *user_data) ;
+</pre>
+<p>
+The virtual file context must copy ("read") "count" bytes into the
+buffer provided by ptr and return the count of actually copied bytes.
+</p>
+<h4>sf_vio_write</h4>
+<pre>
+ typedef sf_count_t (*sf_vio_write) (const void *ptr, sf_count_t count, void *user_data) ;
+</pre>
+<p>
+The virtual file context must process "count" bytes stored in the
+buffer passed with ptr and return the count of actually processed bytes.<br>
+</p>
+<h4>sf_vio_tell</h4>
+<pre>
+ typedef sf_count_t (*sf_vio_tell) (void *user_data) ;
+</pre>
+<p>
+Return the current position of the virtual file context.<br>
+</p>
+
+
<A NAME="check"></A>
<BR><H2><B>Format Check Function</B></H2>
sf_count_t sf_write_raw (SNDFILE *sndfile, void *ptr, sf_count_t bytes) ;
</PRE>
+<P>
+<b>Note:</b> Unless you are writing an external decoder/encode that uses
+libsndfile to handle the file headers, you should not be using these
+functions.
+</P>
+
<P>
The raw read and write functions read raw audio data from the audio file (not to be
confused with reading RAW header-less PCM files). The number of bytes read or written
SF_STR_SOFTWARE,
SF_STR_ARTIST,
SF_STR_COMMENT,
- SF_STR_DATE
+ SF_STR_DATE,
+ SF_STR_ALBUM,
+ SF_STR_LICENSE,
+ SF_STR_TRACKNUMBER,
+ SF_STR_GENRE
} ;
</PRE>
<P>
-The sf_get_string() function returns the specificed string if it exists and a
+The sf_get_string() function returns the specified string if it exists and a
NULL pointer otherwise.
In addition to the string ids above, SF_STR_FIRST (== SF_STR_TITLE) and
SF_STR_LAST (always the same as the highest numbers string id) are also
In order to read these files correctly using integer read methods, it is recommended
that you use the
<A HREF="command.html">sf_command</A>
-interface a command of
+interface, a command of
<A HREF="command.html#SFC_SET_SCALE_FLOAT_INT_READ">SFC_SET_SCALE_FLOAT_INT_READ</A>
and a parameter of SF_TRUE to force correct scaling.
</P>
<A HREF="http://www.mega-nerd.com/libsndfile/">here</A>.
</P>
<P>
-Version : 1.0.19
+Version : 1.0.25
</P>
<!-- pepper -->
<!-- pepper -->
Bug Reporting
</TITLE>
<META NAME="Author" CONTENT="Erik de Castro Lopo (erikd AT mega-nerd DOT com)">
- <LINK REL=StyleSheet HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="print.css" TYPE="text/css" MEDIA="print">
</HEAD>
<BODY>
<LI> Whether you are using a package provided by your distribution or you
compiled it youself.
<LI> If you compiled it yourself, the compiler you are using. (Also make
- sure to run "make check".)
+ sure to run 'make check'.)
<LI> A description of the problem.
<LI> Information generated by the sndfile-info program (see next paragraph).
<LI> If you are having problems with sndfile-play and ALSA on Linux, I will
<!-- Another version at the bottom of the page. -->
<META NAME="Description" CONTENT="The libsndfile API.">
<META NAME="Keywords" CONTENT="WAV AIFF AU libsndfile sound audio dsp Linux">
- <LINK REL=StyleSheet HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="print.css" TYPE="text/css" MEDIA="print">
</HEAD>
<BODY>
Most of these operations are performed on a per-file basis.
</P>
<P>
- The cmd parameter is a integer identifier which is defined in <sndfile.h>.
+ The cmd parameter is an integer identifier which is defined in <sndfile.h>.
All of the valid command identifiers have names beginning with "SFC_".
Data is passed to and returned from the library by use of a void pointer.
The library will not read or write more than datasize bytes from the void pointer.
<TR>
<TD><A HREF="#SFC_GET_CLIPPING">SFC_GET_CLIPPING</A></TD>
- <TD>Retreive current clipping setting.</TD>
+ <TD>Retrieve current clipping setting.</TD>
</TR>
<TR>
<TD><A HREF="#SFC_GET_EMBED_FILE_INFO">SFC_GET_EMBED_FILE_INFO</A></TD>
- <TD>Retreive information about audio files embedded inside other files.</TD>
+ <TD>Retrieve information about audio files embedded inside other files.</TD>
</TR>
<TR>
<TD>Set the Broadcast Chunk info</TD>
</TR>
+<TR>
+ <TD><A HREF="#SFC_GET_LOOP_INFO">SFC_GET_LOOP_INFO</A></TD>
+ <TD>Get loop info</TD>
+</TR>
+
+<TR>
+ <TD><A HREF="#SFC_GET_INSTRUMENT">SFC_GET_INSTRUMENT</A></TD>
+ <TD>Get instrument info</TD>
+</TR>
+
+<TR>
+ <TD><A HREF="#SFC_SET_INSTRUMENT">SFC_SET_INSTRUMENT</A></TD>
+ <TD>Set instrument info</TD>
+</TR>
+
+<TR>
+ <TD><A HREF="#SFC_SET_VBR_ENCODING_QUALITY">SFC_SET_VBR_ENCODING_QUALITY</A></TD>
+ <TD>Set variable bit rate encoding quality</TD>
+</TR>
+
+
+
<!--
<TR>
<TD><A HREF="#add-dither">add dither</A></TD>
<A NAME="SFC_GET_FORMAT_SUBTYPE"></A>
<H2><BR><B>SFC_GET_FORMAT_SUBTYPE</B></H2>
<P>
-Enumerate the subtypes (this function does not translate a sub type into
+Enumerate the subtypes (this function does not translate a subtype into
a string describing that subtype).
A typical use case might be retrieving a string description of all subtypes
so that a dialog box can be filled in.
datasize : sizeof (SF_FORMAT_INFO)
</PRE>
<P>
-Example 1: Retrieve all subytpes supported by the WAV format.
+Example 1: Retrieve all sybtypes supported by the WAV format.
</P>
<PRE>
SF_FORMAT_INFO format_info ;
</P>
<DL>
<DT>Return value: </DT>
- <DD>SF_AMBISONIC_NONE or SF_AMBISONIC_B_FORMAT or zero if the file format
+ <DD>SF_AMBISONIC_NONE or SF_AMBISONIC_B_FORMAT or zero if the file format
does not support ambisonic formats.
</DL>
<A NAME="SFC_GET_BROADCAST_INFO"></A>
<H2><BR><B>SFC_GET_BROADCAST_INFO</B></H2>
<P>
-Retrieve the Broadcast Extention Chunk from WAV (and related) files.
+Retrieve the Broadcast Extension Chunk from WAV (and related) files.
</P>
<p>
Parameters:
<DL>
<DT>Return value: </DT>
- <DD>SF_TRUE if the file contained a Broadcast Extention chunk or SF_FALSE
+ <DD>SF_TRUE if the file contained a Broadcast Extension chunk or SF_FALSE
otherwise.
</DL>
<A NAME="SFC_SET_BROADCAST_INFO"></A>
<H2><BR><B>SFC_SET_BROADCAST_INFO</B></H2>
<P>
-Set the Broadcast Extention Chunk for WAV (and related) files.
+Set the Broadcast Extension Chunk for WAV (and related) files.
</P>
<p>
Parameters:
<DL>
<DT>Return value: </DT>
- <DD>SF_TRUE if setting the Broadcast Extention chunk was successful and SF_FALSE
+ <DD>SF_TRUE if setting the Broadcast Extension chunk was successful and SF_FALSE
otherwise.
</DL>
<!-- ========================================================================= -->
+<A NAME="SFC_GET_LOOP_INFO"></A>
+<H2><BR><B>SFC_GET_LOOP_INFO</B></H2>
+<P>
+Retrieve loop information for file including time signature, length in
+beats and original MIDI base note
+</P>
+<p>
+Parameters:
+</p>
+<PRE>
+ sndfile : A valid SNDFILE* pointer
+ cmd : SFC_GET_LOOP_INFO
+ data : a pointer to an SF_LOOP_INFO struct
+ datasize : sizeof (SF_LOOP_INFO)
+</PRE>
+<P>
+The SF_BROADCAST_INFO struct is defined in <sndfile.h> as:
+</P>
+<PRE>
+ typedef struct
+ { short time_sig_num ; /* any positive integer > 0 */
+ short time_sig_den ; /* any positive power of 2 > 0 */
+ int loop_mode ; /* see SF_LOOP enum */
+
+ int num_beats ; /* this is NOT the amount of quarter notes !!!*/
+ /* a full bar of 4/4 is 4 beats */
+ /* a full bar of 7/8 is 7 beats */
+
+ float bpm ; /* suggestion, as it can be calculated using other fields:*/
+ /* file's lenght, file's sampleRate and our time_sig_den*/
+ /* -> bpms are always the amount of _quarter notes_ per minute */
+
+ int root_key ; /* MIDI note, or -1 for None */
+ int future [6] ;
+ } SF_LOOP_INFO ;
+</PRE>
+<P>
+Example:
+</P>
+<PRE>
+ SF_LOOP_INFO loop;
+ sf_command (sndfile, SFC_GET_LOOP_INFO, &loop, sizeof (loop)) ;
+</PRE>
+<DL>
+<DT>Return value:</DT>
+ <DD>SF_TRUE if the file header contains loop information for the file.
+ SF_FALSE otherwise.
+</DL>
+
+<!-- ========================================================================= -->
+
+
+<A NAME="SFC_GET_INSTRUMENT"></A>
+<H2><BR><B>SFC_GET_INSTRUMENT</B></H2>
+<P>
+Retrieve instrument information from file including MIDI base note,
+keyboard mapping and looping informations(start/stop and mode).
+</P>
+<p>
+Parameters:
+</p>
+<PRE>
+ sndfile : A valid SNDFILE* pointer
+ cmd : SFC_GET_INSTRUMENT
+ data : a pointer to an SF_INSTRUMENT struct
+ datasize : sizeof (SF_INSTRUMENT)
+</PRE>
+
+<P>
+The SF_INSTRUMENT struct is defined in <sndfile.h> as:
+</P>
+<PRE>
+ enum
+ { /*
+ ** The loop mode field in SF_INSTRUMENT will be one of the following.
+ */
+ SF_LOOP_NONE = 800,
+ SF_LOOP_FORWARD,
+ SF_LOOP_BACKWARD,
+ SF_LOOP_ALTERNATING
+ } ;
+
+ typedef struct
+ { int gain ;
+ char basenote, detune ;
+ char velocity_lo, velocity_hi ;
+ char key_lo, key_hi ;
+ int loop_count ;
+
+ struct
+ { int mode ;
+ unsigned int start ;
+ unsigned int end ;
+ unsigned int count ;
+ } loops [16] ; /* make variable in a sensible way */
+ } SF_INSTRUMENT ;
+</PRE>
+
+<P>
+Example:
+</P>
+<PRE>
+ SF_INSTRUMENT inst ;
+ sf_command (sndfile, SFC_GET_INSTRUMENT, &inst, sizeof (inst)) ;
+</PRE>
+<DL>
+<DT>Return value:</DT>
+ <dd>SF_TRUE if the file header contains instrument information for the
+ file. SF_FALSE otherwise.
+</DL>
+
+<!-- ========================================================================= -->
+
+
+<A NAME="SFC_SET_INSTRUMENT"></A>
+<H2><BR><B>SFC_SET_INSTRUMENT</B></H2>
+<P>
+Set the instrument information for the file.
+</P>
+<p>
+Parameters:
+</p>
+<PRE>
+ sndfile : A valid SNDFILE* pointer
+ cmd : SFC_GET_INSTRUMENT
+ data : a pointer to an SF_INSTRUMENT struct
+ datasize : sizeof (SF_INSTRUMENT)
+</PRE>
+<P>
+Example:
+</P>
+<PRE>
+ SF_INSTRUMENT inst ;
+ sf_command (sndfile, SFC_SET_INSTRUMENT, &inst, sizeof (inst)) ;
+</PRE>
+<DL>
+<DT>Return value:</DT>
+ <dd>SF_TRUE if the file header contains instrument information for the
+ file. SF_FALSE otherwise.
+</DL>
+
+<!-- ========================================================================= -->
+
+
+<A NAME="SFC_SET_VBR_ENCODING_QUALITY"></A>
+<H2><BR><B>SFC_SET_VBR_ENCODING_QUALITY</B></H2>
+<P>
+Set the Variable Bite Rate encoding quality.
+Currenly only implemented fro Ogg/Vorbis files.
+</P>
+<p>
+Parameters:
+</p>
+<PRE>
+ sndfile : A valid SNDFILE* pointer
+ cmd : SFC_SET_VBR_ENCODING_QUALITY
+ data : a pointer to double specifing VBR quality
+ datasize : sizeof (double)
+</PRE>
+<P>
+Example:
+</P>
+<PRE>
+ double quality = 0.5 ;
+ sf_command (sndfile, SFC_SET_VBR_ENCODING_QUALITY, &quality, sizeof (double)) ;
+</PRE>
+<DL>
+<DT>Return value:</DT>
+ <dd>SF_TRUE if VBR encoding quality was set.
+ SF_FALSE otherwise.
+</DL>
+
+<!-- ========================================================================= -->
+
<HR>
<P>
<A HREF="http://www.mega-nerd.com/libsndfile/">
http://www.mega-nerd.com/libsndfile/</A>.
<BR>
-Version : 1.0.19
+Version : 1.0.25
</P>
</BODY>
<!-- Another version at the bottom of the page. -->
<META NAME="Description" CONTENT="The libsndfile API.">
<META NAME="Keywords" CONTENT="WAV AIFF AU libsndfile sound audio dsp Linux">
- <LINK REL=StyleSheet HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="print.css" TYPE="text/css" MEDIA="print">
</HEAD>
<BODY>
<A HREF="http://www.mega-nerd.com/libsndfile/">
http://www.mega-nerd.com/libsndfile/</A>.
<BR>
-Version : 1.0.19
+Version : 1.0.25
</P>
</BODY>
<META NAME="Author" CONTENT="Erik de Castro Lopo (erikd AT mega-nerd DOT com)">
<META NAME="Description" CONTENT="The libsndfile API.">
<META NAME="Keywords" CONTENT="WAV AIFF AU libsndfile sound audio dsp Linux">
- <LINK REL=StyleSheet HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="print.css" TYPE="text/css" MEDIA="print">
</HEAD>
<!-- pepper -->
<BODY>
libsndfile
</TITLE>
<META NAME="Author" CONTENT="Erik de Castro Lopo (erikd AT mega-nerd DOT com)">
- <META NAME="Version" CONTENT="libsndfile-1.0.19">
+ <META NAME="Version" CONTENT="libsndfile-1.0.25">
<META NAME="Description" CONTENT="The libsndfile Home Page">
<META NAME="Keywords" CONTENT="WAV AIFF AU SVX PAF NIST W64 libsndfile sound audio dsp Linux">
<META NAME="ROBOTS" CONTENT="NOFOLLOW">
- <LINK REL=StyleSheet HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="print.css" TYPE="text/css" MEDIA="print">
</HEAD>
<BODY>
<!-- pepper -->
<P>
The library was written to compile and run on a Linux system but should compile
- and run on just about any Unix (including MacOSX).
- It can also be compiled and run on Win32 systems using the Microsoft compiler and
- MacOS (OS9 and earlier) using the Metrowerks compiler.
- There are directions for compiling libsndfile on these platforms in the Win32 and
- MacOS directories of the source code distribution.
+ and run on just about any Unix (including MacOS X).
+ There are also pre-compiled binaries available for 32 and 64 bit windows.
</P>
<P>
It was designed to handle both little-endian (such as WAV) and big-endian
</P>
<!-- pepper -->
<UL>
- <LI>i586-pc-linux-gnu (Linux on PC hardware)
- <LI>powerpc-unknown-linux-gnu (Linux on Apple Mac hardware)
- <LI>powerpc-apple-darwin7.0 (Mac OS X 10.3)
- <LI>sparc-sun-solaris2.8 (using gcc)
- <LI>mips-sgi-irix5.3 (using gcc)
- <LI>QNX 6.0
- <LI>i386-unknown-openbsd2.9
+ <LI>Every platform supported by Debian GNU/Linux including x86_64-linux-gnu,
+ i486-linux-gnu, powerpc-linux-gnu, sparc-linux-gnu, alpha-linux-gnu,
+ mips-linux-gnu and armel-linux-gnu.</LI>
+ <LI>arm-linux-androideab (Android phones OS)</LI>
+ <LI>powerpc-apple-darwin7.0 (Mac OS X 10.3)</LI>
+ <LI>sparc-sun-solaris2.8 (using gcc)</LI>
+ <LI>mips-sgi-irix5.3 (using gcc)</LI>
+ <LI>QNX 6.0</LI>
+ <LI>i386-unknown-openbsd2.9</LI>
</UL>
<!-- pepper -->
<P>
- At the moment, each new release is being tested on i386 Linux, PowerPC Linux,
- MacOSX on PowerPC and Win32.
+ At the moment, each new release is being tested on i386 Linux, x86_64 Linux,
+ PowerPC Linux, Win32 and Win64.
</P>
<!-- pepper -->
<LI>Version 1.0.5 (May 03 2003) One new file format and new functionality.
<LI>Version 1.0.6 (Feb 08 2004) Large file fix for Linux/Solaris, new functionality
and Win32 improvements.
- <LI>Version 1.0.7 (Feb 24 2004) Fix build problems on MacOSX and fix ia64/MIPS etc
+ <LI>Version 1.0.7 (Feb 24 2004) Fix build problems on MacOS X and fix ia64/MIPS etc
clip mode detction.
<LI>Version 1.0.8 (Mar 14 2004) Minor bug fixes.
<LI>Version 1.0.9 (Mar 30 2004) Add AVR format. Improve handling of some WAV files.
<LI>Version 1.0.17 (Aug 31 2006) Add C++ wrapper sndfile.hh. Minor bug fixes and cleanups.
<LI>Version 1.0.18 (Feb 07 2009) Add Ogg/Vorbis suppport, remove captive libraries, many
new features and bug fixes. Generate Win32 and Win64 pre-compiled binaries.
- <LI>Version 1.0.19 (Mar 02 2009) Fix for CVE-2009-0186. Huge number of minor fixes as a
+ <LI>Version 1.0.19 (Mar 02 2009) Fix for CVE-2009-0186. Huge number of minor fixes as a
result of static analysis.
+ <LI>Version 1.0.20 (May 14 2009) Fix for potential heap overflow.
+ <LI>Version 1.0.21 (December 13 2009) Bunch of minor bug fixes.
+ <LI>Version 1.0.22 (October 04 2010) Bunch of minor bug fixes.
+ <LI>Version 1.0.23 (October 10 2010) Minor bug fixes.
+ <LI>Version 1.0.24 (March 23 2011) Minor bug fixes.
+ <LI>Version 1.0.25 (July 13 2011) Fix for Secunia Advisory SA45125. Minor bug fixes and
+ improvements.
</UL>
<A NAME="Similar"></A>
<a href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">version 2.1</a>
and
<a href="http://www.gnu.org/copyleft/lesser.html">version 3</a>.
- To mamximise the compatibility of libsndfile, the user may choose to use libsndfile
+ To maximise the compatibility of libsndfile, the user may choose to use libsndfile
under either of the above two licenses.
You can also read a simple explanation of the ideas behind the GPL and the LGPL
<A HREF="http://www.gnu.org/copyleft/copyleft.html">here</A>.
<A HREF="http://www.gnu.org/">Free Software</A>
or
<A HREF="http://www.opensource.org/">Open Source</A>.
- However, if you put in a great deal of effort building a huge application
+ However, if you put in a great deal of effort building a significant application
which simply uses libsndfile for file I/O, then I have no problem with you releasing
that as closed source and charging as much money as you want for it as long as you
abide by <A HREF="http://www.gnu.org/copyleft/lesser.html">the license</A>.
</P>
-<P>
- What I don't like to see is things like Steve Dekorte's <b>SoundConverter</b>
- (no I won't link to his page) for Mac OSX.
- Mr Dekorte has grabbed a number of Free Software packages and wrapped them in a
- rather amateurish, buggy GUI and released the result as shareware.
- He charges US$10 for the full version when his contribution to the whole is, by
- his own
- <A HREF="http://groups.google.com/groups?selm=3F9B8F8B.7853300B@mega-nerd.com">
- admission</A>,
- less than 10%.
-</P>
-
<A NAME="Download"></A>
<H1><B>Download</B></H1>
<P>
</P>
<UL>
<LI>Source code as a .tar.gz :
- <A HREF="libsndfile-1.0.19.tar.gz">libsndfile-1.0.19.tar.gz</A>
+ <A HREF="files/libsndfile-1.0.25.tar.gz">libsndfile-1.0.25.tar.gz</A>
and
- <A HREF="libsndfile-1.0.19.tar.gz.asc">(GPG signature)</A>.
+ <A HREF="files/libsndfile-1.0.25.tar.gz.asc">(GPG signature)</A>.
<LI>Win32 installer:
- <A HREF="libsndfile-1.0.19-w32-setup.exe">
- libsndfile-1.0.19-w32-setup.exe</A> (thoroughly tested under
+ <A HREF="files/libsndfile-1.0.25-w32-setup.exe">
+ libsndfile-1.0.25-w32-setup.exe</A> (thoroughly tested under
<a href="http://www.winehq.com/">Wine</a> and Windows XP).
<LI>Win64 installer:
- <A HREF="libsndfile-1.0.19-w64-setup.exe">
- libsndfile-1.0.19-w64-setup.exe</A> (alpha quality release).
+ <A HREF="files/libsndfile-1.0.25-w64-setup.exe">
+ libsndfile-1.0.25-w64-setup.exe</A>
+ (thoroughly tested on 64 bit Windows 7).
</UL>
<P>
The Win32 installer was compiled for Windows XP but should also work on Windows
-2000 and Vista.
-It may even work on earlier versions of Windows.
-The Win64 is pretty much untested.
+2000, Vista and Windows 7.
</p>
<P>
margin-left : 3% ;
margin-right : 3% ;
}
-h1 {
- font-size : xx-large ;
+h1 {
+ font-size : xx-large ;
background : black ;
- color : #5050FF ;
+ color : #5050FF ;
+ text-align : left ;
+ margin-left : 3% ;
+ margin-right : 3% ;
+}
+h2 {
+ font-size : x-large ;
+ background : black ;
+ color : #5050FF ;
text-align : left ;
margin-left : 3% ;
margin-right : 3% ;
}
-h2 {
- font-size : x-large ;
+h3 {
+ font-size : large ;
background : black ;
color : #5050FF ;
text-align : left ;
margin-left : 3% ;
margin-right : 3% ;
}
-h3 {
- font-size : large ;
+h4 {
+ font-size : medium ;
background : black ;
color : #5050FF ;
text-align : left ;
margin-left : 3% ;
margin-right : 3% ;
}
-h1 {
- font-size : xx-large ;
+h1 {
+ font-size : xx-large ;
background : @HTML_BGCOLOUR@ ;
- color : #5050FF ;
+ color : #5050FF ;
+ text-align : left ;
+ margin-left : 3% ;
+ margin-right : 3% ;
+}
+h2 {
+ font-size : x-large ;
+ background : @HTML_BGCOLOUR@ ;
+ color : #5050FF ;
text-align : left ;
margin-left : 3% ;
margin-right : 3% ;
}
-h2 {
- font-size : x-large ;
+h3 {
+ font-size : large ;
background : @HTML_BGCOLOUR@ ;
color : #5050FF ;
text-align : left ;
margin-left : 3% ;
margin-right : 3% ;
}
-h3 {
- font-size : large ;
+h4 {
+ font-size : medium ;
background : @HTML_BGCOLOUR@ ;
color : #5050FF ;
text-align : left ;
libsndfile Mailing Lists
</TITLE>
<META NAME="Author" CONTENT="Erik de Castro Lopo (erikd AT mega-nerd DOT com)">
- <LINK REL=StyleSheet HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="print.css" TYPE="text/css" MEDIA="print">
</HEAD>
<BODY>
libsndfile and GNU Octave
</TITLE>
<META NAME="Author" CONTENT="Erik de Castro Lopo (erikd AT mega-nerd DOT com)">
- <LINK REL=StyleSheet HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="print.css" TYPE="text/css" MEDIA="print">
</HEAD>
<BODY>
to play the correct types of Octave files.
Using this command line player <B>sndfile-play</B> and a third Octave script
file allows Octave data to be played from within Octave on any of the platforms
- which <B>sndfile-play</B> supports (at the moment: Linux, MacOSX, Solaris and
+ which <B>sndfile-play</B> supports (at the moment: Linux, MacOS X, Solaris and
Win32).
</P>
<PRE>
libsndfile : pkg-config
</TITLE>
<META NAME="Author" CONTENT="Erik de Castro Lopo (erikd AT mega-nerd DOT com)">
- <LINK REL=StyleSheet HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="print.css" TYPE="text/css" MEDIA="print">
</HEAD>
<BODY>
From version 1.0.0 libsndfile has had the ability to read and write files of
greater than 2 Gig in size on most OSes even if sizeof (long) == 4.
OSes which support this feature include Linux (2.4 kernel, glibc6) on x86, PPC and
- probably others, Win32, MacOSX, *BSD, Solaris and probably others.
+ probably others, Win32, MacOS X, *BSD, Solaris and probably others.
OSes on 64 bit processors where the default compile environment is LP64 (longs and
pointers are 64 bit ie Linux on DEC/Compaq/HP Alpha processors) automatically
support large file access.
programs which link to the library.
</P>
<P>
- Note : People using Win32, MacOS (both OSX and pre-OSX) or *BSD can disregard the
+ Note : People using Win32, MacOS (both OS X and pre-OS X) or *BSD can disregard the
rest of this document as it does not apply to either of these OSes.
</P>
<P>
sndfile-info
</TITLE>
<META NAME="Author" CONTENT="Erik de Castro Lopo (erikd AT mega-nerd DOT com)">
- <LINK REL=StyleSheet HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="print.css" TYPE="text/css" MEDIA="print">
</HEAD>
<BODY>
libsndfile Tutorial
</TITLE>
<META NAME="Author" CONTENT="Erik de Castro Lopo (erikd AT mega-nerd DOT com)">
- <LINK REL=StyleSheet HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="print.css" TYPE="text/css" MEDIA="print">
</HEAD>
<BODY>
Building libsndfile on Win32
</TITLE>
<META NAME="Author" CONTENT="Erik de Castro Lopo (erikd AT mega-nerd DOT com)">
- <LINK REL=StyleSheet HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="libsndfile.css" TYPE="text/css" MEDIA="all">
+ <LINK REL="stylesheet" HREF="print.css" TYPE="text/css" MEDIA="print">
</HEAD>
<BODY>
+++ /dev/null
-/*
-** Copyright (C) 2002-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 <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <sys/stat.h>
-
-#include <sndfile.h>
-
-#define BUFFER_LEN 1024
-
-static void usage_exit (char *progname) ;
-static int is_data_really_float (SNDFILE *sndfile) ;
-static void fix_file (char *filename) ;
-static off_t file_size (char *filename) ;
-
-static union
-{ int i [BUFFER_LEN] ;
- float f [BUFFER_LEN] ;
-} buffer ;
-
-int
-main (int argc, char *argv [])
-{ SNDFILE *sndfile ;
- SF_INFO sfinfo ;
- int k, data_is_float, converted = 0 ;
-
- puts ("\nCooledit Fixer.\n---------------") ;
-
- if (argc < 2)
- usage_exit (argv [0]) ;
-
- for (k = 1 ; k < argc ; k++)
- { if ((sndfile = sf_open (argv [k], SFM_READ, &sfinfo)) == NULL)
- { /*-printf ("Failed to open : %s\n", argv [k]) ;-*/
- continue ;
- } ;
-
- if (sfinfo.format != (SF_FORMAT_WAV | SF_FORMAT_PCM_32))
- { /*-printf ("%-50s : not a 32 bit PCM WAV file.\n", argv [k]) ;-*/
- sf_close (sndfile) ;
- continue ;
- } ;
-
- data_is_float = is_data_really_float (sndfile) ;
-
- sf_close (sndfile) ;
-
- if (data_is_float == SF_FALSE)
- { /*-printf ("%-50s : not a Cooledit abomination.\n", argv [k]) ;-*/
- continue ;
- } ;
-
- fix_file (argv [k]) ;
- converted ++ ;
- } ;
-
- if (converted == 0)
- puts ("\nNo files converted.") ;
-
- puts ("") ;
-
- return 0 ;
-} /* main */
-
-
-static void
-usage_exit (char *progname)
-{ char *cptr ;
-
- if ((cptr = strrchr (progname, '/')))
- progname = cptr + 1 ;
- if ((cptr = strrchr (progname, '\\')))
- progname = cptr + 1 ;
-
- printf ("\n Usage : %s <filename>\n", progname) ;
- puts ("\n"
- "Fix broken files created by Syntrillium's Cooledit. These files are \n"
- "marked as containing PCM data but actually contain floating point \n"
- "data. Only the broken files created by Cooledit are processed. All \n"
- "other files remain untouched.\n"
- "\n"
- "More than one file may be included on the command line. \n"
- ) ;
-
- exit (1) ;
-} /* usage_exit */
-
-static int
-is_data_really_float (SNDFILE *sndfile)
-{ int k, readcount ;
-
- while ((readcount = sf_read_int (sndfile, buffer.i, BUFFER_LEN)) > 0)
- { for (k = 0 ; k < readcount ; k++)
- { if (buffer.i [k] == 0)
- continue ;
-
- if (fabs (buffer.f [k]) > 32768.0)
- return SF_FALSE ;
- } ;
- } ;
-
- return SF_TRUE ;
-} /* is_data_really_float */
-
-static void
-fix_file (char *filename)
-{ static char newfilename [512] ;
-
- SNDFILE *infile, *outfile ;
- SF_INFO sfinfo ;
- int readcount, k ;
- float normfactor ;
- char *cptr ;
-
- printf ("\nFixing : %s\n", filename) ;
-
- if ((infile = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
- { printf ("Not able to open input file %s\n", filename) ;
- exit (1) ;
- } ;
-
- if (strlen (filename) >= sizeof (newfilename) - 1)
- { puts ("Error : Path name too long.\n") ;
- exit (1) ;
- } ;
-
- strncpy (newfilename, filename, sizeof (newfilename)) ;
- newfilename [sizeof (newfilename) - 1] = 0 ;
-
- if ((cptr = strrchr (newfilename, '/')) == NULL)
- cptr = strrchr (newfilename, '\\') ;
-
- if (cptr)
- { cptr [1] = 0 ;
- strncat (newfilename, "fixed.wav", sizeof (newfilename) - strlen (newfilename) - 1) ;
- }
- else
- strncpy (newfilename, "fixed.wav", sizeof (newfilename) - 1) ;
-
- newfilename [sizeof (newfilename) - 1] = 0 ;
-
- printf (" Output : %s\n", newfilename) ;
-
- sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT ;
-
- if ((outfile = sf_open (newfilename, SFM_WRITE, &sfinfo)) == NULL)
- { printf ("Not able to output open file %s\n", filename) ;
- exit (1) ;
- } ;
-
- /* Find the file peak. sf-command (SFC_CALC_SIGNAL_MAX) cannot be used. */
-
- normfactor = 0.0 ;
-
- while ((readcount = sf_read_int (infile, buffer.i, BUFFER_LEN)) > 0)
- { for (k = 0 ; k < readcount ; k++)
- if (fabs (buffer.f [k]) > normfactor)
- normfactor = fabs (buffer.f [k]) ;
- } ;
-
- printf (" Peak : %g\n", normfactor) ;
-
- normfactor = 1.0 / normfactor ;
-
- sf_seek (infile, 0, SEEK_SET) ;
-
- while ((readcount = sf_read_int (infile, buffer.i, BUFFER_LEN)) > 0)
- { for (k = 0 ; k < readcount ; k++)
- buffer.f [k] *= normfactor ;
- sf_write_float (outfile, buffer.f, readcount) ;
- } ;
-
- sf_close (infile) ;
- sf_close (outfile) ;
-
- if (abs (file_size (filename) - file_size (newfilename)) > 50)
- { puts ("Error : file size mismatch.\n") ;
- exit (1) ;
- } ;
-
- printf (" Renaming : %s\n", filename) ;
-
- if (remove (filename) != 0)
- { perror ("rename") ;
- exit (1) ;
- } ;
-
- if (rename (newfilename, filename) != 0)
- { perror ("rename") ;
- exit (1) ;
- } ;
-
- return ;
-} /* fix_file */
-
-static off_t
-file_size (char *filename)
-{ struct stat buf ;
-
- if (stat (filename, &buf) != 0)
- { perror ("stat") ;
- exit (1) ;
- } ;
-
- return buf.st_size ;
-} /* file_size */
-/*
-** 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: 5475655e-3898-40ff-969b-c8ab2351b0e4
-*/
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** All rights reserved.
**
} ;
while ((readcount = sf_read_float (infile, buffer, BUFFER_LEN)) > 0)
- sf_write_float (outfile, buffer, BUFFER_LEN) ;
+ sf_write_float (outfile, buffer, readcount) ;
sf_close (infile) ;
sf_close (outfile) ;
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** All rights reserved.
**
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** All rights reserved.
**
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** All rights reserved.
**
+++ /dev/null
-/*
-** 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 <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <sndfile.h>
-
-#define BUFFER_LEN 1024
-
-
-typedef struct
-{ char *infilename, *outfilename ;
- SF_INFO infileinfo, outfileinfo ;
-} OptionData ;
-
-typedef struct
-{ const char *ext ;
- int len ;
- int format ;
-} OUTPUT_FORMAT_MAP ;
-
-static void copy_metadata (SNDFILE *outfile, SNDFILE *infile) ;
-static void copy_data_fp (SNDFILE *outfile, SNDFILE *infile, int channels) ;
-static void copy_data_int (SNDFILE *outfile, SNDFILE *infile, int channels) ;
-
-static OUTPUT_FORMAT_MAP format_map [] =
-{
- { "aif", 3, SF_FORMAT_AIFF },
- { "wav", 0, SF_FORMAT_WAV },
- { "au", 0, SF_FORMAT_AU },
- { "caf", 0, SF_FORMAT_CAF },
- { "flac", 0, SF_FORMAT_FLAC },
- { "snd", 0, SF_FORMAT_AU },
- { "svx", 0, SF_FORMAT_SVX },
- { "paf", 0, SF_ENDIAN_BIG | SF_FORMAT_PAF },
- { "fap", 0, SF_ENDIAN_LITTLE | SF_FORMAT_PAF },
- { "gsm", 0, SF_FORMAT_RAW },
- { "nist", 0, SF_FORMAT_NIST },
- { "ircam", 0, SF_FORMAT_IRCAM },
- { "sf", 0, SF_FORMAT_IRCAM },
- { "voc", 0, SF_FORMAT_VOC },
- { "w64", 0, SF_FORMAT_W64 },
- { "raw", 0, SF_FORMAT_RAW },
- { "mat4", 0, SF_FORMAT_MAT4 },
- { "mat5", 0, SF_FORMAT_MAT5 },
- { "mat", 0, SF_FORMAT_MAT4 },
- { "pvf", 0, SF_FORMAT_PVF },
- { "sds", 0, SF_FORMAT_SDS },
- { "sd2", 0, SF_FORMAT_SD2 },
- { "vox", 0, SF_FORMAT_RAW },
- { "xi", 0, SF_FORMAT_XI }
-} ; /* format_map */
-
-static int
-guess_output_file_type (char *str, int format)
-{ char buffer [16], *cptr ;
- int k ;
-
- format &= SF_FORMAT_SUBMASK ;
-
- if ((cptr = strrchr (str, '.')) == NULL)
- return 0 ;
-
- strncpy (buffer, cptr + 1, 15) ;
- buffer [15] = 0 ;
-
- for (k = 0 ; buffer [k] ; k++)
- buffer [k] = tolower ((buffer [k])) ;
-
- if (strcmp (buffer, "gsm") == 0)
- return SF_FORMAT_RAW | SF_FORMAT_GSM610 ;
-
- if (strcmp (buffer, "vox") == 0)
- return SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM ;
-
- for (k = 0 ; k < (int) (sizeof (format_map) / sizeof (format_map [0])) ; k++)
- { if (format_map [k].len > 0 && strncmp (buffer, format_map [k].ext, format_map [k].len) == 0)
- return format_map [k].format | format ;
- else if (strcmp (buffer, format_map [k].ext) == 0)
- return format_map [k].format | format ;
- } ;
-
- return 0 ;
-} /* guess_output_file_type */
-
-
-static void
-print_usage (char *progname)
-{ SF_FORMAT_INFO info ;
-
- int k ;
-
- printf ("\nUsage : %s [encoding] <input file> <output file>\n", progname) ;
- puts ("\n"
- " where [encoding] may be one of the following:\n\n"
- " -pcms8 : force the output to signed 8 bit pcm\n"
- " -pcmu8 : force the output to unsigned 8 bit pcm\n"
- " -pcm16 : force the output to 16 bit pcm\n"
- " -pcm24 : force the output to 24 bit pcm\n"
- " -pcm32 : force the output to 32 bit pcm\n"
- " -float32 : force the output to 32 bit floating point"
- ) ;
- puts (
- " -ulaw : force the output ULAW\n"
- " -alaw : force the output ALAW\n"
- " -ima-adpcm : force the output to IMA ADPCM (WAV only)\n"
- " -ms-adpcm : force the output to MS ADPCM (WAV only)\n"
- " -gsm610 : force the GSM6.10 (WAV only)\n"
- " -dwvw12 : force the output to 12 bit DWVW (AIFF only)\n"
- " -dwvw16 : force the output to 16 bit DWVW (AIFF only)\n"
- " -dwvw24 : force the output to 24 bit DWVW (AIFF only)\n"
- ) ;
-
- puts (
- " The format of the output file is determined by the file extension of the\n"
- " output file name. The following extensions are currently understood:\n"
- ) ;
-
- for (k = 0 ; k < (int) (sizeof (format_map) / sizeof (format_map [0])) ; k++)
- { info.format = format_map [k].format ;
- sf_command (NULL, SFC_GET_FORMAT_INFO, &info, sizeof (info)) ;
- printf (" %-10s : %s\n", format_map [k].ext, info.name) ;
- } ;
-
- puts ("") ;
-} /* print_usage */
-
-int
-main (int argc, char * argv [])
-{ char *progname, *infilename, *outfilename ;
- SNDFILE *infile = NULL, *outfile = NULL ;
- SF_INFO sfinfo ;
- int k, outfilemajor, outfileminor = 0, infileminor ;
-
- progname = strrchr (argv [0], '/') ;
- progname = progname ? progname + 1 : argv [0] ;
-
- if (argc < 3 || argc > 5)
- { print_usage (progname) ;
- return 1 ;
- } ;
-
- infilename = argv [argc-2] ;
- outfilename = argv [argc-1] ;
-
- if (strcmp (infilename, outfilename) == 0)
- { printf ("Error : Input and output filenames are the same.\n\n") ;
- print_usage (progname) ;
- return 1 ;
- } ;
-
- if (infilename [0] == '-')
- { printf ("Error : Input filename (%s) looks like an option.\n\n", infilename) ;
- print_usage (progname) ;
- return 1 ;
- } ;
-
- if (outfilename [0] == '-')
- { printf ("Error : Output filename (%s) looks like an option.\n\n", outfilename) ;
- print_usage (progname) ;
- return 1 ;
- } ;
-
- for (k = 1 ; k < argc - 2 ; k++)
- { if (! strcmp (argv [k], "-pcms8"))
- { outfileminor = SF_FORMAT_PCM_S8 ;
- continue ;
- } ;
- if (! strcmp (argv [k], "-pcmu8"))
- { outfileminor = SF_FORMAT_PCM_U8 ;
- continue ;
- } ;
- if (! strcmp (argv [k], "-pcm16"))
- { outfileminor = SF_FORMAT_PCM_16 ;
- continue ;
- } ;
- if (! strcmp (argv [k], "-pcm24"))
- { outfileminor = SF_FORMAT_PCM_24 ;
- continue ;
- } ;
- if (! strcmp (argv [k], "-pcm32"))
- { outfileminor = SF_FORMAT_PCM_32 ;
- continue ;
- } ;
- if (! strcmp (argv [k], "-float32"))
- { outfileminor = SF_FORMAT_FLOAT ;
- continue ;
- } ;
- if (! strcmp (argv [k], "-ulaw"))
- { outfileminor = SF_FORMAT_ULAW ;
- continue ;
- } ;
- if (! strcmp (argv [k], "-alaw"))
- { outfileminor = SF_FORMAT_ALAW ;
- continue ;
- } ;
- if (! strcmp (argv [k], "-ima-adpcm"))
- { outfileminor = SF_FORMAT_IMA_ADPCM ;
- continue ;
- } ;
- if (! strcmp (argv [k], "-ms-adpcm"))
- { outfileminor = SF_FORMAT_MS_ADPCM ;
- continue ;
- } ;
- if (! strcmp (argv [k], "-gsm610"))
- { outfileminor = SF_FORMAT_GSM610 ;
- continue ;
- } ;
- if (! strcmp (argv [k], "-dwvw12"))
- { outfileminor = SF_FORMAT_DWVW_12 ;
- continue ;
- } ;
- if (! strcmp (argv [k], "-dwvw16"))
- { outfileminor = SF_FORMAT_DWVW_16 ;
- continue ;
- } ;
- if (! strcmp (argv [k], "-dwvw24"))
- { outfileminor = SF_FORMAT_DWVW_24 ;
- continue ;
- } ;
-
- printf ("Error : Not able to decode argunment '%s'.\n", argv [k]) ;
- exit (1) ;
- } ;
-
- if ((infile = sf_open (infilename, SFM_READ, &sfinfo)) == NULL)
- { printf ("Not able to open input file %s.\n", infilename) ;
- puts (sf_strerror (NULL)) ;
- return 1 ;
- } ;
-
- infileminor = sfinfo.format & SF_FORMAT_SUBMASK ;
-
- if ((sfinfo.format = guess_output_file_type (outfilename, sfinfo.format)) == 0)
- { printf ("Error : Not able to determine output file type for %s.\n", outfilename) ;
- return 1 ;
- } ;
-
- outfilemajor = sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_ENDMASK) ;
-
- if (outfileminor == 0)
- outfileminor = sfinfo.format & SF_FORMAT_SUBMASK ;
-
- if (outfileminor != 0)
- sfinfo.format = outfilemajor | outfileminor ;
- else
- sfinfo.format = outfilemajor | (sfinfo.format & SF_FORMAT_SUBMASK) ;
-
- if ((sfinfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_XI)
- switch (sfinfo.format & SF_FORMAT_SUBMASK)
- { case SF_FORMAT_PCM_16 :
- sfinfo.format = outfilemajor | SF_FORMAT_DPCM_16 ;
- break ;
-
- case SF_FORMAT_PCM_S8 :
- case SF_FORMAT_PCM_U8 :
- sfinfo.format = outfilemajor | SF_FORMAT_DPCM_8 ;
- break ;
- } ;
-
- if (sf_format_check (&sfinfo) == 0)
- { printf ("Error : output file format is invalid (0x%08X).\n", sfinfo.format) ;
- return 1 ;
- } ;
-
- /* Open the output file. */
- if ((outfile = sf_open (outfilename, SFM_WRITE, &sfinfo)) == NULL)
- { printf ("Not able to open output file %s : %s\n", outfilename, sf_strerror (NULL)) ;
- return 1 ;
- } ;
-
- /* Copy the metadata */
- copy_metadata (outfile, infile) ;
-
- if ((outfileminor == SF_FORMAT_DOUBLE) || (outfileminor == SF_FORMAT_FLOAT) ||
- (infileminor == SF_FORMAT_DOUBLE) || (infileminor == SF_FORMAT_FLOAT))
- copy_data_fp (outfile, infile, sfinfo.channels) ;
- else
- copy_data_int (outfile, infile, sfinfo.channels) ;
-
- sf_close (infile) ;
- sf_close (outfile) ;
-
- return 0 ;
-} /* main */
-
-static void
-copy_metadata (SNDFILE *outfile, SNDFILE *infile)
-{ SF_INSTRUMENT inst ;
- const char *str ;
- int k, err = 0 ;
-
- for (k = SF_STR_FIRST ; k <= SF_STR_LAST ; k++)
- { str = sf_get_string (infile, k) ;
- if (str != NULL)
- err = sf_set_string (outfile, k, str) ;
- } ;
-
- memset (&inst, 0, sizeof (inst)) ;
- if (sf_command (infile, SFC_GET_INSTRUMENT, &inst, sizeof (inst)) == SF_TRUE)
- sf_command (outfile, SFC_SET_INSTRUMENT, &inst, sizeof (inst)) ;
-
-} /* copy_metadata */
-
-static void
-copy_data_fp (SNDFILE *outfile, SNDFILE *infile, int channels)
-{ static double data [BUFFER_LEN], max ;
- int frames, readcount, k ;
-
- frames = BUFFER_LEN / channels ;
- readcount = frames ;
-
- sf_command (infile, SFC_CALC_SIGNAL_MAX, &max, sizeof (max)) ;
-
- if (max < 1.0)
- { while (readcount > 0)
- { readcount = sf_readf_double (infile, data, frames) ;
- sf_writef_double (outfile, data, readcount) ;
- } ;
- }
- else
- { sf_command (infile, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
-
- while (readcount > 0)
- { readcount = sf_readf_double (infile, data, frames) ;
- for (k = 0 ; k < readcount * channels ; k++)
- data [k] /= max ;
- sf_writef_double (outfile, data, readcount) ;
- } ;
- } ;
-
- return ;
-} /* copy_data_fp */
-
-static void
-copy_data_int (SNDFILE *outfile, SNDFILE *infile, int channels)
-{ static int data [BUFFER_LEN] ;
- int frames, readcount ;
-
- frames = BUFFER_LEN / channels ;
- readcount = frames ;
-
- while (readcount > 0)
- { readcount = sf_readf_int (infile, data, frames) ;
- sf_writef_int (outfile, data, readcount) ;
- } ;
-
- return ;
-} /* copy_data_int */
-
-/*
-** 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: 259682b3-2887-48a6-b5bb-3cde00521ba3
-*/
+++ /dev/null
-/*
-** Copyright (C) 1999-2006 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 <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <math.h>
-
-#include <sndfile.h>
-
-#define BUFFER_LEN (1 << 16)
-
-#if (defined (WIN32) || defined (_WIN32))
-#define snprintf _snprintf
-#endif
-
-static void print_version (void) ;
-static void print_usage (const char *progname) ;
-
-static void info_dump (const char *filename) ;
-static void instrument_dump (const char *filename) ;
-static void broadcast_dump (const char *filename) ;
-
-int
-main (int argc, char *argv [])
-{ int k ;
-
- print_version () ;
-
- if (argc < 2 || strcmp (argv [1], "--help") == 0 || strcmp (argv [1], "-h") == 0)
- { char *progname ;
-
- progname = strrchr (argv [0], '/') ;
- progname = progname ? progname + 1 : argv [0] ;
-
- print_usage (progname) ;
- return 1 ;
- } ;
-
- if (strcmp (argv [1], "-i") == 0)
- { instrument_dump (argv [2]) ;
- return 0 ;
- } ;
-
- if (strcmp (argv [1], "-b") == 0)
- { broadcast_dump (argv [2]) ;
- return 0 ;
- } ;
-
- for (k = 1 ; k < argc ; k++)
- info_dump (argv [k]) ;
-
- return 0 ;
-} /* main */
-
-/*==============================================================================
-** Print version and usage.
-*/
-
-static double data [BUFFER_LEN] ;
-
-static void
-print_version (void)
-{ char buffer [256] ;
-
- sf_command (NULL, SFC_GET_LIB_VERSION, buffer, sizeof (buffer)) ;
- printf ("\nVersion : %s\n\n", buffer) ;
-} /* print_version */
-
-
-static void
-print_usage (const char *progname)
-{ printf ("Usage :\n %s <file> ...\n", progname) ;
- printf (" Prints out information about one or more sound files.\n\n") ;
- printf (" %s -i <file>\n", progname) ;
- printf (" Prints out the instrument data for the given file.\n\n") ;
- printf (" %s -b <file>\n", progname) ;
- printf (" Prints out the broadcast WAV info for the given file.\n\n") ;
-#if (defined (_WIN32) || defined (WIN32))
- printf ("This is a Unix style command line application which\n"
- "should be run in a MSDOS box or Command Shell window.\n\n") ;
- printf ("Sleeping for 5 seconds before exiting.\n\n") ;
- fflush (stdout) ;
-
- /* This is the officially blessed by microsoft way but I can't get
- ** it to link.
- ** Sleep (15) ;
- ** Instead, use this:
- */
- _sleep (5 * 1000) ;
-#endif
-} /* print_usage */
-
-/*==============================================================================
-** Dumping of sndfile info.
-*/
-
-static double data [BUFFER_LEN] ;
-
-static double
-get_signal_max (SNDFILE *file)
-{ double max, temp ;
- int readcount, k, save_state ;
-
- save_state = sf_command (file, SFC_GET_NORM_DOUBLE, NULL, 0) ;
- sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
-
- max = 0.0 ;
- while ((readcount = sf_read_double (file, data, BUFFER_LEN)))
- { for (k = 0 ; k < readcount ; k++)
- { temp = fabs (data [k]) ;
- if (temp > max)
- max = temp ;
- } ;
- } ;
-
- sf_command (file, SFC_SET_NORM_DOUBLE, NULL, save_state) ;
-
- return max ;
-} /* get_signal_max */
-
-static double
-calc_decibels (SF_INFO * sfinfo, double max)
-{ double decibels ;
-
- switch (sfinfo->format & SF_FORMAT_SUBMASK)
- { case SF_FORMAT_PCM_U8 :
- case SF_FORMAT_PCM_S8 :
- decibels = max / 0x80 ;
- break ;
-
- case SF_FORMAT_PCM_16 :
- decibels = max / 0x8000 ;
- break ;
-
- case SF_FORMAT_PCM_24 :
- decibels = max / 0x800000 ;
- break ;
-
- case SF_FORMAT_PCM_32 :
- decibels = max / 0x80000000 ;
- break ;
-
- case SF_FORMAT_FLOAT :
- case SF_FORMAT_DOUBLE :
- decibels = max / 1.0 ;
- break ;
-
- default :
- decibels = max / 0x8000 ;
- break ;
- } ;
-
- return 20.0 * log10 (decibels) ;
-} /* calc_decibels */
-
-static const char *
-generate_duration_str (SF_INFO *sfinfo)
-{ static char str [128] ;
-
- int seconds ;
-
- memset (str, 0, sizeof (str)) ;
-
- if (sfinfo->samplerate < 1)
- return NULL ;
-
- if (sfinfo->frames / sfinfo->samplerate > 0x7FFFFFFF)
- return "unknown" ;
-
- seconds = sfinfo->frames / sfinfo->samplerate ;
-
- snprintf (str, sizeof (str) - 1, "%02d:", seconds / 60 / 60) ;
-
- seconds = seconds % (60 * 60) ;
- snprintf (str + strlen (str), sizeof (str) - strlen (str) - 1, "%02d:", seconds / 60) ;
-
- seconds = seconds % 60 ;
- snprintf (str + strlen (str), sizeof (str) - strlen (str) - 1, "%02d.", seconds) ;
-
- seconds = ((1000 * sfinfo->frames) / sfinfo->samplerate) % 1000 ;
- snprintf (str + strlen (str), sizeof (str) - strlen (str) - 1, "%03d", seconds) ;
-
- return str ;
-} /* generate_duration_str */
-
-static void
-info_dump (const char *filename)
-{ static char strbuffer [BUFFER_LEN] ;
- SNDFILE *file ;
- SF_INFO sfinfo ;
- double signal_max, decibels ;
-
- memset (&sfinfo, 0, sizeof (sfinfo)) ;
-
- if ((file = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
- { printf ("Error : Not able to open input file %s.\n", filename) ;
- fflush (stdout) ;
- memset (data, 0, sizeof (data)) ;
- sf_command (file, SFC_GET_LOG_INFO, strbuffer, BUFFER_LEN) ;
- puts (strbuffer) ;
- puts (sf_strerror (NULL)) ;
- return ;
- } ;
-
- printf ("========================================\n") ;
- sf_command (file, SFC_GET_LOG_INFO, strbuffer, BUFFER_LEN) ;
- puts (strbuffer) ;
- printf ("----------------------------------------\n") ;
-
- if (file == NULL)
- { printf ("Error : Not able to open input file %s.\n", filename) ;
- fflush (stdout) ;
- memset (data, 0, sizeof (data)) ;
- puts (sf_strerror (NULL)) ;
- }
- else
- { printf ("Sample Rate : %d\n", sfinfo.samplerate) ;
- if (sfinfo.frames > 0x7FFFFFFF)
- printf ("Frames : unknown\n") ;
- else
- printf ("Frames : %ld\n", (long) sfinfo.frames) ;
- printf ("Channels : %d\n", sfinfo.channels) ;
- printf ("Format : 0x%08X\n", sfinfo.format) ;
- printf ("Sections : %d\n", sfinfo.sections) ;
- printf ("Seekable : %s\n", (sfinfo.seekable ? "TRUE" : "FALSE")) ;
- printf ("Duration : %s\n", generate_duration_str (&sfinfo)) ;
-
- /* Do not use sf_signal_max because it doesn work for non-seekable files . */
- signal_max = get_signal_max (file) ;
- decibels = calc_decibels (&sfinfo, signal_max) ;
- printf ("Signal Max : %g (%4.2f dB)\n\n", signal_max, decibels) ;
- } ;
-
- sf_close (file) ;
-
-} /* info_dump */
-
-/*==============================================================================
-** Dumping of SF_INSTRUMENT data.
-*/
-
-static const char *
-str_of_type (int mode)
-{ switch (mode)
- { case SF_LOOP_NONE : return "none" ;
- case SF_LOOP_FORWARD : return "fwd " ;
- case SF_LOOP_BACKWARD : return "back" ;
- case SF_LOOP_ALTERNATING : return "alt " ;
- default : break ;
- } ;
-
- return "????" ;
-} /* str_of_mode */
-
-static void
-instrument_dump (const char *filename)
-{ SNDFILE *file ;
- SF_INFO sfinfo ;
- SF_INSTRUMENT inst ;
- int got_inst, k ;
-
- memset (&sfinfo, 0, sizeof (sfinfo)) ;
-
- if ((file = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
- { printf ("Error : Not able to open input file %s.\n", filename) ;
- fflush (stdout) ;
- memset (data, 0, sizeof (data)) ;
- puts (sf_strerror (NULL)) ;
- return ;
- } ;
-
- got_inst = sf_command (file, SFC_GET_INSTRUMENT, &inst, sizeof (inst)) ;
- sf_close (file) ;
-
- if (got_inst == SF_FALSE)
- { printf ("Error : File '%s' does not contain instrument data.\n\n", filename) ;
- return ;
- } ;
-
- printf ("Instrument : %s\n\n", filename) ;
- printf (" Gain : %d\n", inst.gain) ;
- printf (" Base note : %d\n", inst.basenote) ;
- printf (" Velocity : %d - %d\n", (int) inst.velocity_lo, (int) inst.velocity_hi) ;
- printf (" Key : %d - %d\n", (int) inst.key_lo, (int) inst.key_hi) ;
- printf (" Loop points : %d\n", inst.loop_count) ;
-
- for (k = 0 ; k < inst.loop_count ; k++)
- printf (" %-2d Mode : %s Start : %6d End : %6d Count : %6d\n", k, str_of_type (inst.loops [k].mode), inst.loops [k].start, inst.loops [k].end, inst.loops [k].count) ;
-
- putchar ('\n') ;
-} /* instrument_dump */
-
-static void
-broadcast_dump (const char *filename)
-{ SNDFILE *file ;
- SF_INFO sfinfo ;
- SF_BROADCAST_INFO bext ;
- int got_bext ;
-
- memset (&sfinfo, 0, sizeof (sfinfo)) ;
-
- if ((file = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
- { printf ("Error : Not able to open input file %s.\n", filename) ;
- fflush (stdout) ;
- memset (data, 0, sizeof (data)) ;
- puts (sf_strerror (NULL)) ;
- return ;
- } ;
-
- memset (&bext, 0, sizeof (SF_BROADCAST_INFO)) ;
-
- got_bext = sf_command (file, SFC_GET_BROADCAST_INFO, &bext, sizeof (bext)) ;
- sf_close (file) ;
-
- if (got_bext == SF_FALSE)
- { printf ("Error : File '%s' does not contain broadcast information.\n\n", filename) ;
- return ;
- } ;
-
- printf ("Description : %.*s\n", (int) sizeof (bext.description), bext.description) ;
- printf ("Originator : %.*s\n", (int) sizeof (bext.originator), bext.originator) ;
- printf ("Origination ref : %.*s\n", (int) sizeof (bext.originator_reference), bext.originator_reference) ;
- printf ("Origination date : %.*s\n", (int) sizeof (bext.origination_date), bext.origination_date) ;
- printf ("Origination time : %.*s\n", (int) sizeof (bext.origination_time), bext.origination_time) ;
- printf ("BWF version : %d\n", bext.version) ;
- printf ("UMID : %.*s\n", (int) sizeof (bext.umid), bext.umid) ;
- printf ("Coding history : %.*s\n", bext.coding_history_size, bext.coding_history) ;
-
-} /* broadcast_dump */
-
-/*
-** 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: f59a05db-a182-41de-aedd-d717ce2bb099
-*/
+++ /dev/null
-/*
-** Copyright (C) 2001 Marcus Overhagen <marcus@overhagen.de>
-**
-** 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 <Application.h>
-#include <SoundPlayer.h>
-#include <string.h>
-
-#include <sndfile.h>
-
-#define BUFFER_LEN 1024
-
-/*------------------------------------------------------------------------------
-** BeOS functions for playing a sound.
-*/
-
-#if defined (__BEOS__)
-
-struct shared_data
-{
- BSoundPlayer *player;
- SNDFILE *sndfile;
- SF_INFO sfinfo;
- sem_id finished;
-};
-
-static void
-buffer_callback(void *theCookie, void *buf, size_t size, const media_raw_audio_format &format)
-{
- shared_data *data = (shared_data *)theCookie;
- short *buffer = (short *)buf;
- int count = size / sizeof(short);
- int m, readcount;
-
- if (!data->player->HasData())
- return;
-
- readcount = sf_read_short(data->sndfile, buffer, count);
- if (readcount == 0)
- { data->player->SetHasData(false);
- release_sem(data->finished);
- }
- if (readcount < count)
- { for (m = readcount ; m < count ; m++)
- buffer [m] = 0 ;
- }
- if (data->sfinfo.pcmbitwidth < 16)
- { for (m = 0 ; m < count ; m++)
- buffer [m] *= 256 ;
- }
-}
-
-static void
-beos_play (int argc, char *argv [])
-{
- shared_data data;
- status_t status;
- int k;
-
- /* BSoundPlayer requires a BApplication object */
- BApplication app("application/x-vnd.MarcusOverhagen-sfplay");
-
- for (k = 1 ; k < argc ; k++)
- { printf ("Playing %s\n", argv [k]) ;
- if (! (data.sndfile = sf_open_read (argv [k], &data.sfinfo)))
- { sf_perror (NULL) ;
- continue ;
- } ;
-
- if (data.sfinfo.channels < 1 || data.sfinfo.channels > 2)
- { printf ("Error : channels = %d.\n", data.sfinfo.channels) ;
- sf_close (data.sndfile) ;
- continue ;
- } ;
-
- data.finished = create_sem(0,"finished");
-
- media_raw_audio_format format =
- { data.sfinfo.samplerate,
- data.sfinfo.channels,
- media_raw_audio_format::B_AUDIO_SHORT,
- B_HOST_IS_LENDIAN ? B_MEDIA_LITTLE_ENDIAN : B_MEDIA_BIG_ENDIAN,
- BUFFER_LEN * sizeof(short)
- };
-
- BSoundPlayer player(&format,"player",buffer_callback,NULL,&data);
- data.player = &player;
-
- if ((status = player.InitCheck()) != B_OK)
- {
- printf ("Error : BSoundPlayer init failed, %s.\n", strerror(status)) ;
- delete_sem(data.finished);
- sf_close (data.sndfile) ;
- continue ;
- }
-
- player.SetVolume(1.0);
- player.Start();
- player.SetHasData(true);
- acquire_sem(data.finished);
- player.Stop();
- delete_sem(data.finished);
-
- sf_close (data.sndfile) ;
-
- } ;
-
-} /* beos_play */
-
-#endif
-
-/*==============================================================================
-** Main function.
-*/
-
-int
-main (int argc, char *argv [])
-{
- if (argc < 2)
- { printf ("Usage : %s <input sound file>\n\n", argv [0]) ;
- return 1 ;
- } ;
-
- beos_play (argc, argv) ;
-
- 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: 5407a79d-88de-41c7-8d8e-9acf2cf13cc1
-*/
-
+++ /dev/null
-/*
-** 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 "sfconfig.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#if HAVE_ALSA_ASOUNDLIB_H
- #define ALSA_PCM_NEW_HW_PARAMS_API
- #define ALSA_PCM_NEW_SW_PARAMS_API
- #include <alsa/asoundlib.h>
- #include <sys/time.h>
-#endif
-
-#if defined (__linux__)
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #include <sys/soundcard.h>
-
-#elif (defined (__MACH__) && defined (__APPLE__))
- #include <Carbon.h>
- #include <CoreAudio/AudioHardware.h>
-
-#elif (defined (sun) && defined (unix))
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #include <sys/audioio.h>
-
-#elif (OS_IS_WIN32 == 1)
- #include <windows.h>
- #include <mmsystem.h>
-
-#endif
-
-#include <sndfile.h>
-
-#define SIGNED_SIZEOF(x) ((int) sizeof (x))
-#define BUFFER_LEN (2048)
-
-/*------------------------------------------------------------------------------
-** Linux/OSS functions for playing a sound.
-*/
-
-#if HAVE_ALSA_ASOUNDLIB_H
-
-static snd_pcm_t * alsa_open (int channels, unsigned srate, int realtime) ;
-static int alsa_write_float (snd_pcm_t *alsa_dev, float *data, int frames, int channels) ;
-
-static void
-alsa_play (int argc, char *argv [])
-{ static float buffer [BUFFER_LEN] ;
- SNDFILE *sndfile ;
- SF_INFO sfinfo ;
- snd_pcm_t * alsa_dev ;
- int k, readcount, subformat ;
-
- for (k = 1 ; k < argc ; k++)
- { memset (&sfinfo, 0, sizeof (sfinfo)) ;
-
- printf ("Playing %s\n", argv [k]) ;
- if (! (sndfile = sf_open (argv [k], SFM_READ, &sfinfo)))
- { puts (sf_strerror (NULL)) ;
- continue ;
- } ;
-
- if (sfinfo.channels < 1 || sfinfo.channels > 2)
- { printf ("Error : channels = %d.\n", sfinfo.channels) ;
- continue ;
- } ;
-
- if ((alsa_dev = alsa_open (sfinfo.channels, (unsigned) sfinfo.samplerate, SF_FALSE)) == NULL)
- continue ;
-
- subformat = sfinfo.format & SF_FORMAT_SUBMASK ;
-
- if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
- { double scale ;
- int m ;
-
- sf_command (sndfile, SFC_CALC_SIGNAL_MAX, &scale, sizeof (scale)) ;
- if (scale < 1e-10)
- scale = 1.0 ;
- else
- scale = 32700.0 / scale ;
-
- while ((readcount = sf_read_float (sndfile, buffer, BUFFER_LEN)))
- { for (m = 0 ; m < readcount ; m++)
- buffer [m] *= scale ;
- alsa_write_float (alsa_dev, buffer, BUFFER_LEN / sfinfo.channels, sfinfo.channels) ;
- } ;
- }
- else
- { while ((readcount = sf_read_float (sndfile, buffer, BUFFER_LEN)))
- alsa_write_float (alsa_dev, buffer, BUFFER_LEN / sfinfo.channels, sfinfo.channels) ;
- } ;
-
- snd_pcm_drain (alsa_dev) ;
- snd_pcm_close (alsa_dev) ;
-
- sf_close (sndfile) ;
- } ;
-
- return ;
-} /* alsa_play */
-
-static snd_pcm_t *
-alsa_open (int channels, unsigned samplerate, int realtime)
-{ const char * device = "plughw:0" ;
- snd_pcm_t *alsa_dev = NULL ;
- snd_pcm_hw_params_t *hw_params ;
- snd_pcm_uframes_t buffer_size, xfer_align, start_threshold ;
- snd_pcm_uframes_t alsa_period_size, alsa_buffer_frames ;
- snd_pcm_sw_params_t *sw_params ;
-
- int err ;
-
- if (realtime)
- { alsa_period_size = 256 ;
- alsa_buffer_frames = 3 * alsa_period_size ;
- }
- else
- { alsa_period_size = 1024 ;
- alsa_buffer_frames = 4 * alsa_period_size ;
- } ;
-
- if ((err = snd_pcm_open (&alsa_dev, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
- { fprintf (stderr, "cannot open audio device \"%s\" (%s)\n", device, snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- snd_pcm_nonblock (alsa_dev, 0) ;
-
- if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0)
- { fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- if ((err = snd_pcm_hw_params_any (alsa_dev, hw_params)) < 0)
- { fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- if ((err = snd_pcm_hw_params_set_access (alsa_dev, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
- { fprintf (stderr, "cannot set access type (%s)\n", snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- if ((err = snd_pcm_hw_params_set_format (alsa_dev, hw_params, SND_PCM_FORMAT_FLOAT)) < 0)
- { fprintf (stderr, "cannot set sample format (%s)\n", snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- if ((err = snd_pcm_hw_params_set_rate_near (alsa_dev, hw_params, &samplerate, 0)) < 0)
- { fprintf (stderr, "cannot set sample rate (%s)\n", snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- if ((err = snd_pcm_hw_params_set_channels (alsa_dev, hw_params, channels)) < 0)
- { fprintf (stderr, "cannot set channel count (%s)\n", snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- if ((err = snd_pcm_hw_params_set_buffer_size_near (alsa_dev, hw_params, &alsa_buffer_frames)) < 0)
- { fprintf (stderr, "cannot set buffer size (%s)\n", snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- if ((err = snd_pcm_hw_params_set_period_size_near (alsa_dev, hw_params, &alsa_period_size, 0)) < 0)
- { fprintf (stderr, "cannot set period size (%s)\n", snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- if ((err = snd_pcm_hw_params (alsa_dev, hw_params)) < 0)
- { fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- /* extra check: if we have only one period, this code won't work */
- snd_pcm_hw_params_get_period_size (hw_params, &alsa_period_size, 0) ;
- snd_pcm_hw_params_get_buffer_size (hw_params, &buffer_size) ;
- if (alsa_period_size == buffer_size)
- { fprintf (stderr, "Can't use period equal to buffer size (%lu == %lu)", alsa_period_size, buffer_size) ;
- goto catch_error ;
- } ;
-
- snd_pcm_hw_params_free (hw_params) ;
-
- if ((err = snd_pcm_sw_params_malloc (&sw_params)) != 0)
- { fprintf (stderr, "%s: snd_pcm_sw_params_malloc: %s", __func__, snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- if ((err = snd_pcm_sw_params_current (alsa_dev, sw_params)) != 0)
- { fprintf (stderr, "%s: snd_pcm_sw_params_current: %s", __func__, snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- /* note: set start threshold to delay start until the ring buffer is full */
- snd_pcm_sw_params_current (alsa_dev, sw_params) ;
- if ((err = snd_pcm_sw_params_get_xfer_align (sw_params, &xfer_align)) < 0)
- { fprintf (stderr, "cannot get xfer align (%s)\n", snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- /* round up to closest transfer boundary */
- start_threshold = (buffer_size / xfer_align) * xfer_align ;
- if (start_threshold < 1)
- start_threshold = 1 ;
- if ((err = snd_pcm_sw_params_set_start_threshold (alsa_dev, sw_params, start_threshold)) < 0)
- { fprintf (stderr, "cannot set start threshold (%s)\n", snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- if ((err = snd_pcm_sw_params (alsa_dev, sw_params)) != 0)
- { fprintf (stderr, "%s: snd_pcm_sw_params: %s", __func__, snd_strerror (err)) ;
- goto catch_error ;
- } ;
-
- snd_pcm_sw_params_free (sw_params) ;
-
- snd_pcm_reset (alsa_dev) ;
-
-catch_error :
-
- if (err < 0 && alsa_dev != NULL)
- { snd_pcm_close (alsa_dev) ;
- return NULL ;
- } ;
-
- return alsa_dev ;
-} /* alsa_open */
-
-static int
-alsa_write_float (snd_pcm_t *alsa_dev, float *data, int frames, int channels)
-{ static int epipe_count = 0 ;
-
- snd_pcm_status_t *status ;
- int total = 0 ;
- int retval ;
-
- if (epipe_count > 0)
- epipe_count -- ;
-
- while (total < frames)
- { retval = snd_pcm_writei (alsa_dev, data + total * channels, frames - total) ;
-
- if (retval >= 0)
- { total += retval ;
- if (total == frames)
- return total ;
-
- continue ;
- } ;
-
- switch (retval)
- { case -EAGAIN :
- puts ("alsa_write_float: EAGAIN") ;
- continue ;
- break ;
-
- case -EPIPE :
- if (epipe_count > 0)
- { printf ("alsa_write_float: EPIPE %d\n", epipe_count) ;
- if (epipe_count > 140)
- return retval ;
- } ;
- epipe_count += 100 ;
-
- if (0)
- { snd_pcm_status_alloca (&status) ;
- if ((retval = snd_pcm_status (alsa_dev, status)) < 0)
- fprintf (stderr, "alsa_out: xrun. can't determine length\n") ;
- else if (snd_pcm_status_get_state (status) == SND_PCM_STATE_XRUN)
- { struct timeval now, diff, tstamp ;
-
- gettimeofday (&now, 0) ;
- snd_pcm_status_get_trigger_tstamp (status, &tstamp) ;
- timersub (&now, &tstamp, &diff) ;
-
- fprintf (stderr, "alsa_write_float xrun: of at least %.3f msecs. resetting stream\n",
- diff.tv_sec * 1000 + diff.tv_usec / 1000.0) ;
- }
- else
- fprintf (stderr, "alsa_write_float: xrun. can't determine length\n") ;
- } ;
-
- snd_pcm_prepare (alsa_dev) ;
- break ;
-
- case -EBADFD :
- fprintf (stderr, "alsa_write_float: Bad PCM state.n") ;
- return 0 ;
- break ;
-
- case -ESTRPIPE :
- fprintf (stderr, "alsa_write_float: Suspend event.n") ;
- return 0 ;
- break ;
-
- case -EIO :
- puts ("alsa_write_float: EIO") ;
- return 0 ;
-
- default :
- fprintf (stderr, "alsa_write_float: retval = %d\n", retval) ;
- return 0 ;
- break ;
- } ; /* switch */
- } ; /* while */
-
- return total ;
-} /* alsa_write_float */
-
-#endif /* HAVE_ALSA_ASOUNDLIB_H */
-
-/*------------------------------------------------------------------------------
-** Linux/OSS functions for playing a sound.
-*/
-
-#if defined (__linux__)
-
-static int linux_open_dsp_device (int channels, int srate) ;
-
-static void
-linux_play (int argc, char *argv [])
-{ static short buffer [BUFFER_LEN] ;
- SNDFILE *sndfile ;
- SF_INFO sfinfo ;
- int k, audio_device, readcount, subformat ;
-
- for (k = 1 ; k < argc ; k++)
- { memset (&sfinfo, 0, sizeof (sfinfo)) ;
-
- printf ("Playing %s\n", argv [k]) ;
- if (! (sndfile = sf_open (argv [k], SFM_READ, &sfinfo)))
- { puts (sf_strerror (NULL)) ;
- continue ;
- } ;
-
- if (sfinfo.channels < 1 || sfinfo.channels > 2)
- { printf ("Error : channels = %d.\n", sfinfo.channels) ;
- continue ;
- } ;
-
- audio_device = linux_open_dsp_device (sfinfo.channels, sfinfo.samplerate) ;
-
- subformat = sfinfo.format & SF_FORMAT_SUBMASK ;
-
- if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
- { static float float_buffer [BUFFER_LEN] ;
- double scale ;
- int m ;
-
- sf_command (sndfile, SFC_CALC_SIGNAL_MAX, &scale, sizeof (scale)) ;
- if (scale < 1e-10)
- scale = 1.0 ;
- else
- scale = 32700.0 / scale ;
-
- while ((readcount = sf_read_float (sndfile, float_buffer, BUFFER_LEN)))
- { for (m = 0 ; m < readcount ; m++)
- buffer [m] = scale * float_buffer [m] ;
- write (audio_device, buffer, readcount * sizeof (short)) ;
- } ;
- }
- else
- { while ((readcount = sf_read_short (sndfile, buffer, BUFFER_LEN)))
- write (audio_device, buffer, readcount * sizeof (short)) ;
- } ;
-
- if (ioctl (audio_device, SNDCTL_DSP_POST, 0) == -1)
- perror ("ioctl (SNDCTL_DSP_POST) ") ;
-
- if (ioctl (audio_device, SNDCTL_DSP_SYNC, 0) == -1)
- perror ("ioctl (SNDCTL_DSP_SYNC) ") ;
-
- close (audio_device) ;
-
- sf_close (sndfile) ;
- } ;
-
- return ;
-} /* linux_play */
-
-static int
-linux_open_dsp_device (int channels, int srate)
-{ int fd, stereo, fmt ;
-
- if ((fd = open ("/dev/dsp", O_WRONLY, 0)) == -1 &&
- (fd = open ("/dev/sound/dsp", O_WRONLY, 0)) == -1)
- { perror ("linux_open_dsp_device : open ") ;
- exit (1) ;
- } ;
-
- stereo = 0 ;
- if (ioctl (fd, SNDCTL_DSP_STEREO, &stereo) == -1)
- { /* Fatal error */
- perror ("linux_open_dsp_device : stereo ") ;
- exit (1) ;
- } ;
-
- if (ioctl (fd, SNDCTL_DSP_RESET, 0))
- { perror ("linux_open_dsp_device : reset ") ;
- exit (1) ;
- } ;
-
- fmt = CPU_IS_BIG_ENDIAN ? AFMT_S16_BE : AFMT_S16_LE ;
- if (ioctl (fd, SOUND_PCM_SETFMT, &fmt) != 0)
- { perror ("linux_open_dsp_device : set format ") ;
- exit (1) ;
- } ;
-
- if (ioctl (fd, SOUND_PCM_WRITE_CHANNELS, &channels) != 0)
- { perror ("linux_open_dsp_device : channels ") ;
- exit (1) ;
- } ;
-
- if (ioctl (fd, SOUND_PCM_WRITE_RATE, &srate) != 0)
- { perror ("linux_open_dsp_device : sample rate ") ;
- exit (1) ;
- } ;
-
- if (ioctl (fd, SNDCTL_DSP_SYNC, 0) != 0)
- { perror ("linux_open_dsp_device : sync ") ;
- exit (1) ;
- } ;
-
- return fd ;
-} /* linux_open_dsp_device */
-
-#endif /* __linux__ */
-
-/*------------------------------------------------------------------------------
-** Mac OS X functions for playing a sound.
-*/
-
-#if (defined (__MACH__) && defined (__APPLE__)) /* MacOSX */
-
-typedef struct
-{ AudioStreamBasicDescription format ;
-
- UInt32 buf_size ;
- AudioDeviceID device ;
-
- SNDFILE *sndfile ;
- SF_INFO sfinfo ;
-
- int fake_stereo ;
- int done_playing ;
-} MacOSXAudioData ;
-
-#include <math.h>
-
-static OSStatus
-macosx_audio_out_callback (AudioDeviceID device, const AudioTimeStamp* current_time,
- const AudioBufferList* data_in, const AudioTimeStamp* time_in,
- AudioBufferList* data_out, const AudioTimeStamp* time_out,
- void* client_data)
-{ MacOSXAudioData *audio_data ;
- int size, sample_count, read_count, k ;
- float *buffer ;
-
- /* Prevent compiler warnings. */
- device = device ;
- current_time = current_time ;
- data_in = data_in ;
- time_in = time_in ;
- time_out = time_out ;
-
- audio_data = (MacOSXAudioData*) client_data ;
-
- size = data_out->mBuffers [0].mDataByteSize ;
- sample_count = size / sizeof (float) ;
-
- buffer = (float*) data_out->mBuffers [0].mData ;
-
- if (audio_data->fake_stereo != 0)
- { read_count = sf_read_float (audio_data->sndfile, buffer, sample_count / 2) ;
-
- for (k = read_count - 1 ; k >= 0 ; k--)
- { buffer [2 * k ] = buffer [k] ;
- buffer [2 * k + 1] = buffer [k] ;
- } ;
- read_count *= 2 ;
- }
- else
- read_count = sf_read_float (audio_data->sndfile, buffer, sample_count) ;
-
- /* Fill the remainder with zeroes. */
- if (read_count < sample_count)
- { if (audio_data->fake_stereo == 0)
- memset (&(buffer [read_count]), 0, (sample_count - read_count) * sizeof (float)) ;
- /* Tell the main application to terminate. */
- audio_data->done_playing = SF_TRUE ;
- } ;
-
- return noErr ;
-} /* macosx_audio_out_callback */
-
-static void
-macosx_play (int argc, char *argv [])
-{ MacOSXAudioData audio_data ;
- OSStatus err ;
- UInt32 count, buffer_size ;
- int k ;
-
- audio_data.fake_stereo = 0 ;
- audio_data.device = kAudioDeviceUnknown ;
-
- /* get the default output device for the HAL */
- count = sizeof (AudioDeviceID) ;
- if ((err = AudioHardwareGetProperty (kAudioHardwarePropertyDefaultOutputDevice,
- &count, (void *) &(audio_data.device))) != noErr)
- { printf ("AudioHardwareGetProperty (kAudioDevicePropertyDefaultOutputDevice) failed.\n") ;
- return ;
- } ;
-
- /* get the buffersize that the default device uses for IO */
- count = sizeof (UInt32) ;
- if ((err = AudioDeviceGetProperty (audio_data.device, 0, false, kAudioDevicePropertyBufferSize,
- &count, &buffer_size)) != noErr)
- { printf ("AudioDeviceGetProperty (kAudioDevicePropertyBufferSize) failed.\n") ;
- return ;
- } ;
-
- /* get a description of the data format used by the default device */
- count = sizeof (AudioStreamBasicDescription) ;
- if ((err = AudioDeviceGetProperty (audio_data.device, 0, false, kAudioDevicePropertyStreamFormat,
- &count, &(audio_data.format))) != noErr)
- { printf ("AudioDeviceGetProperty (kAudioDevicePropertyStreamFormat) failed.\n") ;
- return ;
- } ;
-
- /* Base setup completed. Now play files. */
- for (k = 1 ; k < argc ; k++)
- { printf ("Playing %s\n", argv [k]) ;
- if (! (audio_data.sndfile = sf_open (argv [k], SFM_READ, &(audio_data.sfinfo))))
- { puts (sf_strerror (NULL)) ;
- continue ;
- } ;
-
- if (audio_data.sfinfo.channels < 1 || audio_data.sfinfo.channels > 2)
- { printf ("Error : channels = %d.\n", audio_data.sfinfo.channels) ;
- continue ;
- } ;
-
- audio_data.format.mSampleRate = audio_data.sfinfo.samplerate ;
-
- if (audio_data.sfinfo.channels == 1)
- { audio_data.format.mChannelsPerFrame = 2 ;
- audio_data.fake_stereo = 1 ;
- }
- else
- audio_data.format.mChannelsPerFrame = audio_data.sfinfo.channels ;
-
- if ((err = AudioDeviceSetProperty (audio_data.device, NULL, 0, false, kAudioDevicePropertyStreamFormat,
- sizeof (AudioStreamBasicDescription), &(audio_data.format))) != noErr)
- { printf ("AudioDeviceSetProperty (kAudioDevicePropertyStreamFormat) failed.\n") ;
- return ;
- } ;
-
- /* we want linear pcm */
- if (audio_data.format.mFormatID != kAudioFormatLinearPCM)
- return ;
-
- /* Fire off the device. */
- if ((err = AudioDeviceAddIOProc (audio_data.device, macosx_audio_out_callback,
- (void *) &audio_data)) != noErr)
- { printf ("AudioDeviceAddIOProc failed.\n") ;
- return ;
- } ;
-
- err = AudioDeviceStart (audio_data.device, macosx_audio_out_callback) ;
- if (err != noErr)
- return ;
-
- audio_data.done_playing = SF_FALSE ;
-
- while (audio_data.done_playing == SF_FALSE)
- usleep (10 * 1000) ; /* 10 000 milliseconds. */
-
- if ((err = AudioDeviceStop (audio_data.device, macosx_audio_out_callback)) != noErr)
- { printf ("AudioDeviceStop failed.\n") ;
- return ;
- } ;
-
- err = AudioDeviceRemoveIOProc (audio_data.device, macosx_audio_out_callback) ;
- if (err != noErr)
- { printf ("AudioDeviceRemoveIOProc failed.\n") ;
- return ;
- } ;
-
- sf_close (audio_data.sndfile) ;
- } ;
-
- return ;
-} /* macosx_play */
-
-#endif /* MacOSX */
-
-
-/*------------------------------------------------------------------------------
-** Win32 functions for playing a sound.
-**
-** This API sucks. Its needlessly complicated and is *WAY* too loose with
-** passing pointers arounf in integers and and using char* pointers to
-** point to data instead of short*. It plain sucks!
-*/
-
-#if (OS_IS_WIN32 == 1)
-
-#define WIN32_BUFFER_LEN (1<<15)
-
-typedef struct
-{ HWAVEOUT hwave ;
- WAVEHDR whdr [2] ;
-
- CRITICAL_SECTION mutex ; /* to control access to BuffersInUSe */
- HANDLE Event ; /* signal that a buffer is free */
-
- short buffer [WIN32_BUFFER_LEN / sizeof (short)] ;
- int current, bufferlen ;
- int BuffersInUse ;
-
- SNDFILE *sndfile ;
- SF_INFO sfinfo ;
-
- sf_count_t remaining ;
-} Win32_Audio_Data ;
-
-
-static void
-win32_play_data (Win32_Audio_Data *audio_data)
-{ int thisread, readcount ;
-
- /* fill a buffer if there is more data and we can read it sucessfully */
- readcount = (audio_data->remaining > audio_data->bufferlen) ? audio_data->bufferlen : (int) audio_data->remaining ;
-
- thisread = (int) sf_read_short (audio_data->sndfile, (short *) (audio_data->whdr [audio_data->current].lpData), readcount) ;
-
- audio_data->remaining -= thisread ;
-
- if (thisread > 0)
- { /* Fix buffer length if this is only a partial block. */
- if (thisread < audio_data->bufferlen)
- audio_data->whdr [audio_data->current].dwBufferLength = thisread * sizeof (short) ;
-
- /* Queue the WAVEHDR */
- waveOutWrite (audio_data->hwave, (LPWAVEHDR) &(audio_data->whdr [audio_data->current]), sizeof (WAVEHDR)) ;
-
- /* count another buffer in use */
- EnterCriticalSection (&audio_data->mutex) ;
- audio_data->BuffersInUse ++ ;
- LeaveCriticalSection (&audio_data->mutex) ;
-
- /* use the other buffer next time */
- audio_data->current = (audio_data->current + 1) % 2 ;
- } ;
-
- return ;
-} /* win32_play_data */
-
-static void CALLBACK
-win32_audio_out_callback (HWAVEOUT hwave, UINT msg, DWORD data, DWORD param1, DWORD param2)
-{ Win32_Audio_Data *audio_data ;
-
- /* Prevent compiler warnings. */
- hwave = hwave ;
- param1 = param2 ;
-
- if (data == 0)
- return ;
-
- /*
- ** I consider this technique of passing a pointer via an integer as
- ** fundamentally broken but thats the way microsoft has defined the
- ** interface.
- */
- audio_data = (Win32_Audio_Data*) data ;
-
- /* let main loop know a buffer is free */
- if (msg == MM_WOM_DONE)
- { EnterCriticalSection (&audio_data->mutex) ;
- audio_data->BuffersInUse -- ;
- LeaveCriticalSection (&audio_data->mutex) ;
- SetEvent (audio_data->Event) ;
- } ;
-
- return ;
-} /* win32_audio_out_callback */
-
-/* This is needed for earlier versions of the M$ development tools. */
-#ifndef DWORD_PTR
-#define DWORD_PTR DWORD
-#endif
-
-static void
-win32_play (int argc, char *argv [])
-{ Win32_Audio_Data audio_data ;
-
- WAVEFORMATEX wf ;
- int k, error ;
-
- audio_data.sndfile = NULL ;
- audio_data.hwave = 0 ;
-
- for (k = 1 ; k < argc ; k++)
- { printf ("Playing %s\n", argv [k]) ;
-
- if (! (audio_data.sndfile = sf_open (argv [k], SFM_READ, &(audio_data.sfinfo))))
- { puts (sf_strerror (NULL)) ;
- continue ;
- } ;
-
- audio_data.remaining = audio_data.sfinfo.frames * audio_data.sfinfo.channels ;
- audio_data.current = 0 ;
-
- InitializeCriticalSection (&audio_data.mutex) ;
- audio_data.Event = CreateEvent (0, FALSE, FALSE, 0) ;
-
- wf.nChannels = audio_data.sfinfo.channels ;
- wf.wFormatTag = WAVE_FORMAT_PCM ;
- wf.cbSize = 0 ;
- wf.wBitsPerSample = 16 ;
-
- wf.nSamplesPerSec = audio_data.sfinfo.samplerate ;
-
- wf.nBlockAlign = audio_data.sfinfo.channels * sizeof (short) ;
-
- wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec ;
-
- error = waveOutOpen (&(audio_data.hwave), WAVE_MAPPER, &wf, (DWORD_PTR) win32_audio_out_callback,
- (DWORD_PTR) &audio_data, CALLBACK_FUNCTION) ;
- if (error)
- { puts ("waveOutOpen failed.") ;
- audio_data.hwave = 0 ;
- continue ;
- } ;
-
- audio_data.whdr [0].lpData = (char*) audio_data.buffer ;
- audio_data.whdr [1].lpData = ((char*) audio_data.buffer) + sizeof (audio_data.buffer) / 2 ;
-
- audio_data.whdr [0].dwBufferLength = sizeof (audio_data.buffer) / 2 ;
- audio_data.whdr [1].dwBufferLength = sizeof (audio_data.buffer) / 2 ;
-
- audio_data.whdr [0].dwFlags = 0 ;
- audio_data.whdr [1].dwFlags = 0 ;
-
- /* length of each audio buffer in samples */
- audio_data.bufferlen = sizeof (audio_data.buffer) / 2 / sizeof (short) ;
-
- /* Prepare the WAVEHDRs */
- if ((error = waveOutPrepareHeader (audio_data.hwave, &(audio_data.whdr [0]), sizeof (WAVEHDR))))
- { printf ("waveOutPrepareHeader [0] failed : %08X\n", error) ;
- waveOutClose (audio_data.hwave) ;
- continue ;
- } ;
-
- if ((error = waveOutPrepareHeader (audio_data.hwave, &(audio_data.whdr [1]), sizeof (WAVEHDR))))
- { printf ("waveOutPrepareHeader [1] failed : %08X\n", error) ;
- waveOutUnprepareHeader (audio_data.hwave, &(audio_data.whdr [0]), sizeof (WAVEHDR)) ;
- waveOutClose (audio_data.hwave) ;
- continue ;
- } ;
-
- /* Fill up both buffers with audio data */
- audio_data.BuffersInUse = 0 ;
- win32_play_data (&audio_data) ;
- win32_play_data (&audio_data) ;
-
- /* loop until both buffers are released */
- while (audio_data.BuffersInUse > 0)
- {
- /* wait for buffer to be released */
- WaitForSingleObject (audio_data.Event, INFINITE) ;
-
- /* refill the buffer if there is more data to play */
- win32_play_data (&audio_data) ;
- } ;
-
- waveOutUnprepareHeader (audio_data.hwave, &(audio_data.whdr [0]), sizeof (WAVEHDR)) ;
- waveOutUnprepareHeader (audio_data.hwave, &(audio_data.whdr [1]), sizeof (WAVEHDR)) ;
-
- waveOutClose (audio_data.hwave) ;
- audio_data.hwave = 0 ;
-
- DeleteCriticalSection (&audio_data.mutex) ;
-
- sf_close (audio_data.sndfile) ;
- } ;
-
-} /* win32_play */
-
-#endif /* Win32 */
-
-/*------------------------------------------------------------------------------
-** Solaris.
-*/
-
-#if (defined (sun) && defined (unix)) /* ie Solaris */
-
-static void
-solaris_play (int argc, char *argv [])
-{ static short buffer [BUFFER_LEN] ;
- audio_info_t audio_info ;
- SNDFILE *sndfile ;
- SF_INFO sfinfo ;
- unsigned long delay_time ;
- long k, start_count, output_count, write_count, read_count ;
- int audio_fd, error, done ;
-
- for (k = 1 ; k < argc ; k++)
- { printf ("Playing %s\n", argv [k]) ;
- if (! (sndfile = sf_open (argv [k], SFM_READ, &sfinfo)))
- { puts (sf_strerror (NULL)) ;
- continue ;
- } ;
-
- if (sfinfo.channels < 1 || sfinfo.channels > 2)
- { printf ("Error : channels = %d.\n", sfinfo.channels) ;
- continue ;
- } ;
-
- /* open the audio device - write only, non-blocking */
- if ((audio_fd = open ("/dev/audio", O_WRONLY | O_NONBLOCK)) < 0)
- { perror ("open (/dev/audio) failed") ;
- return ;
- } ;
-
- /* Retrive standard values. */
- AUDIO_INITINFO (&audio_info) ;
-
- audio_info.play.sample_rate = sfinfo.samplerate ;
- audio_info.play.channels = sfinfo.channels ;
- audio_info.play.precision = 16 ;
- audio_info.play.encoding = AUDIO_ENCODING_LINEAR ;
- audio_info.play.gain = AUDIO_MAX_GAIN ;
- audio_info.play.balance = AUDIO_MID_BALANCE ;
-
- if ((error = ioctl (audio_fd, AUDIO_SETINFO, &audio_info)))
- { perror ("ioctl (AUDIO_SETINFO) failed") ;
- return ;
- } ;
-
- /* Delay time equal to 1/4 of a buffer in microseconds. */
- delay_time = (BUFFER_LEN * 1000000) / (audio_info.play.sample_rate * 4) ;
-
- done = 0 ;
- while (! done)
- { read_count = sf_read_short (sndfile, buffer, BUFFER_LEN) ;
- if (read_count < BUFFER_LEN)
- { memset (&(buffer [read_count]), 0, (BUFFER_LEN - read_count) * sizeof (short)) ;
- /* Tell the main application to terminate. */
- done = SF_TRUE ;
- } ;
-
- start_count = 0 ;
- output_count = BUFFER_LEN * sizeof (short) ;
-
- while (output_count > 0)
- { /* write as much data as possible */
- write_count = write (audio_fd, &(buffer [start_count]), output_count) ;
- if (write_count > 0)
- { output_count -= write_count ;
- start_count += write_count ;
- }
- else
- { /* Give the audio output time to catch up. */
- usleep (delay_time) ;
- } ;
- } ; /* while (outpur_count > 0) */
- } ; /* while (! done) */
-
- close (audio_fd) ;
- } ;
-
- return ;
-} /* solaris_play */
-
-#endif /* Solaris */
-
-/*==============================================================================
-** Main function.
-*/
-
-int
-main (int argc, char *argv [])
-{
- if (argc < 2)
- {
- printf ("\nUsage : %s <input sound file>\n\n", argv [0]) ;
-#if (OS_IS_WIN32 == 1)
- printf ("This is a Unix style command line application which\n"
- "should be run in a MSDOS box or Command Shell window.\n\n") ;
- printf ("Sleeping for 5 seconds before exiting.\n\n") ;
-
- /* This is the officially blessed by microsoft way but I can't get
- ** it to link.
- ** Sleep (15) ;
- ** Instead, use this:
- */
- _sleep (5 * 1000) ;
-#endif
- return 1 ;
- } ;
-
-#if defined (__linux__)
- #if HAVE_ALSA_ASOUNDLIB_H
- if (access ("/proc/asound/cards", R_OK) == 0)
- alsa_play (argc, argv) ;
- else
- #endif
- linux_play (argc, argv) ;
-#elif (defined (__MACH__) && defined (__APPLE__))
- macosx_play (argc, argv) ;
-#elif (defined (sun) && defined (unix))
- solaris_play (argc, argv) ;
-#elif (OS_IS_WIN32 == 1)
- win32_play (argc, argv) ;
-#elif defined (__BEOS__)
- printf ("This program cannot be compiled on BeOS.\n") ;
- printf ("Instead, compile the file sfplay_beos.cpp.\n") ;
- return 1 ;
-#else
- puts ("*** Playing sound not yet supported on this platform.") ;
- puts ("*** Please feel free to submit a patch.") ;
- return 1 ;
-#endif
-
- 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: 8fc4110d-6cec-4e03-91df-0f384cabedac
-*/
/*
-** Copyright (C) 2008-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2008-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** All rights reserved.
**
/*
-** Copyright (C) 2007 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2007-2011 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
## Process this file with automake to produce Makefile.in
-man_MANS = sndfile-info.1 sndfile-play.1 sndfile-convert.1
+man_MANS = sndfile-info.1 sndfile-play.1 sndfile-convert.1 sndfile-cmp.1 \
+ sndfile-metadata-get.1 sndfile-metadata-set.1 sndfile-concat.1 \
+ sndfile-interleave.1 sndfile-deinterleave.1
-EXTRA_DIST = sndfile-info.1 sndfile-play.1 sndfile-convert.1
+EXTRA_DIST = sndfile-info.1 sndfile-play.1 sndfile-convert.1 sndfile-cmp.1 \
+ sndfile-metadata-get.1 sndfile-concat.1 sndfile-interleave.1
+# Same manpage for both programs.
+sndfile-metadata-set.1 : sndfile-metadata-get.1
+ $(LN_S) $(srcdir)/sndfile-metadata-get.1 $@
+
+sndfile-deinterleave.1 : sndfile-interleave.1
+ $(LN_S) $(srcdir)/sndfile-interleave.1 $@
of the output file.
.LP
The optional encoding parameter allows setting of the data encoding for
-the output file. Run "sndfile-convert --help" for more information.
+the output file. Run "sndfile\-convert \-\-help" for more information.
.SH AUTHOR
This manual page was written by Erik de Castro Lopo <erikd@mega-nerd.com>.
## Process this file with automake to produce Makefile.in
-bin_PROGRAMS = sndfile-info sndfile-play sndfile-convert sndfile-jackplay sndfile-cmp \
- sndfile-metadata-set sndfile-metadata-get
+bin_PROGRAMS = sndfile-info sndfile-play sndfile-convert sndfile-cmp \
+ sndfile-metadata-set sndfile-metadata-get sndfile-interleave \
+ sndfile-deinterleave sndfile-concat sndfile-salvage
OS_SPECIFIC_CFLAGS = @OS_SPECIFIC_CFLAGS@
OS_SPECIFIC_LINKS = @OS_SPECIFIC_LINKS@
INCLUDES = -I$(top_srcdir)/src $(OS_SPECIFIC_CFLAGS)
+CLEANFILES = *~
+
# This is the BeOS version of sndfile-play. It needs to be compiled with the C++
# compiler.
EXTRA_DIST = sndfile-play-beos.cpp test-sndfile-metadata-set.py
-sndfile_info_SOURCES = sndfile-info.c
+sndfile_info_SOURCES = sndfile-info.c common.c common.h
sndfile_info_LDADD = $(top_builddir)/src/libsndfile.la
-sndfile_play_SOURCES = sndfile-play.c
-sndfile_play_LDADD = $(top_builddir)/src/libsndfile.la $(OS_SPECIFIC_LINKS) $(ALSA_LIBS)
-
-sndfile_jackplay_SOURCES = sndfile-jackplay.c
-sndfile_jackplay_CFLAGS = $(JACK_CFLAGS)
-sndfile_jackplay_LDADD = $(top_builddir)/src/libsndfile.la $(JACK_LIBS)
+sndfile_play_SOURCES = sndfile-play.c common.c common.h
+sndfile_play_LDADD = $(top_builddir)/src/libsndfile.la $(OS_SPECIFIC_LINKS) $(ALSA_LIBS) $(SNDIO_LIBS)
sndfile_convert_SOURCES = sndfile-convert.c common.c common.h
sndfile_convert_LDADD = $(top_builddir)/src/libsndfile.la
-sndfile_cmp_SOURCES = sndfile-cmp.c
+sndfile_cmp_SOURCES = sndfile-cmp.c common.c common.h
sndfile_cmp_LDADD = $(top_builddir)/src/libsndfile.la
sndfile_metadata_set_SOURCES = sndfile-metadata-set.c common.c common.h
sndfile_metadata_set_LDADD = $(top_builddir)/src/libsndfile.la
-sndfile_metadata_get_SOURCES = sndfile-metadata-get.c
+sndfile_metadata_get_SOURCES = sndfile-metadata-get.c common.c common.h
sndfile_metadata_get_LDADD = $(top_builddir)/src/libsndfile.la
+sndfile_interleave_SOURCES = sndfile-interleave.c common.c common.h
+sndfile_interleave_LDADD = $(top_builddir)/src/libsndfile.la
+
+sndfile_deinterleave_SOURCES = sndfile-deinterleave.c common.c common.h
+sndfile_deinterleave_LDADD = $(top_builddir)/src/libsndfile.la
+
+sndfile_concat_SOURCES = sndfile-concat.c common.c common.h
+sndfile_concat_LDADD = $(top_builddir)/src/libsndfile.la
+
+sndfile_salvage_SOURCES = sndfile-salvage.c common.c common.h
+sndfile_salvage_LDADD = $(top_builddir)/src/libsndfile.la
+
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2008 George Blood Audio
**
** All rights reserved.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <stdint.h>
#include <sndfile.h>
REPLACE_IF_NEW (origination_time) ;
REPLACE_IF_NEW (umid) ;
+ /* Special case for Time Ref. */
+ if (info->time_ref != NULL)
+ { uint64_t ts = atoll (info->time_ref) ;
+
+ binfo.time_reference_high = (ts >> 32) ;
+ binfo.time_reference_low = (ts & 0xffffffff) ;
+ } ;
+
/* Special case for coding_history because we may want to append. */
if (info->coding_history != NULL)
{ if (info->coding_hist_append)
sf_set_string (outfile, SF_STR_TITLE, info->title) ;
if (info->copyright != NULL)
- sf_set_string (outfile, SF_STR_TITLE, info->copyright) ;
+ sf_set_string (outfile, SF_STR_COPYRIGHT, info->copyright) ;
if (info->artist != NULL)
sf_set_string (outfile, SF_STR_ARTIST, info->artist) ;
if (info->comment != NULL)
- sf_set_string (outfile, SF_STR_TITLE, info->comment) ;
+ sf_set_string (outfile, SF_STR_COMMENT, info->comment) ;
if (info->date != NULL)
sf_set_string (outfile, SF_STR_DATE, info->date) ;
if (info->album != NULL)
- sf_set_string (outfile, SF_STR_TITLE, info->album) ;
+ sf_set_string (outfile, SF_STR_ALBUM, info->album) ;
if (info->license != NULL)
- sf_set_string (outfile, SF_STR_TITLE, info->license) ;
+ sf_set_string (outfile, SF_STR_LICENSE, info->license) ;
} /* update_strings */
goto cleanup_exit ;
} ;
- update_strings (outfile, info) ;
-
if (infile != outfile)
{ int infileminor = SF_FORMAT_SUBMASK & sfinfo.format ;
sfe_copy_data_int (outfile, infile, sfinfo.channels) ;
} ;
+ update_strings (outfile, info) ;
+
cleanup_exit :
if (outfile != NULL && outfile != infile)
return ;
} /* sfe_apply_metadata_changes */
+/*==============================================================================
+*/
+
+typedef struct
+{ const char *ext ;
+ int len ;
+ int format ;
+} OUTPUT_FORMAT_MAP ;
+
+static OUTPUT_FORMAT_MAP format_map [] =
+{
+ { "aif", 3, SF_FORMAT_AIFF },
+ { "wav", 0, SF_FORMAT_WAV },
+ { "au", 0, SF_FORMAT_AU },
+ { "caf", 0, SF_FORMAT_CAF },
+ { "flac", 0, SF_FORMAT_FLAC },
+ { "snd", 0, SF_FORMAT_AU },
+ { "svx", 0, SF_FORMAT_SVX },
+ { "paf", 0, SF_ENDIAN_BIG | SF_FORMAT_PAF },
+ { "fap", 0, SF_ENDIAN_LITTLE | SF_FORMAT_PAF },
+ { "gsm", 0, SF_FORMAT_RAW },
+ { "nist", 0, SF_FORMAT_NIST },
+ { "htk", 0, SF_FORMAT_HTK },
+ { "ircam", 0, SF_FORMAT_IRCAM },
+ { "sf", 0, SF_FORMAT_IRCAM },
+ { "voc", 0, SF_FORMAT_VOC },
+ { "w64", 0, SF_FORMAT_W64 },
+ { "raw", 0, SF_FORMAT_RAW },
+ { "mat4", 0, SF_FORMAT_MAT4 },
+ { "mat5", 0, SF_FORMAT_MAT5 },
+ { "mat", 0, SF_FORMAT_MAT4 },
+ { "pvf", 0, SF_FORMAT_PVF },
+ { "sds", 0, SF_FORMAT_SDS },
+ { "sd2", 0, SF_FORMAT_SD2 },
+ { "vox", 0, SF_FORMAT_RAW },
+ { "xi", 0, SF_FORMAT_XI },
+ { "wve", 0, SF_FORMAT_WVE },
+ { "oga", 0, SF_FORMAT_OGG },
+ { "mpc", 0, SF_FORMAT_MPC2K },
+ { "rf64", 0, SF_FORMAT_RF64 },
+} ; /* format_map */
+
+int
+sfe_file_type_of_ext (const char *str, int format)
+{ char buffer [16], *cptr ;
+ int k ;
+
+ format &= SF_FORMAT_SUBMASK ;
+
+ if ((cptr = strrchr (str, '.')) == NULL)
+ return 0 ;
+
+ strncpy (buffer, cptr + 1, 15) ;
+ buffer [15] = 0 ;
+
+ for (k = 0 ; buffer [k] ; k++)
+ buffer [k] = tolower ((buffer [k])) ;
+
+ if (strcmp (buffer, "gsm") == 0)
+ return SF_FORMAT_RAW | SF_FORMAT_GSM610 ;
+
+ if (strcmp (buffer, "vox") == 0)
+ return SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM ;
+
+ for (k = 0 ; k < (int) (sizeof (format_map) / sizeof (format_map [0])) ; k++)
+ { if (format_map [k].len > 0 && strncmp (buffer, format_map [k].ext, format_map [k].len) == 0)
+ return format_map [k].format | format ;
+ else if (strcmp (buffer, format_map [k].ext) == 0)
+ return format_map [k].format | format ;
+ } ;
+
+ /* Default if all the above fails. */
+ return (SF_FORMAT_WAV | SF_FORMAT_PCM_24) ;
+} /* sfe_file_type_of_ext */
+
+void
+sfe_dump_format_map (void)
+{ SF_FORMAT_INFO info ;
+ int k ;
+
+ for (k = 0 ; k < ARRAY_LEN (format_map) ; k++)
+ { info.format = format_map [k].format ;
+ sf_command (NULL, SFC_GET_FORMAT_INFO, &info, sizeof (info)) ;
+ printf (" %-10s : %s\n", format_map [k].ext, info.name == NULL ? "????" : info.name) ;
+ } ;
+
+} /* sfe_dump_format_map */
+
+const char *
+program_name (const char * argv0)
+{ const char * tmp ;
+
+ tmp = strrchr (argv0, '/') ;
+ argv0 = tmp ? tmp + 1 : argv0 ;
+
+ tmp = strrchr (argv0, '/') ;
+ argv0 = tmp ? tmp + 1 : argv0 ;
+
+ /* Remove leading libtool name mangling. */
+ if (strstr (argv0, "lt-") == argv0)
+ return argv0 + 3 ;
+
+ return argv0 ;
+} /* program_name */
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** All rights reserved.
**
** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sndfile.h>
+
+#define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof (x [0])))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
typedef struct
{ const char * title ;
const char * origination_time ;
const char * umid ;
const char * coding_history ;
+ const char * time_ref ;
} METADATA_INFO ;
typedef SF_BROADCAST_INFO_VAR (2048) SF_BROADCAST_INFO_2K ;
void sfe_copy_data_fp (SNDFILE *outfile, SNDFILE *infile, int channels) ;
void sfe_copy_data_int (SNDFILE *outfile, SNDFILE *infile, int channels) ;
+
+int sfe_file_type_of_ext (const char *filename, int format) ;
+
+void sfe_dump_format_map (void) ;
+
+const char * program_name (const char * argv0) ;
/*
-** Copyright (C) 2008-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2008-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2008 Conrad Parker <conrad@metadecks.org>
**
** All rights reserved.
**
** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* sndfile-cmp.c
- * Conrad Parker 2008
- */
-
-
#include "sfconfig.h"
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <inttypes.h>
#include <sndfile.h>
+#include "common.h"
+
/* Length of comparison data buffers in units of items */
#define BUFLEN 65536
-static char * progname ;
-static char * filename1, * filename2 ;
+static const char * progname = NULL ;
+static char * filename1 = NULL, * filename2 = NULL ;
static int
-comparison_error (const char * what)
-{ printf ("%s: %s of files %s and %s differ\n", progname, what, filename1, filename2) ;
+comparison_error (const char * what, sf_count_t frame_offset)
+{ char buffer [128] = "" ;
+
+ if (frame_offset >= 0)
+ snprintf (buffer, sizeof (buffer), " (at frame offset %" PRId64 ")", frame_offset) ;
+
+ printf ("%s: %s of files %s and %s differ%s.\n", progname, what, filename1, filename2, buffer) ;
return 1 ;
} /* comparison_error */
double buf1 [BUFLEN], buf2 [BUFLEN] ;
SF_INFO sfinfo1, sfinfo2 ;
SNDFILE * sf1 = NULL, * sf2 = NULL ;
- sf_count_t len, i, nread1, nread2 ;
+ sf_count_t items, i, nread1, nread2, offset = 0 ;
int retval = 0 ;
memset (&sfinfo1, 0, sizeof (SF_INFO)) ;
} ;
if (sfinfo1.samplerate != sfinfo2.samplerate)
- { retval = comparison_error ("Samplerates") ;
+ { retval = comparison_error ("Samplerates", -1) ;
goto out ;
} ;
if (sfinfo1.channels != sfinfo2.channels)
- { retval = comparison_error ("Number of channels") ;
+ { retval = comparison_error ("Number of channels", -1) ;
goto out ;
} ;
/* Calculate the framecount that will fit in our data buffers */
- len = BUFLEN / sfinfo1.channels ;
+ items = BUFLEN / sfinfo1.channels ;
- while ( (nread1 = sf_readf_double (sf1, buf1, len)) > 0)
+ while ( (nread1 = sf_readf_double (sf1, buf1, items)) > 0)
{ nread2 = sf_readf_double (sf2, buf2, nread1) ;
if (nread2 != nread1)
- { retval = comparison_error ("PCM data lengths") ;
+ { retval = comparison_error ("PCM data lengths", -1) ;
goto out ;
} ;
- for (i = 0 ; i < nread1 ; i++)
+ for (i = 0 ; i < nread1 * sfinfo1.channels ; i++)
{ if (buf1 [i] != buf2 [i])
- { retval = comparison_error ("PCM data") ;
+ { retval = comparison_error ("PCM data", offset + i / sfinfo1.channels) ;
goto out ;
} ;
} ;
+ offset += nread1 ;
} ;
if ( (nread2 = sf_readf_double (sf2, buf2, nread1)) != 0)
- { retval = comparison_error ("PCM data lengths") ;
+ { retval = comparison_error ("PCM data lengths", -1) ;
goto out ;
} ;
} /* print_version */
static void
-print_usage (void)
+usage_exit (void)
{
print_version () ;
printf ("Usage : %s <filename> <filename>\n", progname) ;
printf (" Compare the PCM data of two sound files.\n\n") ;
-} /* print_usage */
+ exit (0) ;
+} /* usage_exit */
int
main (int argc, char *argv [])
{
- progname = strrchr (argv [0], '/') ;
- progname = progname ? progname + 1 : argv [0] ;
+ progname = program_name (argv [0]) ;
if (argc != 3)
- { print_usage () ;
+ { usage_exit () ;
return 1 ;
} ;
if (strcmp (filename1, filename2) == 0)
{ printf ("Error : Input filenames are the same.\n\n") ;
- print_usage () ;
+ usage_exit () ;
return 1 ;
} ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** All rights reserved.
**
SF_INFO infileinfo, outfileinfo ;
} OptionData ;
-typedef struct
-{ const char *ext ;
- int len ;
- int format ;
-} OUTPUT_FORMAT_MAP ;
-
-static void copy_metadata (SNDFILE *outfile, SNDFILE *infile) ;
-
-static OUTPUT_FORMAT_MAP format_map [] =
-{
- { "aif", 3, SF_FORMAT_AIFF },
- { "wav", 0, SF_FORMAT_WAV },
- { "au", 0, SF_FORMAT_AU },
- { "caf", 0, SF_FORMAT_CAF },
- { "flac", 0, SF_FORMAT_FLAC },
- { "snd", 0, SF_FORMAT_AU },
- { "svx", 0, SF_FORMAT_SVX },
- { "paf", 0, SF_ENDIAN_BIG | SF_FORMAT_PAF },
- { "fap", 0, SF_ENDIAN_LITTLE | SF_FORMAT_PAF },
- { "gsm", 0, SF_FORMAT_RAW },
- { "nist", 0, SF_FORMAT_NIST },
- { "htk", 0, SF_FORMAT_HTK },
- { "ircam", 0, SF_FORMAT_IRCAM },
- { "sf", 0, SF_FORMAT_IRCAM },
- { "voc", 0, SF_FORMAT_VOC },
- { "w64", 0, SF_FORMAT_W64 },
- { "raw", 0, SF_FORMAT_RAW },
- { "mat4", 0, SF_FORMAT_MAT4 },
- { "mat5", 0, SF_FORMAT_MAT5 },
- { "mat", 0, SF_FORMAT_MAT4 },
- { "pvf", 0, SF_FORMAT_PVF },
- { "sds", 0, SF_FORMAT_SDS },
- { "sd2", 0, SF_FORMAT_SD2 },
- { "vox", 0, SF_FORMAT_RAW },
- { "xi", 0, SF_FORMAT_XI },
- { "wve", 0, SF_FORMAT_WVE },
- { "oga", 0, SF_FORMAT_OGG },
- { "mpc", 0, SF_FORMAT_MPC2K },
- { "rf64", 0, SF_FORMAT_RF64 },
-} ; /* format_map */
-
-static int
-guess_output_file_type (char *str, int format)
-{ char buffer [16], *cptr ;
- int k ;
-
- format &= SF_FORMAT_SUBMASK ;
-
- if ((cptr = strrchr (str, '.')) == NULL)
- return 0 ;
-
- strncpy (buffer, cptr + 1, 15) ;
- buffer [15] = 0 ;
-
- for (k = 0 ; buffer [k] ; k++)
- buffer [k] = tolower ((buffer [k])) ;
-
- if (strcmp (buffer, "gsm") == 0)
- return SF_FORMAT_RAW | SF_FORMAT_GSM610 ;
-
- if (strcmp (buffer, "vox") == 0)
- return SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM ;
-
- for (k = 0 ; k < (int) (sizeof (format_map) / sizeof (format_map [0])) ; k++)
- { if (format_map [k].len > 0 && strncmp (buffer, format_map [k].ext, format_map [k].len) == 0)
- return format_map [k].format | format ;
- else if (strcmp (buffer, format_map [k].ext) == 0)
- return format_map [k].format | format ;
- } ;
-
- return 0 ;
-} /* guess_output_file_type */
-
+static void copy_metadata (SNDFILE *outfile, SNDFILE *infile, int channels) ;
static void
-print_usage (char *progname)
-{ SF_FORMAT_INFO info ;
-
- int k ;
-
+usage_exit (const char *progname)
+{
printf ("\nUsage : %s [options] [encoding] <input file> <output file>\n", progname) ;
puts ("\n"
" where [option] may be:\n\n"
- " -override-sample-rate=X : force sample rate of input to X\n\n"
+ " -override-sample-rate=X : force sample rate of input to X\n"
) ;
- puts ("\n"
+ puts (
" where [encoding] may be one of the following:\n\n"
" -pcms8 : force the output to signed 8 bit pcm\n"
" -pcmu8 : force the output to unsigned 8 bit pcm\n"
" output file name. The following extensions are currently understood:\n"
) ;
- for (k = 0 ; k < (int) (sizeof (format_map) / sizeof (format_map [0])) ; k++)
- { info.format = format_map [k].format ;
- sf_command (NULL, SFC_GET_FORMAT_INFO, &info, sizeof (info)) ;
- printf (" %-10s : %s\n", format_map [k].ext, info.name) ;
- } ;
+ sfe_dump_format_map () ;
puts ("") ;
-} /* print_usage */
+ exit (0) ;
+} /* usage_exit */
int
main (int argc, char * argv [])
-{ char *progname, *infilename, *outfilename ;
+{ const char *progname, *infilename, *outfilename ;
SNDFILE *infile = NULL, *outfile = NULL ;
SF_INFO sfinfo ;
int k, outfilemajor, outfileminor = 0, infileminor ;
int override_sample_rate = 0 ; /* assume no sample rate override. */
- progname = strrchr (argv [0], '/') ;
- progname = progname ? progname + 1 : argv [0] ;
+ progname = program_name (argv [0]) ;
if (argc < 3 || argc > 5)
- { print_usage (progname) ;
+ { usage_exit (progname) ;
return 1 ;
} ;
if (strcmp (infilename, outfilename) == 0)
{ printf ("Error : Input and output filenames are the same.\n\n") ;
- print_usage (progname) ;
+ usage_exit (progname) ;
return 1 ;
} ;
- if (infilename [0] == '-')
+ if (strlen (infilename) > 1 && infilename [0] == '-')
{ printf ("Error : Input filename (%s) looks like an option.\n\n", infilename) ;
- print_usage (progname) ;
+ usage_exit (progname) ;
return 1 ;
} ;
if (outfilename [0] == '-')
{ printf ("Error : Output filename (%s) looks like an option.\n\n", outfilename) ;
- print_usage (progname) ;
+ usage_exit (progname) ;
return 1 ;
} ;
exit (1) ;
} ;
+ memset (&sfinfo, 0, sizeof (sfinfo)) ;
+
if ((infile = sf_open (infilename, SFM_READ, &sfinfo)) == NULL)
{ printf ("Not able to open input file %s.\n", infilename) ;
puts (sf_strerror (NULL)) ;
infileminor = sfinfo.format & SF_FORMAT_SUBMASK ;
- if ((sfinfo.format = guess_output_file_type (outfilename, sfinfo.format)) == 0)
+ if ((sfinfo.format = sfe_file_type_of_ext (outfilename, sfinfo.format)) == 0)
{ printf ("Error : Not able to determine output file type for %s.\n", outfilename) ;
return 1 ;
} ;
} ;
/* Copy the metadata */
- copy_metadata (outfile, infile) ;
+ copy_metadata (outfile, infile, sfinfo.channels) ;
if ((outfileminor == SF_FORMAT_DOUBLE) || (outfileminor == SF_FORMAT_FLOAT)
|| (infileminor == SF_FORMAT_DOUBLE) || (infileminor == SF_FORMAT_FLOAT)
} /* main */
static void
-copy_metadata (SNDFILE *outfile, SNDFILE *infile)
+copy_metadata (SNDFILE *outfile, SNDFILE *infile, int channels)
{ SF_INSTRUMENT inst ;
SF_BROADCAST_INFO_2K binfo ;
const char *str ;
- int k, err = 0 ;
+ int k, chanmap [256] ;
for (k = SF_STR_FIRST ; k <= SF_STR_LAST ; k++)
{ str = sf_get_string (infile, k) ;
if (str != NULL)
- err = sf_set_string (outfile, k, str) ;
+ sf_set_string (outfile, k, str) ;
} ;
memset (&inst, 0, sizeof (inst)) ;
memset (&binfo, 0, sizeof (binfo)) ;
+ if (channels < ARRAY_LEN (chanmap))
+ { size_t size = channels * sizeof (chanmap [0]) ;
+
+ if (sf_command (infile, SFC_GET_CHANNEL_MAP_INFO, chanmap, size) == SF_TRUE)
+ sf_command (outfile, SFC_SET_CHANNEL_MAP_INFO, chanmap, size) ;
+ } ;
+
if (sf_command (infile, SFC_GET_INSTRUMENT, &inst, sizeof (inst)) == SF_TRUE)
sf_command (outfile, SFC_SET_INSTRUMENT, &inst, sizeof (inst)) ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** All rights reserved.
**
#if (defined (WIN32) || defined (_WIN32))
#include <windows.h>
-#define snprintf _snprintf
#endif
static void print_version (void) ;
-static void print_usage (const char *progname) ;
+static void usage_exit (const char *progname) ;
static void info_dump (const char *filename) ;
static int instrument_dump (const char *filename) ;
static int broadcast_dump (const char *filename) ;
+static int chanmap_dump (const char *filename) ;
static void total_dump (void) ;
static double total_seconds = 0.0 ;
print_version () ;
if (argc < 2 || strcmp (argv [1], "--help") == 0 || strcmp (argv [1], "-h") == 0)
- { char *progname ;
-
- progname = strrchr (argv [0], '/') ;
- progname = progname ? progname + 1 : argv [0] ;
-
- print_usage (progname) ;
+ { usage_exit (program_name (argv [0])) ;
return 1 ;
} ;
return error ;
} ;
+ if (strcmp (argv [1], "-c") == 0)
+ { int error = 0 ;
+
+ for (k = 2 ; k < argc ; k++)
+ error += chanmap_dump (argv [k]) ;
+ return error ;
+ } ;
+
for (k = 1 ; k < argc ; k++)
info_dump (argv [k]) ;
static void
-print_usage (const char *progname)
+usage_exit (const char *progname)
{ printf ("Usage :\n %s <file> ...\n", progname) ;
printf (" Prints out information about one or more sound files.\n\n") ;
printf (" %s -i <file>\n", progname) ;
*/
Sleep (5 * 1000) ;
#endif
-} /* print_usage */
+ printf ("Using %s.\n\n", sf_version_string ()) ;
+ exit (0) ;
+} /* usage_exit */
/*==============================================================================
** Dumping of sndfile info.
printf ("----------------------------------------\n") ;
printf ("Sample Rate : %d\n", sfinfo.samplerate) ;
- printf ("Frames : %" PRId64 "\n", sfinfo.frames) ;
+
+ if (sfinfo.frames == SF_COUNT_MAX)
+ printf ("Frames : unknown\n") ;
+ else
+ printf ("Frames : %" PRId64 "\n", sfinfo.frames) ;
+
printf ("Channels : %d\n", sfinfo.channels) ;
printf ("Format : 0x%08X\n", sfinfo.format) ;
printf ("Sections : %d\n", sfinfo.sections) ;
return 0 ;
} /* broadcast_dump */
+static int
+chanmap_dump (const char *filename)
+{ SNDFILE *file ;
+ SF_INFO sfinfo ;
+ int * channel_map ;
+ int got_chanmap, k ;
+
+ memset (&sfinfo, 0, sizeof (sfinfo)) ;
+
+ if ((file = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
+ { printf ("Error : Not able to open input file %s.\n", filename) ;
+ fflush (stdout) ;
+ memset (data, 0, sizeof (data)) ;
+ puts (sf_strerror (NULL)) ;
+ return 1 ;
+ } ;
+
+ if ((channel_map = calloc (sfinfo.channels, sizeof (int))) == NULL)
+ { printf ("Error : malloc failed.\n\n") ;
+ return 1 ;
+ } ;
+
+ got_chanmap = sf_command (file, SFC_GET_CHANNEL_MAP_INFO, channel_map, sfinfo.channels * sizeof (int)) ;
+ sf_close (file) ;
+
+ if (got_chanmap == SF_FALSE)
+ { printf ("Error : File '%s' does not contain channel map information.\n\n", filename) ;
+ free (channel_map) ;
+ return 1 ;
+ } ;
+
+ printf ("File : %s\n\n", filename) ;
+
+ puts (" Chan Position") ;
+ for (k = 0 ; k < sfinfo.channels ; k ++)
+ { const char * name ;
+
+#define CASE_NAME(x) case x : name = #x ; break ;
+ switch (channel_map [k])
+ { CASE_NAME (SF_CHANNEL_MAP_INVALID) ;
+ CASE_NAME (SF_CHANNEL_MAP_MONO) ;
+ CASE_NAME (SF_CHANNEL_MAP_LEFT) ;
+ CASE_NAME (SF_CHANNEL_MAP_RIGHT) ;
+ CASE_NAME (SF_CHANNEL_MAP_CENTER) ;
+ CASE_NAME (SF_CHANNEL_MAP_FRONT_LEFT) ;
+ CASE_NAME (SF_CHANNEL_MAP_FRONT_RIGHT) ;
+ CASE_NAME (SF_CHANNEL_MAP_FRONT_CENTER) ;
+ CASE_NAME (SF_CHANNEL_MAP_REAR_CENTER) ;
+ CASE_NAME (SF_CHANNEL_MAP_REAR_LEFT) ;
+ CASE_NAME (SF_CHANNEL_MAP_REAR_RIGHT) ;
+ CASE_NAME (SF_CHANNEL_MAP_LFE) ;
+ CASE_NAME (SF_CHANNEL_MAP_FRONT_LEFT_OF_CENTER) ;
+ CASE_NAME (SF_CHANNEL_MAP_FRONT_RIGHT_OF_CENTER) ;
+ CASE_NAME (SF_CHANNEL_MAP_SIDE_LEFT) ;
+ CASE_NAME (SF_CHANNEL_MAP_SIDE_RIGHT) ;
+ CASE_NAME (SF_CHANNEL_MAP_TOP_CENTER) ;
+ CASE_NAME (SF_CHANNEL_MAP_TOP_FRONT_LEFT) ;
+ CASE_NAME (SF_CHANNEL_MAP_TOP_FRONT_RIGHT) ;
+ CASE_NAME (SF_CHANNEL_MAP_TOP_FRONT_CENTER) ;
+ CASE_NAME (SF_CHANNEL_MAP_TOP_REAR_LEFT) ;
+ CASE_NAME (SF_CHANNEL_MAP_TOP_REAR_RIGHT) ;
+ CASE_NAME (SF_CHANNEL_MAP_TOP_REAR_CENTER) ;
+ CASE_NAME (SF_CHANNEL_MAP_MAX) ;
+ default : name = "default" ;
+ break ;
+ } ;
+
+ printf (" %3d %s\n", k, name) ;
+ } ;
+
+ putchar ('\n') ;
+ free (channel_map) ;
+
+ return 0 ;
+} /* chanmap_dump */
+
static void
total_dump (void)
{ printf ("========================================\n") ;
+++ /dev/null
-/*
-** Copyright (c) 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
-** Copyright (C) 2007 Jonatan Liljedahl <lijon@kymatica.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 "sfconfig.h"
-
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if HAVE_JACK
-
-#include <math.h>
-#include <pthread.h>
-
-#include <jack/jack.h>
-#include <jack/ringbuffer.h>
-
-#include <sndfile.h>
-
-#define RB_SIZE (1 << 16)
-
-typedef struct _thread_info
-{ pthread_t thread_id ;
- SNDFILE *sndfile ;
- jack_nframes_t pos ;
- jack_client_t *client ;
- unsigned int channels ;
- volatile int can_process ;
- volatile int read_done ;
- volatile int play_done ;
-} thread_info_t ;
-
-pthread_mutex_t disk_thread_lock = PTHREAD_MUTEX_INITIALIZER ;
-pthread_cond_t data_ready = PTHREAD_COND_INITIALIZER ;
-
-static jack_ringbuffer_t *ringbuf ;
-static jack_port_t **output_port ;
-static jack_default_audio_sample_t ** outs ;
-const size_t sample_size = sizeof (jack_default_audio_sample_t) ;
-
-static int
-process (jack_nframes_t nframes, void * arg)
-{
- thread_info_t *info = (thread_info_t *) arg ;
- jack_default_audio_sample_t buf [info->channels] ;
- unsigned i, n ;
-
- if (! info->can_process)
- return 0 ;
-
- for (n = 0 ; n < info->channels ; n++)
- outs [n] = jack_port_get_buffer (output_port [n], nframes) ;
-
- for (i = 0 ; i < nframes ; i++)
- { size_t read_cnt ;
-
- /* Read one frame of audio. */
- read_cnt = jack_ringbuffer_read (ringbuf, (void*) buf, sample_size*info->channels) ;
- if (read_cnt == 0 && info->read_done)
- { /* File is done, so stop the main loop. */
- info->play_done = 1 ;
- return 0 ;
- } ;
-
- /* Update play-position counter. */
- info->pos += read_cnt / (sample_size*info->channels) ;
-
- /* Output each channel of the frame. */
- for (n = 0 ; n < info->channels ; n++)
- outs [n][i] = buf [n] ;
- } ;
-
- /* Wake up the disk thread to read more data. */
- if (pthread_mutex_trylock (&disk_thread_lock) == 0)
- { pthread_cond_signal (&data_ready) ;
- pthread_mutex_unlock (&disk_thread_lock) ;
- } ;
-
- return 0 ;
-} /* process */
-
-static void *
-disk_thread (void *arg)
-{ thread_info_t *info = (thread_info_t *) arg ;
- sf_count_t buf_avail, read_frames ;
- jack_ringbuffer_data_t vec [2] ;
- size_t bytes_per_frame = sample_size*info->channels ;
-
- pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL) ;
- pthread_mutex_lock (&disk_thread_lock) ;
-
- while (1)
- { jack_ringbuffer_get_write_vector (ringbuf, vec) ;
-
- read_frames = 0 ;
-
- if (vec [0].len)
- { /* Fill the first part of the ringbuffer. */
- buf_avail = vec [0].len / bytes_per_frame ;
- read_frames = sf_readf_float (info->sndfile, (float *) vec [0].buf, buf_avail) ;
- if (vec [1].len)
- { /* Fill the second part of the ringbuffer? */
- buf_avail = vec [1].len / bytes_per_frame ;
- read_frames += sf_readf_float (info->sndfile, (float *) vec [1].buf, buf_avail) ;
- } ;
- } ;
-
- if (read_frames == 0)
- break ; /* end of file? */
-
- jack_ringbuffer_write_advance (ringbuf, read_frames * bytes_per_frame) ;
-
- /* Tell process that we've filled the ringbuffer. */
- info->can_process = 1 ;
-
- /* Wait for the process thread to wake us up. */
- pthread_cond_wait (&data_ready, &disk_thread_lock) ;
- } ;
-
- /* Tell that we're done reading the file. */
- info->read_done = 1 ;
- pthread_mutex_unlock (&disk_thread_lock) ;
-
- return 0 ;
-} /* disk_thread */
-
-static void
-jack_shutdown (void *arg)
-{ (void) arg ;
- exit (1) ;
-} /* jack_shutdown */
-
-static void
-print_time (jack_nframes_t pos, int jack_sr)
-{ float sec = pos / (1.0 * jack_sr) ;
- int min = sec / 60.0 ;
- fprintf (stderr, "%02d:%05.2f", min, fmod (sec, 60.0)) ;
-} /* print_time */
-
-int
-main (int narg, char * args [])
-{
- SNDFILE *sndfile ;
- SF_INFO sndfileinfo ;
- jack_client_t *client ;
- thread_info_t info ;
- int i, jack_sr ;
-
- if (narg < 2)
- { fprintf (stderr, "no soundfile given\n") ;
- return 1 ;
- } ;
-
- // create jack client
- if ((client = jack_client_new ("jackplay")) == 0)
- {
- fprintf (stderr, "Jack server not running?\n") ;
- return 1 ;
- } ;
-
- jack_sr = jack_get_sample_rate (client) ;
-
- /* Open the soundfile. */
- sndfileinfo.format = 0 ;
- sndfile = sf_open (args [1], SFM_READ, &sndfileinfo) ;
- if (sndfile == NULL)
- { fprintf (stderr, "Could not open soundfile '%s'\n", args [1]) ;
- return 1 ;
- } ;
-
- fprintf (stderr, "Channels : %d\nSample rate : %d Hz\nDuration : ", sndfileinfo.channels, sndfileinfo.samplerate) ;
-
- print_time (sndfileinfo.frames, sndfileinfo.samplerate) ;
- fprintf (stderr, "\n") ;
-
- if (sndfileinfo.samplerate != jack_sr)
- fprintf (stderr, "Warning: samplerate of soundfile (%d Hz) does not match jack server (%d Hz).\n", sndfileinfo.samplerate, jack_sr) ;
-
- /* Init the thread info struct. */
- memset (&info, 0, sizeof (info)) ;
- info.can_process = 0 ;
- info.read_done = 0 ;
- info.play_done = 0 ;
- info.sndfile = sndfile ;
- info.channels = sndfileinfo.channels ;
- info.client = client ;
- info.pos = 0 ;
-
- /* Set up callbacks. */
- jack_set_process_callback (client, process, &info) ;
- jack_on_shutdown (client, jack_shutdown, 0) ;
-
- /* Allocate output ports. */
- output_port = calloc (sndfileinfo.channels, sizeof (jack_port_t *)) ;
- outs = calloc (sndfileinfo.channels, sizeof (jack_default_audio_sample_t *)) ;
- for (i = 0 ; i < sndfileinfo.channels ; i++)
- { char name [16] ;
-
- snprintf (name, sizeof (name), "out_%d", i + 1) ;
- output_port [i] = jack_port_register (client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0) ;
- } ;
-
- /* Allocate and clear ringbuffer. */
- ringbuf = jack_ringbuffer_create (sizeof (jack_default_audio_sample_t) * RB_SIZE) ;
- memset (ringbuf->buf, 0, ringbuf->size) ;
-
- /* Activate client. */
- if (jack_activate (client))
- { fprintf (stderr, "Cannot activate client.\n") ;
- return 1 ;
- } ;
-
- /* Auto connect all channels. */
- for (i = 0 ; i < sndfileinfo.channels ; i++)
- { char name [64] ;
-
- snprintf (name, sizeof (name), "alsa_pcm:playback_%d", i + 1) ;
-
- if (jack_connect (client, jack_port_name (output_port [i]), name))
- fprintf (stderr, "Cannot connect output port %d (%s).\n", i, name) ;
- } ;
-
- /* Start the disk thread. */
- pthread_create (&info.thread_id, NULL, disk_thread, &info) ;
-
- /* Sit in a loop, displaying the current play position. */
- while (! info.play_done)
- { fprintf (stderr, "\r-> ") ;
- print_time (info.pos, jack_sr) ;
- fflush (stdout) ;
- usleep (50000) ;
- } ;
-
- /* Clean up. */
- jack_client_close (client) ;
- jack_ringbuffer_free (ringbuf) ;
- sf_close (sndfile) ;
- free (outs) ;
- free (output_port) ;
-
- puts ("") ;
-
- return 0 ;
-} /* main */
-
-#else
-
-int
-main (void)
-{
- puts (
- "Sorry this program was compiled without libjack (which probably\n"
- "only exists on Linux and Mac OSX) and hence doesn't work."
- ) ;
-
- return 0 ;
-} /* main */
-
-#endif
/*
-** Copyright (C) 2008 George Blood Audio
-** Written by Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2008-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2008-2010 George Blood Audio
**
** All rights reserved.
**
int start ;
/* Store the program name. */
- progname = strrchr (argv [0], '/') ;
- progname = progname ? progname + 1 : argv [0] ;
+ progname = program_name (argv [0]) ;
/* Check if we've been asked for help. */
if (argc <= 2 || strcmp (argv [1], "--help") == 0 || strcmp (argv [1], "-h") == 0)
" --str-license Print the license metadata.\n"
) ;
+ printf ("Using %s.\n\n", sf_version_string ()) ;
exit (exit_code) ;
} /* usage_exit */
/*
-** Copyright (C) 2008 George Blood Audio
-** Written by Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2008-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2008-2010 George Blood Audio
**
** All rights reserved.
**
int k ;
/* Store the program name. */
- progname = strrchr (argv [0], '/') ;
- progname = progname ? progname + 1 : argv [0] ;
+ progname = program_name (argv [0]) ;
/* Check if we've been asked for help. */
if (argc < 3 || strcmp (argv [1], "--help") == 0 || strcmp (argv [1], "-h") == 0)
HANDLE_BEXT_ARG ("--bext-orig-date", origination_date) ;
HANDLE_BEXT_ARG ("--bext-orig-time", origination_time) ;
HANDLE_BEXT_ARG ("--bext-coding-hist", coding_history) ;
+ HANDLE_BEXT_ARG ("--bext-time-ref", time_ref) ;
#define HANDLE_STR_ARG(cmd,field) \
if (strcmp (argv [k], cmd) == 0) \
continue ; \
} ;
+ HANDLE_STR_ARG ("--str-comment", comment) ;
HANDLE_STR_ARG ("--str-title", title) ;
HANDLE_STR_ARG ("--str-copyright", copyright) ;
HANDLE_STR_ARG ("--str-artist", artist) ;
" --bext-umid Set the 'bext' UMID.\n"
" --bext-orig-date Set the 'bext' origination date.\n"
" --bext-orig-time Set the 'bext' origination time.\n"
- " --bext-coding-hist Set the 'bext' coding history\n"
+ " --bext-coding-hist Set the 'bext' coding history.\n"
+ " --bext-time-raf Set the 'bext' Time ref.\n"
"\n"
+ " --str-comment Set the metadata comment.\n"
" --str-title Set the metadata title.\n"
" --str-copyright Set the metadata copyright.\n"
" --str-artist Set the metadata artist.\n"
"exit with an appropriate error message.\n"
) ;
+ printf ("Using %s.\n\n", sf_version_string ()) ;
exit (exit_code) ;
} /* usage_exit */
if (info->description || info->originator || info->originator_reference)
return 1 ;
- if (info->origination_date || info->origination_time || info->umid || info->coding_history)
+ if (info->origination_date || info->origination_time || info->umid || info->coding_history || info->time_ref)
return 1 ;
return 0 ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** All rights reserved.
**
#include <unistd.h>
#endif
+#include <sndfile.h>
+
+#include "common.h"
+
#if HAVE_ALSA_ASOUNDLIB_H
#define ALSA_PCM_NEW_HW_PARAMS_API
#define ALSA_PCM_NEW_SW_PARAMS_API
#include <sys/time.h>
#endif
-#if defined (__linux__)
+#if defined (__linux__) || defined (__FreeBSD_kernel__) || defined (__FreeBSD__)
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#include <Carbon.h>
#include <CoreAudio/AudioHardware.h>
+#elif defined (HAVE_SNDIO_H)
+ #include <sndio.h>
+
#elif (defined (sun) && defined (unix))
#include <fcntl.h>
#include <sys/ioctl.h>
#endif
-#include <sndfile.h>
-
#define SIGNED_SIZEOF(x) ((int) sizeof (x))
#define BUFFER_LEN (2048)
** Linux/OSS functions for playing a sound.
*/
-#if defined (__linux__)
+#if defined (__linux__) || defined (__FreeBSD_kernel__) || defined (__FreeBSD__)
-static int linux_open_dsp_device (int channels, int srate) ;
+static int opensoundsys_open_device (int channels, int srate) ;
-static void
-linux_play (int argc, char *argv [])
+static int
+opensoundsys_play (int argc, char *argv [])
{ static short buffer [BUFFER_LEN] ;
SNDFILE *sndfile ;
SF_INFO sfinfo ;
continue ;
} ;
- audio_device = linux_open_dsp_device (sfinfo.channels, sfinfo.samplerate) ;
+ audio_device = opensoundsys_open_device (sfinfo.channels, sfinfo.samplerate) ;
subformat = sfinfo.format & SF_FORMAT_SUBMASK ;
sf_close (sndfile) ;
} ;
- return ;
-} /* linux_play */
+ return writecount ;
+} /* opensoundsys_play */
static int
-linux_open_dsp_device (int channels, int srate)
+opensoundsys_open_device (int channels, int srate)
{ int fd, stereo, fmt ;
if ((fd = open ("/dev/dsp", O_WRONLY, 0)) == -1 &&
(fd = open ("/dev/sound/dsp", O_WRONLY, 0)) == -1)
- { perror ("linux_open_dsp_device : open ") ;
+ { perror ("opensoundsys_open_device : open ") ;
exit (1) ;
} ;
stereo = 0 ;
if (ioctl (fd, SNDCTL_DSP_STEREO, &stereo) == -1)
{ /* Fatal error */
- perror ("linux_open_dsp_device : stereo ") ;
+ perror ("opensoundsys_open_device : stereo ") ;
exit (1) ;
} ;
if (ioctl (fd, SNDCTL_DSP_RESET, 0))
- { perror ("linux_open_dsp_device : reset ") ;
+ { perror ("opensoundsys_open_device : reset ") ;
exit (1) ;
} ;
fmt = CPU_IS_BIG_ENDIAN ? AFMT_S16_BE : AFMT_S16_LE ;
if (ioctl (fd, SNDCTL_DSP_SETFMT, &fmt) != 0)
- { perror ("linux_open_dsp_device : set format ") ;
+ { perror ("opensoundsys_open_device : set format ") ;
exit (1) ;
} ;
if (ioctl (fd, SNDCTL_DSP_CHANNELS, &channels) != 0)
- { perror ("linux_open_dsp_device : channels ") ;
+ { perror ("opensoundsys_open_device : channels ") ;
exit (1) ;
} ;
if (ioctl (fd, SNDCTL_DSP_SPEED, &srate) != 0)
- { perror ("linux_open_dsp_device : sample rate ") ;
+ { perror ("opensoundsys_open_device : sample rate ") ;
exit (1) ;
} ;
if (ioctl (fd, SNDCTL_DSP_SYNC, 0) != 0)
- { perror ("linux_open_dsp_device : sync ") ;
+ { perror ("opensoundsys_open_device : sync ") ;
exit (1) ;
} ;
return fd ;
-} /* linux_open_dsp_device */
+} /* opensoundsys_open_device */
#endif /* __linux__ */
#endif /* Win32 */
+/*------------------------------------------------------------------------------
+** OpenBDS's sndio.
+*/
+
+#if defined (HAVE_SNDIO_H)
+
+static void
+sndio_play (int argc, char *argv [])
+{ struct sio_hdl *hdl ;
+ struct sio_par par ;
+ short buffer [BUFFER_LEN] ;
+ SNDFILE *sndfile ;
+ SF_INFO sfinfo ;
+ int k, readcount ;
+
+ for (k = 1 ; k < argc ; k++)
+ { printf ("Playing %s\n", argv [k]) ;
+ if (! (sndfile = sf_open (argv [k], SFM_READ, &sfinfo)))
+ { puts (sf_strerror (NULL)) ;
+ continue ;
+ } ;
+
+ if (sfinfo.channels < 1 || sfinfo.channels > 2)
+ { printf ("Error : channels = %d.\n", sfinfo.channels) ;
+ continue ;
+ } ;
+
+ if ((hdl = sio_open (NULL, SIO_PLAY, 0)) == NULL)
+ { fprintf (stderr, "open sndio device failed") ;
+ return ;
+ } ;
+
+ sio_initpar (&par) ;
+ par.rate = sfinfo.samplerate ;
+ par.pchan = sfinfo.channels ;
+ par.bits = 16 ;
+ par.sig = 1 ;
+ par.le = SIO_LE_NATIVE ;
+
+ if (! sio_setpar (hdl, &par) || ! sio_getpar (hdl, &par))
+ { fprintf (stderr, "set sndio params failed") ;
+ return ;
+ } ;
+
+ if (! sio_start (hdl))
+ { fprintf (stderr, "sndio start failed") ;
+ return ;
+ } ;
+
+ while ((readcount = sf_read_short (sndfile, buffer, BUFFER_LEN)))
+ sio_write (hdl, buffer, readcount * sizeof (short)) ;
+
+ sio_close (hdl) ;
+ } ;
+
+ return ;
+} /* sndio_play */
+
+#endif /* sndio */
+
/*------------------------------------------------------------------------------
** Solaris.
*/
{
if (argc < 2)
{
- printf ("\nUsage : %s <input sound file>\n\n", argv [0]) ;
+ printf ("\nUsage : %s <input sound file>\n\n", program_name (argv [0])) ;
+ printf (" Using %s.\n\n", sf_version_string ()) ;
#if (OS_IS_WIN32 == 1)
printf ("This is a Unix style command line application which\n"
"should be run in a MSDOS box or Command Shell window.\n\n") ;
printf ("Sleeping for 5 seconds before exiting.\n\n") ;
- /* This is the officially blessed by microsoft way but I can't get
- ** it to link.
- ** Sleep (15) ;
- ** Instead, use this:
- */
Sleep (5 * 1000) ;
#endif
return 1 ;
alsa_play (argc, argv) ;
else
#endif
- linux_play (argc, argv) ;
+ opensoundsys_play (argc, argv) ;
+#elif defined (__FreeBSD_kernel__) || defined (__FreeBSD__)
+ opensoundsys_play (argc, argv) ;
#elif (defined (__MACH__) && defined (__APPLE__))
macosx_play (argc, argv) ;
+#elif defined HAVE_SNDIO_H
+ sndio_play (argc, argv) ;
#elif (defined (sun) && defined (unix))
solaris_play (argc, argv) ;
#elif (OS_IS_WIN32 == 1)
#!/usr/bin/python
-# Copyright (C) 2008 Erik de Castro Lopo <erikd@mega-nerd.com>
+# Copyright (C) 2008-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
#
# All rights reserved.
#
test_update ([ ("--str-artist", "Fox") ])
-test_coding_history ()
+# This never worked.
+# test_coding_history ()
test_rewrite ()
+++ /dev/null
-#!/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 sucks as well, but this seems necessary.
- ACLOCAL_INC = -I /sw/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 Makefile.in src/config.h.in config.cache config.status
- find . -name .deps -type d -exec rm -rf {} \;
-
-
-# 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: 2b02bfd0-d5ed-489b-a554-2bf36903cca9
/*
-** Copyright (C) 2005-2009 Erik de Castro Lopo
+** Copyright (C) 2005-2011 Erik de Castro Lopo
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
/*
-** Copyright (C) 2005-2009 Erik de Castro Lopo
+** Copyright (C) 2005-2011 Erik de Castro Lopo
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
db->count = 0 ;
err = sqlite3_exec (db->sql, db->cmdbuf, (sqlite3_callback) count_callback, db, &errmsg) ;
- if (db->count == 1)
+ if (err == 0 && db->count == 1)
return 1 ;
return 0 ;
/*
-** Copyright (C) 2005 Erik de Castro Lopo
+** Copyright (C) 2005-2011 Erik de Castro Lopo
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
/*
-** Copyright (C) 2005-2009 Erik de Castro Lopo
+** Copyright (C) 2005-2011 Erik de Castro Lopo
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
Requires:
Version: @VERSION@
Libs: -L${libdir} -lsndfile
+Libs.private: @EXTERNAL_LIBS@
Cflags: -I${includedir}
+++ /dev/null
-## Process this file with automake to produce Makefile.in
-
-EXTRA_DIST = README README.original ChangeLog
-
-noinst_HEADERS = g72x.h g72x_priv.h
-noinst_LTLIBRARIES = libg72x.la
-
-noinst_PROGRAMS = g72x_test
-
-CFILES = g72x.c g721.c g723_16.c g723_24.c g723_40.c
-
-libg72x_la_SOURCES = $(CFILES) $(noinst_HEADERS)
-
-g72x_test_SOURCES = g72x_test.c
-g72x_test_LDADD = ./libg72x.la -lm
-
-check: g72x_test$(EXEEXT)
- ./g72x_test$(EXEEXT) all
-
-# Disable autoheader.
-AUTOHEADER=echo
-
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
-**
+** Copyright (C) 1999-2011 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
+** 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 <unistd.h>
#include <stdlib.h>
return 0 ;
} /* main */
-static void
+static void
g721_test (void)
{
return ;
} /* g721_test */
-static void
+static void
g723_test (double margin)
{ static double orig_buffer [BUFFER_SIZE] ;
static short orig [BUFFER_SIZE] ;
static short data [BUFFER_SIZE] ;
G72x_STATE encoder_state, decoder_state ;
-
+
long k ;
int code, position, max_err ;
memset (data, 0, BUFFER_SIZE * sizeof (short)) ;
memset (orig, 0, BUFFER_SIZE * sizeof (short)) ;
-
+
printf (" g723_test : ") ;
fflush (stdout) ;
-
+
gen_signal_double (orig_buffer, 32000.0, BUFFER_SIZE) ;
for (k = 0 ; k < BUFFER_SIZE ; k++)
orig [k] = (short) orig_buffer [k] ;
#define SIGNAL_MAXVAL 30000.0
#define DECAY_COUNT 1000
-static void
+static void
gen_signal_double (double *gendata, double scale, int gendatalen)
{ int k, ramplen ;
double amp = 0.0 ;
-
+
ramplen = DECAY_COUNT ;
-
+
for (k = 0 ; k < gendatalen ; k++)
{ if (k <= ramplen)
amp = scale * k / ((double) ramplen) ;
gendata [k] = amp * (0.4 * sin (33.3 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))
+ 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ;
} ;
-
+
return ;
} /* gen_signal_double */
-static int
+static int
error_function (double data, double orig, double margin)
{ double error ;
error = fabs (data - orig) / 3000.0 ;
else
error = fabs (data - orig) / fabs (orig) ;
-
+
if (error > margin)
{ printf ("\n\n*******************\nError : %f\n", error) ;
return 1 ;
return 0 ;
} /* error_function */
-static int
+static int
oct_save_short (short *a, short *b, int len)
{ FILE *file ;
int k ;
if (! (file = fopen ("error.dat", "w")))
return 1 ;
-
+
fprintf (file, "# Not created by Octave\n") ;
-
+
fprintf (file, "# name: a\n") ;
fprintf (file, "# type: matrix\n") ;
fprintf (file, "# rows: %d\n", len) ;
fprintf (file, "# columns: 1\n") ;
-
+
for (k = 0 ; k < len ; k++)
fprintf (file, "% d\n", a [k]) ;
fprintf (file, "# type: matrix\n") ;
fprintf (file, "# rows: %d\n", len) ;
fprintf (file, "# columns: 1\n") ;
-
+
for (k = 0 ; k < len ; k++)
fprintf (file, "% d\n", b [k]) ;
+++ /dev/null
-## Process this file with automake to produce Makefile.in
-
-EXTRA_DIST = README COPYRIGHT ChangeLog
-
-noinst_HEADERS = gsm.h config.h gsm610_priv.h
-noinst_LTLIBRARIES = libgsm.la
-
-CFILES = add.c decode.c gsm_decode.c gsm_encode.c long_term.c preprocess.c \
- short_term.c code.c gsm_create.c gsm_destroy.c gsm_option.c lpc.c rpe.c table.c
-
-libgsm_la_SOURCES = $(CFILES) $(noinst_HEADERS)
-
-# Disable autoheader.
-AUTOHEADER=echo
-
-
## Process this file with automake to produce Makefile.in
-SUBDIRS = GSM610 G72x
+AUTOMAKE_OPTIONS = subdir-objects
INCLUDES = @EXTERNAL_CFLAGS@
include_HEADERS = sndfile.hh
nodist_include_HEADERS = sndfile.h
-noinst_LTLIBRARIES = libcommon.la
+noinst_LTLIBRARIES = GSM610/libgsm.la G72x/libg72x.la libcommon.la
OS_SPECIFIC_CFLAGS = @OS_SPECIFIC_CFLAGS@
OS_SPECIFIC_LINKS = @OS_SPECIFIC_LINKS@
-SYMBOL_FILES = Symbols.linux Symbols.darwin libsndfile-1.def Symbols.os2
+SYMBOL_FILES = Symbols.gnu-binutils Symbols.darwin libsndfile-1.def Symbols.os2 Symbols.static
EXTRA_DIST = sndfile.h.in config.h.in test_endswap.tpl test_endswap.def \
- $(SYMBOL_FILES) create_symbols_file.py binheader_writef_check.py
+ $(SYMBOL_FILES) create_symbols_file.py binheader_writef_check.py \
+ GSM610/README GSM610/COPYRIGHT GSM610/ChangeLog \
+ G72x/README G72x/README.original G72x/ChangeLog \
+ make-static-lib-hidden-privates.sh
-noinst_HEADERS = common.h sfconfig.h sfendian.h wav_w64.h sf_unistd.h
+noinst_HEADERS = common.h sfconfig.h sfendian.h wav_w64.h sf_unistd.h ogg.h chanmap.h
-noinst_PROGRAMS =
+check_PROGRAMS = test_main G72x/g72x_test
COMMON = common.c file_io.c command.c pcm.c ulaw.c alaw.c float32.c \
double64.c ima_adpcm.c ms_adpcm.c gsm610.c dwvw.c vox_adpcm.c \
interleave.c strings.c dither.c broadcast.c audio_detect.c \
- ima_oki_adpcm.c ima_oki_adpcm.h chunk.c
+ ima_oki_adpcm.c ima_oki_adpcm.h chunk.c ogg.c chanmap.c \
+ windows.c id3.c $(WIN_VERSION_FILE)
FILESPECIFIC = sndfile.c aiff.c au.c avr.c caf.c dwd.c flac.c g72x.c htk.c ircam.c \
- macbinary3.c macos.c mat4.c mat5.c nist.c ogg.c paf.c pvf.c raw.c rx2.c sd2.c \
- sds.c svx.c txw.c voc.c wve.c w64.c wav_w64.c wav.c xi.c mpc2k.c rf64.c
+ macbinary3.c macos.c mat4.c mat5.c nist.c paf.c pvf.c raw.c rx2.c sd2.c \
+ sds.c svx.c txw.c voc.c wve.c w64.c wav_w64.c wav.c xi.c mpc2k.c rf64.c \
+ ogg_vorbis.c ogg_speex.c ogg_pcm.c
+CLEANFILES = *~
+
+if USE_WIN_VERSION_FILE
+WIN_VERSION_FILE = version-metadata.rc
+else
+WIN_VERSION_FILE =
+endif
+
+#===============================================================================
# MinGW requires -no-undefined if a DLL is to be built.
libsndfile_la_LDFLAGS = -no-undefined -version-info @SHARED_VERSION_INFO@ @SHLIB_VERSION_ARG@
libsndfile_la_SOURCES = $(FILESPECIFIC) $(noinst_HEADERS)
libcommon_la_SOURCES = $(COMMON)
-#test_main_SOURCES = test_main.c test_main.h test_conversions.c test_float.c test_endswap.c \
-# test_audio_detect.c test_log_printf.c test_file_io.c test_ima_oki_adpcm.c
-#test_main_LDADD = libcommon.la
-#
-#
-#test_endswap.c: test_endswap.def test_endswap.tpl
-# autogen --writable test_endswap.def
-
-genfiles : $(SYMBOL_FILES)
-
-# A single test programs.
-# It is not possible to place these in the tests/ directory because they
-# need access to the internals of the SF_PRIVATE struct.
-
-check: $(noinst_PROGRAMS)
- @echo
- @echo
- @echo
- @echo "============================================================"
- @if [ -x /usr/bin/python2.5 ]; then $(srcdir)/binheader_writef_check.py $(srcdir)/*.c ; fi
+#======================================================================
+# Subdir libraries.
+
+GSM610_libgsm_la_SOURCES = GSM610/config.h GSM610/gsm.h GSM610/gsm610_priv.h \
+ GSM610/add.c GSM610/code.c GSM610/decode.c GSM610/gsm_create.c \
+ GSM610/gsm_decode.c GSM610/gsm_destroy.c GSM610/gsm_encode.c \
+ GSM610/gsm_option.c GSM610/long_term.c GSM610/lpc.c GSM610/preprocess.c \
+ GSM610/rpe.c GSM610/short_term.c GSM610/table.c
+
+G72x_libg72x_la_SOURCES = $(COMMON)G72x/g72x.h G72x/g72x_priv.h \
+ G72x/g721.c G72x/g723_16.c G72x/g723_24.c G72x/g723_40.c G72x/g72x.c
+
+#======================================================================
+# Test programs.
+
+test_main_SOURCES = test_main.c test_main.h test_conversions.c test_float.c test_endswap.c \
+ test_audio_detect.c test_log_printf.c test_file_io.c test_ima_oki_adpcm.c \
+ test_strncpy_crlf.c test_broadcast_var.c
+test_main_LDADD = libcommon.la
+
+G72x_g72x_test_SOURCES = G72x/g72x_test.c
+G72x_g72x_test_LDADD = G72x/libg72x.la
+
+test_endswap.c: test_endswap.def test_endswap.tpl
+ autogen --writable test_endswap.def
+
+genfiles : test_endswap.c $(SYMBOL_FILES)
+
+check :
+ @if [ -x /usr/bin/python ]; then $(srcdir)/binheader_writef_check.py $(srcdir)/*.c ; fi
+ G72x/g72x_test$(EXEEXT) all
./test_main$(EXEEXT)
- @echo "============================================================"
- @echo
- @echo
- @echo
+
+# Need this target to force building of test programs.
+checkprograms : $(check_PROGRAMS)
#======================================================================
# Generate an OS specific Symbols files. This is done when the author
# builds the distribution tarball. There should be not need for the
# end user to create these files.
-Symbols.linux: create_symbols_file.py
+Symbols.gnu-binutils: create_symbols_file.py
./create_symbols_file.py linux $(VERSION) > $@
Symbols.darwin: create_symbols_file.py
Symbols.os2: create_symbols_file.py
./create_symbols_file.py os2 $(VERSION) > $@
+Symbols.static: create_symbols_file.py
+ ./create_symbols_file.py static $(VERSION) > $@
+
# Fake dependancy to force the creation of these files.
sndfile.o : $(SYMBOL_FILES)
+#======================================================================
+# Building windows resource files (if needed).
+
+.rc.lo:
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) $< -o $@
+
#======================================================================
# Disable autoheader.
AUTOHEADER=echo
-# Dependancies.
-aiff.c au.c g72x.c ircam.c mat4.c mat5.c nist.c paf.c pvf.c : sndfile.h common.h
-raw.c svx.c voc.c w64.c wav.c wav_w64.c htk.c sd2.c rx2.c txw.c : sndfile.h common.h
-sds.c wve.c dwd.c ogg.c xi.c sndfile.c common.c file_io.c : sndfile.h common.h
-command.c pcm.c ulaw.c alaw.c float32.c double64.c ima_adpcm.c : sndfile.h common.h
-ms_adpcm.c gsm610.c dwvw.c vox_adpcm.c interleave.c strings.c : sndfile.h common.h
-dither.c : sndfile.h common.h
+
_sf_strerror
_sf_get_string
_sf_set_string
+_sf_version_string
_sf_open_fd
_sf_open_virtual
_sf_write_sync
+++ /dev/null
-# Auto-generated by create_symbols_file.py
-
-libsndfile.so.1.0
-{
- global:
- sf_command ;
- sf_open ;
- sf_close ;
- sf_seek ;
- sf_error ;
- sf_perror ;
- sf_error_str ;
- sf_error_number ;
- sf_format_check ;
- sf_read_raw ;
- sf_readf_short ;
- sf_readf_int ;
- sf_readf_float ;
- sf_readf_double ;
- sf_read_short ;
- sf_read_int ;
- sf_read_float ;
- sf_read_double ;
- sf_write_raw ;
- sf_writef_short ;
- sf_writef_int ;
- sf_writef_float ;
- sf_writef_double ;
- sf_write_short ;
- sf_write_int ;
- sf_write_float ;
- sf_write_double ;
- sf_strerror ;
- sf_get_string ;
- sf_set_string ;
- sf_open_fd ;
- sf_open_virtual ;
- sf_write_sync ;
- local:
- * ;
-} ;
-
; Auto-generated by create_symbols_file.py
-LIBRARY sndfile1.dll
+LIBRARY sndfile1
INITINSTANCE TERMINSTANCE
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE NONSHARED
_sf_strerror @50
_sf_get_string @60
_sf_set_string @61
+_sf_version_string @68
_sf_open_fd @70
_sf_open_virtual @80
_sf_write_sync @90
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2005 David Viens <davidv@plogue.com>
**
** This program is free software; you can redistribute it and/or modify
#include <string.h>
#include <time.h>
#include <ctype.h>
+#include <inttypes.h>
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
+#include "chanmap.h"
/*------------------------------------------------------------------------------
* Macros to handle big/little endian issues.
#define MARK_MARKER (MAKE_MARKER ('M', 'A', 'R', 'K'))
#define INST_MARKER (MAKE_MARKER ('I', 'N', 'S', 'T'))
#define APPL_MARKER (MAKE_MARKER ('A', 'P', 'P', 'L'))
+#define CHAN_MARKER (MAKE_MARKER ('C', 'H', 'A', 'N'))
#define c_MARKER (MAKE_MARKER ('(', 'c', ')', ' '))
#define NAME_MARKER (MAKE_MARKER ('N', 'A', 'M', 'E'))
sf_count_t comm_offset ;
sf_count_t ssnd_offset ;
+ int chanmap_tag ;
+
MARK_ID_POS *markstr ;
} AIFF_PRIVATE ;
static int aiff_read_basc_chunk (SF_PRIVATE * psf, int) ;
+static int aiff_read_chanmap (SF_PRIVATE * psf, unsigned dword) ;
+
static unsigned int marker_to_position (const MARK_ID_POS *m, unsigned short n, int marksize) ;
/*------------------------------------------------------------------------------
if ((psf->container_data = calloc (1, sizeof (AIFF_PRIVATE))) == NULL)
return SFE_MALLOC_FAILED ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = aiff_read_header (psf, &comm_fmt)))
return error ;
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
} ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_AIFF)
return SFE_BAD_OPEN_FORMAT ;
- if (psf->mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
+ if (psf->file.mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
{ if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
return SFE_MALLOC_FAILED ;
psf->peak_info->peak_loc = SF_PEAK_START ;
} ;
- if (psf->mode != SFM_RDWR || psf->filelength < 40)
+ if (psf->file.mode != SFM_RDWR || psf->filelength < 40)
{ psf->filelength = 0 ;
psf->datalength = 0 ;
psf->dataoffset = 0 ;
break ;
case SF_FORMAT_DWVW_N :
- if (psf->mode != SFM_READ)
+ if (psf->file.mode != SFM_READ)
{ error = SFE_DWVW_BAD_BITWIDTH ;
break ;
} ;
AIFF_PRIVATE *paiff ;
unsigned marker, dword, FORMsize, SSNDsize, bytesread ;
int k, found_chunk = 0, done = 0, error = 0 ;
- char *cptr, byte ;
+ char *cptr ;
int instr_found = 0, mark_found = 0, mark_count = 0 ;
if (psf->filelength > SF_PLATFORM_S64 (0xffffffff))
while (! done)
{ psf_binheader_readf (psf, "m", &marker) ;
- if (psf->mode == SFM_RDWR && (found_chunk & HAVE_SSND))
+ if (psf->file.mode == SFM_RDWR && (found_chunk & HAVE_SSND))
return SFE_AIFF_RW_SSND_NOT_LAST ;
switch (marker)
return SFE_AIFF_NO_FORM ;
psf_binheader_readf (psf, "E4", &FORMsize) ;
- pchk4_store (&(paiff->chunk4), marker, psf->headindex - 8, FORMsize) ;
+ pchk4_store (&paiff->chunk4, marker, psf->headindex - 8, FORMsize) ;
if (psf->fileoffset > 0 && psf->filelength > FORMsize + 8)
{ /* Set file length. */
psf->peak_info->peaks [dword].value = value ;
psf->peak_info->peaks [dword].position = position ;
- snprintf (cptr, sizeof (psf->u.scbuf), " %2d %-12ld %g\n",
- dword, (long) psf->peak_info->peaks [dword].position, psf->peak_info->peaks [dword].value) ;
+ snprintf (cptr, sizeof (psf->u.scbuf), " %2d %-12" PRId64 " %g\n",
+ dword, psf->peak_info->peaks [dword].position, psf->peak_info->peaks [dword].value) ;
cptr [sizeof (psf->u.scbuf) - 1] = 0 ;
- psf_log_printf (psf, cptr) ;
+ psf_log_printf (psf, "%s", cptr) ;
} ;
psf->peak_info->peak_loc = ((found_chunk & HAVE_SSND) == 0) ? SF_PEAK_START : SF_PEAK_END ;
psf->datalength -= ssnd_fmt.offset ;
}
else
- { psf_log_printf (psf, " Offset : %u (Should be zero)\n", ssnd_fmt.offset) ;
+ { psf_log_printf (psf, " Offset : %u\n", ssnd_fmt.offset) ;
psf_log_printf (psf, " Block Size : %u ???\n", ssnd_fmt.blocksize) ;
+ psf->dataoffset += ssnd_fmt.offset ;
+ psf->datalength -= ssnd_fmt.offset ;
} ;
/* Only set dataend if there really is data at the end. */
cptr [dword] = 0 ;
for (k = 0 ; k < (int) dword ; k++)
- if (! isprint (cptr [k]))
+ if (! psf_isprint (cptr [k]))
{ cptr [k] = 0 ;
break ;
} ;
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
psf_log_printf (psf, " %M : %d\n", marker, dword) ;
{ unsigned short mark_id, n = 0 ;
- unsigned char pstr_len ;
unsigned int position ;
bytesread = psf_binheader_readf (psf, "E2", &n) ;
return SFE_MALLOC_FAILED ;
for (n = 0 ; n < mark_count && bytesread < dword ; n++)
- { bytesread += psf_binheader_readf (psf, "E241", &mark_id, &position, &pstr_len) ;
+ { unsigned int pstr_len ;
+ unsigned char ch ;
+
+ bytesread += psf_binheader_readf (psf, "E241", &mark_id, &position, &ch) ;
psf_log_printf (psf, " Mark ID : %u\n Position : %u\n", mark_id, position) ;
- pstr_len += (pstr_len & 1) ? 0 : 1 ;
+ pstr_len = (ch & 1) ? ch : ch + 1 ;
+
+ if (pstr_len < sizeof (psf->u.scbuf) - 1)
+ { bytesread += psf_binheader_readf (psf, "b", psf->u.scbuf, pstr_len) ;
+ psf->u.scbuf [pstr_len] = 0 ;
+ }
+ else
+ { unsigned int read_len = pstr_len - (sizeof (psf->u.scbuf) - 1) ;
+ bytesread += psf_binheader_readf (psf, "bj", psf->u.scbuf, read_len, pstr_len - read_len) ;
+ psf->u.scbuf [sizeof (psf->u.scbuf) - 1] = 0 ;
+ }
- bytesread += psf_binheader_readf (psf, "b", psf->u.scbuf, pstr_len) ;
- psf->u.scbuf [pstr_len] = 0 ;
psf_log_printf (psf, " Name : %s\n", psf->u.scbuf) ;
paiff->markstr [n].markerID = mark_id ;
case NONE_MARKER :
/* Fix for broken AIFC files with incorrect COMM chunk length. */
- psf_binheader_readf (psf, "1", &byte) ;
- dword = byte ;
- psf_binheader_readf (psf, "j", dword) ;
+ { unsigned char byte ;
+ psf_binheader_readf (psf, "1", &byte) ;
+ dword = byte ;
+ psf_binheader_readf (psf, "j", dword) ;
+ }
+ break ;
+
+ case CHAN_MARKER :
+ psf_binheader_readf (psf, "E4", &dword) ;
+ pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
+
+ if (dword < 12)
+ { psf_log_printf (psf, " %M : %d (should be >= 12)\n", marker, dword) ;
+ psf_binheader_readf (psf, "j", dword) ;
+ break ;
+ }
+
+ psf_log_printf (psf, " %M : %d\n", marker, dword) ;
+
+ if ((error = aiff_read_chanmap (psf, dword)))
+ return error ;
break ;
default :
- if (isprint ((marker >> 24) & 0xFF) && isprint ((marker >> 16) & 0xFF)
- && isprint ((marker >> 8) & 0xFF) && isprint (marker & 0xFF))
+ if (psf_isprint ((marker >> 24) & 0xFF) && psf_isprint ((marker >> 16) & 0xFF)
+ && psf_isprint ((marker >> 8) & 0xFF) && psf_isprint (marker & 0xFF))
{ psf_binheader_readf (psf, "E4", &dword) ;
psf_log_printf (psf, " %M : %d (unknown marker)\n", marker, dword) ;
paiff->markstr = NULL ;
} ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ aiff_write_tailer (psf) ;
aiff_write_header (psf, SF_TRUE) ;
} ;
psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
} ;
- if (psf->mode == SFM_RDWR && psf->dataoffset > 0 && paiff->chunk4.count > 0)
+ if (psf->file.mode == SFM_RDWR && psf->dataoffset > 0 && paiff->chunk4.count > 0)
{ int err = aiff_rewrite_header (psf, paiff) ;
if (current > 0)
psf_fseek (psf, current, SEEK_SET) ;
bit_width = psf->bytewidth * 8 ;
comm_frames = (psf->sf.frames > 0xFFFFFFFF) ? 0xFFFFFFFF : psf->sf.frames ;
- switch (SF_CODEC (psf->sf.format))
- { case SF_FORMAT_PCM_S8 :
+ switch (SF_CODEC (psf->sf.format) | endian)
+ { case SF_FORMAT_PCM_S8 | SF_ENDIAN_BIG :
+ psf->endian = SF_ENDIAN_BIG ;
+ comm_type = AIFC_MARKER ;
+ comm_size = SIZEOF_AIFC_COMM ;
+ comm_encoding = twos_MARKER ;
+ break ;
+
+ case SF_FORMAT_PCM_S8 | SF_ENDIAN_LITTLE :
+ psf->endian = SF_ENDIAN_LITTLE ;
+ comm_type = AIFC_MARKER ;
+ comm_size = SIZEOF_AIFC_COMM ;
+ comm_encoding = sowt_MARKER ;
+ break ;
+
+ case SF_FORMAT_PCM_16 | SF_ENDIAN_BIG :
+ psf->endian = SF_ENDIAN_BIG ;
+ comm_type = AIFC_MARKER ;
+ comm_size = SIZEOF_AIFC_COMM ;
+ comm_encoding = twos_MARKER ;
+ break ;
+
+ case SF_FORMAT_PCM_16 | SF_ENDIAN_LITTLE :
+ psf->endian = SF_ENDIAN_LITTLE ;
+ comm_type = AIFC_MARKER ;
+ comm_size = SIZEOF_AIFC_COMM ;
+ comm_encoding = sowt_MARKER ;
+ break ;
+
+ case SF_FORMAT_PCM_24 | SF_ENDIAN_BIG :
+ psf->endian = SF_ENDIAN_BIG ;
+ comm_type = AIFC_MARKER ;
+ comm_size = SIZEOF_AIFC_COMM ;
+ comm_encoding = in24_MARKER ;
+ break ;
+
+ case SF_FORMAT_PCM_24 | SF_ENDIAN_LITTLE :
+ psf->endian = SF_ENDIAN_LITTLE ;
+ comm_type = AIFC_MARKER ;
+ comm_size = SIZEOF_AIFC_COMM ;
+ comm_encoding = ni24_MARKER ;
+ break ;
+
+ case SF_FORMAT_PCM_32 | SF_ENDIAN_BIG :
+ psf->endian = SF_ENDIAN_BIG ;
+ comm_type = AIFC_MARKER ;
+ comm_size = SIZEOF_AIFC_COMM ;
+ comm_encoding = in32_MARKER ;
+ break ;
+
+ case SF_FORMAT_PCM_32 | SF_ENDIAN_LITTLE :
+ psf->endian = SF_ENDIAN_LITTLE ;
+ comm_type = AIFC_MARKER ;
+ comm_size = SIZEOF_AIFC_COMM ;
+ comm_encoding = ni32_MARKER ;
+ break ;
+
+ case SF_FORMAT_PCM_S8 : /* SF_ENDIAN_FILE */
case SF_FORMAT_PCM_16 :
case SF_FORMAT_PCM_24 :
case SF_FORMAT_PCM_32 :
- switch (endian)
- { case SF_ENDIAN_BIG :
- psf->endian = SF_ENDIAN_BIG ;
- comm_type = AIFC_MARKER ;
- comm_size = SIZEOF_AIFC_COMM ;
- comm_encoding = twos_MARKER ;
- break ;
-
- case SF_ENDIAN_LITTLE :
- psf->endian = SF_ENDIAN_LITTLE ;
- comm_type = AIFC_MARKER ;
- comm_size = SIZEOF_AIFC_COMM ;
- comm_encoding = sowt_MARKER ;
- break ;
-
- default : /* SF_ENDIAN_FILE */
- psf->endian = SF_ENDIAN_BIG ;
- comm_type = AIFF_MARKER ;
- comm_size = SIZEOF_AIFF_COMM ;
- comm_encoding = 0 ;
- break ;
- } ;
- break ;
+ psf->endian = SF_ENDIAN_BIG ;
+ comm_type = AIFF_MARKER ;
+ comm_size = SIZEOF_AIFF_COMM ;
+ comm_encoding = 0 ;
+ break ;
case SF_FORMAT_FLOAT : /* Big endian floating point. */
psf->endian = SF_ENDIAN_BIG ;
if (comm_type == AIFC_MARKER)
psf_binheader_writef (psf, "mb", comm_encoding, comm_zero_bytes, sizeof (comm_zero_bytes)) ;
+ if (psf->channel_map && paiff->chanmap_tag)
+ psf_binheader_writef (psf, "Em4444", CHAN_MARKER, 12, paiff->chanmap_tag, 0, 0) ;
+
if (psf->instrument != NULL)
{ MARK_ID_POS m [4] ;
INST_CHUNK ch ;
} /* aiff_write_strings */
static int
-aiff_command (SF_PRIVATE * UNUSED (psf), int UNUSED (command), void * UNUSED (data), int UNUSED (datasize))
-{
+aiff_command (SF_PRIVATE * psf, int command, void * UNUSED (data), int UNUSED (datasize))
+{ AIFF_PRIVATE *paiff ;
+
+ if ((paiff = psf->container_data) == NULL)
+ return SFE_INTERNAL ;
+
+ switch (command)
+ { case SFC_SET_CHANNEL_MAP_INFO :
+ paiff->chanmap_tag = aiff_caf_find_channel_layout_tag (psf->channel_map, psf->sf.channels) ;
+ return (paiff->chanmap_tag != 0) ;
+
+ default :
+ break ;
+ } ;
+
+
+
return 0 ;
} /* aiff_command */
return 0 ;
} /* aiff_read_basc_chunk */
+
+static int
+aiff_read_chanmap (SF_PRIVATE * psf, unsigned dword)
+{ const AIFF_CAF_CHANNEL_MAP * map_info ;
+ unsigned channel_bitmap, channel_decriptions, bytesread ;
+ int layout_tag ;
+
+ bytesread = psf_binheader_readf (psf, "444", &layout_tag, &channel_bitmap, &channel_decriptions) ;
+
+ if ((map_info = aiff_caf_of_channel_layout_tag (layout_tag)) == NULL)
+ return 0 ;
+
+ psf_log_printf (psf, " Tag : %x\n", layout_tag) ;
+ if (map_info)
+ psf_log_printf (psf, " Layout : %s\n", map_info->name) ;
+
+ if (bytesread < dword)
+ psf_binheader_readf (psf, "j", dword - bytesread) ;
+
+ if (map_info->channel_map != NULL)
+ { size_t chanmap_size = psf->sf.channels * sizeof (psf->channel_map [0]) ;
+
+ free (psf->channel_map) ;
+
+ if ((psf->channel_map = malloc (chanmap_size)) == NULL)
+ return SFE_MALLOC_FAILED ;
+
+ memcpy (psf->channel_map, map_info->channel_map, chanmap_size) ;
+ } ;
+
+ return 0 ;
+} /* aiff_read_chanmap */
+
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
int
alaw_init (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
{ psf->read_short = alaw_read_alaw2s ;
psf->read_int = alaw_read_alaw2i ;
psf->read_float = alaw_read_alaw2f ;
psf->read_double = alaw_read_alaw2d ;
} ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ psf->write_short = alaw_write_s2alaw ;
psf->write_int = alaw_write_i2alaw ;
psf->write_float = alaw_write_f2alaw ;
else
psf->datalength = 0 ;
- psf->sf.frames = psf->datalength / psf->blockwidth ;
+ psf->sf.frames = psf->blockwidth > 0 ? psf->datalength / psf->blockwidth : 0 ;
return 0 ;
} /* alaw_init */
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
{ int subformat ;
int error = 0 ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = au_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ psf->endian = SF_ENDIAN (psf->sf.format) ;
if (CPU_IS_LITTLE_ENDIAN && psf->endian == SF_ENDIAN_CPU)
psf->endian = SF_ENDIAN_LITTLE ;
static int
au_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
au_write_header (psf, SF_TRUE) ;
return 0 ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
/*
-** Copyright (C) 2004-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2004-2011 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
avr_open (SF_PRIVATE *psf)
{ int error = 0 ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = avr_read_header (psf)))
return error ;
} ;
if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_AVR)
return SFE_BAD_OPEN_FORMAT ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ psf->endian = SF_ENDIAN (psf->sf.format) ;
psf->endian = SF_ENDIAN_BIG ;
static int
avr_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
avr_write_header (psf, SF_TRUE) ;
return 0 ;
-#!/usr/bin/python2.5
+#!/usr/bin/python
-# Copyright (C) 2006 Erik de Castro Lopo <erikd@mega-nerd.com>
+# Copyright (C) 2006-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
#
# All rights reserved.
#
print " %s" % item
errors += 1
param_index += 2
-
+
return errors
#===============================================================================
if len (sys.argv) > 1:
- print "%s\n binheader_writef_check :" % sys.argv [0],
+ print "\n binheader_writef_check :",
sys.stdout.flush ()
errors = 0
for fname in sys.argv [1:]:
print "\nErrors : %d\n" % errors
sys.exit (1)
-print "ok"
+print "ok\n"
/*
+** Copyright (C) 2006-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2006 Paul Davis <paul@linuxaudiosystems.com>
-** Copyright (C) 2006-2009 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
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+#include "sfconfig.h"
+
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include "common.h"
-static void strncpy_crlf (char *dest, const char *src, size_t destmax, size_t srcmax) ;
+
static int gen_coding_history (char * added_history, int added_history_max, const SF_INFO * psfinfo) ;
static inline size_t
return 0 ;
return offsetof (SF_BROADCAST_INFO, coding_history) + info->coding_history_size ;
-} /* broadcast_size */
-
-
-static inline size_t
-bc_var_coding_hist_size (const SF_BROADCAST_VAR* var)
-{ return var->size - offsetof (SF_BROADCAST_VAR, binfo.coding_history) ;
-} /* broadcast_size */
-
-SF_BROADCAST_VAR*
-broadcast_var_alloc (size_t datasize)
-{ SF_BROADCAST_VAR * data ;
-
- if ((data = calloc (1, datasize)) != NULL)
- data->size = datasize ;
+} /* bc_min_size */
- return data ;
+SF_BROADCAST_INFO_16K*
+broadcast_var_alloc (void)
+{ return calloc (1, sizeof (SF_BROADCAST_INFO_16K)) ;
} /* broadcast_var_alloc */
-
int
broadcast_var_set (SF_PRIVATE *psf, const SF_BROADCAST_INFO * info, size_t datasize)
-{ char added_history [256] ;
- int added_history_len, len ;
+{ size_t len ;
if (info == NULL)
return SF_FALSE ;
return SF_FALSE ;
} ;
- added_history_len = gen_coding_history (added_history, sizeof (added_history), &(psf->sf)) ;
-
- if (psf->broadcast_var != NULL)
- { size_t coding_hist_offset = offsetof (SF_BROADCAST_INFO, coding_history) ;
-
- if (psf->broadcast_var->binfo.coding_history_size + added_history_len < datasize - coding_hist_offset)
- { free (psf->broadcast_var) ;
- psf->broadcast_var = NULL ;
- } ;
+ if (datasize >= sizeof (SF_BROADCAST_INFO_16K))
+ { psf->error = SFE_BAD_BROADCAST_INFO_TOO_BIG ;
+ return SF_FALSE ;
} ;
- if (psf->broadcast_var == NULL)
- { int size = datasize + added_history_len + 512 ;
-
- psf->broadcast_var = calloc (1, size) ;
- psf->broadcast_var->size = size ;
+ if (psf->broadcast_16k == NULL)
+ { if ((psf->broadcast_16k = broadcast_var_alloc ()) == NULL)
+ { psf->error = SFE_MALLOC_FAILED ;
+ return SF_FALSE ;
+ } ;
} ;
- memcpy (&(psf->broadcast_var->binfo), info, offsetof (SF_BROADCAST_INFO, coding_history)) ;
+ memcpy (psf->broadcast_16k, info, offsetof (SF_BROADCAST_INFO, coding_history)) ;
- strncpy_crlf (psf->broadcast_var->binfo.coding_history, info->coding_history, bc_var_coding_hist_size (psf->broadcast_var), info->coding_history_size) ;
- len = strlen (psf->broadcast_var->binfo.coding_history) ;
+ psf_strlcpy_crlf (psf->broadcast_16k->coding_history, info->coding_history, sizeof (psf->broadcast_16k->coding_history), datasize - offsetof (SF_BROADCAST_INFO, coding_history)) ;
+ len = strlen (psf->broadcast_16k->coding_history) ;
- if (len > 0 && psf->broadcast_var->binfo.coding_history [len] != '\n')
- strncat (psf->broadcast_var->binfo.coding_history, "\r\n", 2) ;
+ if (len > 0 && psf->broadcast_16k->coding_history [len - 1] != '\n')
+ psf_strlcat (psf->broadcast_16k->coding_history, sizeof (psf->broadcast_16k->coding_history), "\r\n") ;
- if (psf->mode == SFM_WRITE)
- strncat (psf->broadcast_var->binfo.coding_history, added_history, strlen (added_history)) ;
+ if (psf->file.mode == SFM_WRITE)
+ { char added_history [256] ;
- psf->broadcast_var->binfo.coding_history_size = strlen (psf->broadcast_var->binfo.coding_history) ;
+ gen_coding_history (added_history, sizeof (added_history), &(psf->sf)) ;
+ psf_strlcat (psf->broadcast_16k->coding_history, sizeof (psf->broadcast_16k->coding_history), added_history) ;
+ } ;
- /* Fore coding_history_size to be even. */
- psf->broadcast_var->binfo.coding_history_size += (psf->broadcast_var->binfo.coding_history_size & 1) ? 1 : 0 ;
+ /* Force coding_history_size to be even. */
+ len = strlen (psf->broadcast_16k->coding_history) ;
+ len += (len & 1) ? 1 : 2 ;
+ psf->broadcast_16k->coding_history_size = len ;
/* Currently writing this version. */
- psf->broadcast_var->binfo.version = 1 ;
+ psf->broadcast_16k->version = 1 ;
return SF_TRUE ;
} /* broadcast_var_set */
broadcast_var_get (SF_PRIVATE *psf, SF_BROADCAST_INFO * data, size_t datasize)
{ size_t size ;
- if (psf->broadcast_var == NULL)
+ if (psf->broadcast_16k == NULL)
return SF_FALSE ;
- size = SF_MIN (datasize, bc_min_size (&(psf->broadcast_var->binfo))) ;
+ size = SF_MIN (datasize, bc_min_size ((const SF_BROADCAST_INFO *) psf->broadcast_16k)) ;
- memcpy (data, &(psf->broadcast_var->binfo), size) ;
+ memcpy (data, psf->broadcast_16k, size) ;
return SF_TRUE ;
-} /* broadcast_var_set */
+} /* broadcast_var_get */
/*------------------------------------------------------------------------------
-** Strncpy which converts all line endings to CR/LF.
*/
-static void
-strncpy_crlf (char *dest, const char *src, size_t destmax, size_t srcmax)
-{ char * destend = dest + destmax - 1 ;
- const char * srcend = src + srcmax ;
-
- while (dest < destend && src < srcend)
- { if ((src [0] == '\r' && src [1] == '\n') || (src [0] == '\n' && src [1] == '\r'))
- { *dest++ = '\r' ;
- *dest++ = '\n' ;
- src += 2 ;
- continue ;
- } ;
-
- if (src [0] == '\r')
- { *dest++ = '\r' ;
- *dest++ = '\n' ;
- src += 1 ;
- continue ;
- } ;
-
- if (src [0] == '\n')
- { *dest++ = '\r' ;
- *dest++ = '\n' ;
- src += 1 ;
- continue ;
- } ;
-
- *dest++ = *src++ ;
- } ;
-
- /* Make sure dest is terminated. */
- *dest = 0 ;
-} /* strncpy_crlf */
-
static int
gen_coding_history (char * added_history, int added_history_max, const SF_INFO * psfinfo)
{ char chnstr [16] ;
return SF_FALSE ;
case 1 :
- strncpy (chnstr, "mono", sizeof (chnstr)) ;
+ psf_strlcpy (chnstr, sizeof (chnstr), "mono") ;
break ;
case 2 :
- strncpy (chnstr, "stereo", sizeof (chnstr)) ;
+ psf_strlcpy (chnstr, sizeof (chnstr), "stereo") ;
break ;
default :
/*
-** Copyright (C) 2005-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2005-2011 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
#include <string.h>
#include <ctype.h>
#include <math.h>
+#include <inttypes.h>
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
+#include "chanmap.h"
/*------------------------------------------------------------------------------
** Macros to handle big/little endian issues.
unsigned int bits_per_chan ;
} DESC_CHUNK ;
+typedef struct
+{ int chanmap_tag ;
+} CAF_PRIVATE ;
+
/*------------------------------------------------------------------------------
** Private static functions.
*/
static int caf_close (SF_PRIVATE *psf) ;
static int caf_read_header (SF_PRIVATE *psf) ;
static int caf_write_header (SF_PRIVATE *psf, int calc_length) ;
+static int caf_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
+static int caf_read_chanmap (SF_PRIVATE * psf, sf_count_t chunk_size) ;
/*------------------------------------------------------------------------------
** Public function.
caf_open (SF_PRIVATE *psf)
{ int subformat, format, error = 0 ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = caf_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if ((psf->container_data = calloc (1, sizeof (CAF_PRIVATE))) == NULL)
+ return SFE_MALLOC_FAILED ;
+
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
psf->blockwidth = psf->bytewidth * psf->sf.channels ;
- if (psf->mode != SFM_RDWR || psf->filelength < 44)
+ if (psf->file.mode != SFM_RDWR || psf->filelength < 44)
{ psf->filelength = 0 ;
psf->datalength = 0 ;
psf->dataoffset = 0 ;
** By default, add the peak chunk to floating point files. Default behaviour
** can be switched off using sf_command (SFC_SET_PEAK_CHUNK, SF_FALSE).
*/
- if (psf->mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
+ if (psf->file.mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
{ if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
return SFE_MALLOC_FAILED ;
psf->peak_info->peak_loc = SF_PEAK_START ;
} ;
psf->container_close = caf_close ;
- /*psf->command = caf_command ;*/
+ psf->command = caf_command ;
switch (subformat)
{ case SF_FORMAT_PCM_S8 :
static int
caf_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
caf_write_header (psf, SF_TRUE) ;
return 0 ;
} /* caf_close */
+static int
+caf_command (SF_PRIVATE * psf, int command, void * UNUSED (data), int UNUSED (datasize))
+{ CAF_PRIVATE *pcaf ;
+
+ if ((pcaf = psf->container_data) == NULL)
+ return SFE_INTERNAL ;
+
+ switch (command)
+ { case SFC_SET_CHANNEL_MAP_INFO :
+ pcaf->chanmap_tag = aiff_caf_find_channel_layout_tag (psf->channel_map, psf->sf.channels) ;
+ return (pcaf->chanmap_tag != 0) ;
+
+ default :
+ break ;
+ } ;
+
+ return 0 ;
+} /* caf_command */
+
/*------------------------------------------------------------------------------
*/
sf_count_t chunk_size ;
double srate ;
short version, flags ;
- int marker, k, have_data = 0 ;
+ int marker, k, have_data = 0, error ;
memset (&desc, 0, sizeof (desc)) ;
" Frames / packet : %u\n Channels / frame : %u\n Bits / channel : %u\n",
desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.pkt_frames, desc.channels_per_frame, desc.bits_per_chan) ;
- if (desc.channels_per_frame > 200)
+ if (desc.channels_per_frame > SF_MAX_CHANNELS)
{ psf_log_printf (psf, "**** Bad channels per frame value %u.\n", desc.channels_per_frame) ;
return SFE_MALFORMED_FILE ;
} ;
psf_binheader_readf (psf, "E4", & (psf->peak_info->edit_number)) ;
psf_log_printf (psf, " edit count : %d\n", psf->peak_info->edit_number) ;
- psf_log_printf (psf, " Ch Position Value\n") ;
+ psf_log_printf (psf, " Ch Position Value\n") ;
for (k = 0 ; k < psf->sf.channels ; k++)
{ sf_count_t position ;
float value ;
psf->peak_info->peaks [k].value = value ;
psf->peak_info->peaks [k].position = position ;
- snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), " %2d %-12ld %g\n", k, (long) position, value) ;
+ snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), " %2d %-12" PRId64 " %g\n", k, position, value) ;
psf_log_printf (psf, psf->u.cbuf) ;
} ;
psf->peak_info->peak_loc = SF_PEAK_START ;
break ;
+ case chan_MARKER :
+ if (chunk_size < 12)
+ { psf_log_printf (psf, "%M : %D (should be >= 12)\n", marker, chunk_size) ;
+ psf_binheader_readf (psf, "j", (int) chunk_size) ;
+ break ;
+ }
+
+ psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
+
+ if ((error = caf_read_chanmap (psf, chunk_size)))
+ return error ;
+ break ;
+
case free_MARKER :
psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
psf_binheader_readf (psf, "j", (int) chunk_size) ;
break ;
case data_MARKER :
- psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
+ if (psf->filelength > 0 && chunk_size + psf->headindex != psf->filelength)
+ psf_log_printf (psf, "%M : %D (should be %D)\n", marker, chunk_size, chunk_size + 4) ;
+ else
+ psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
psf_binheader_readf (psf, "E4", &k) ;
psf_log_printf (psf, " edit : %u\n", k) ;
have_data = 1 ;
static int
caf_write_header (SF_PRIVATE *psf, int calc_length)
-{ DESC_CHUNK desc ;
+{ CAF_PRIVATE *pcaf ;
+ DESC_CHUNK desc ;
sf_count_t current, free_len ;
int subformat ;
+ if ((pcaf = psf->container_data) == NULL)
+ return SFE_INTERNAL ;
+
memset (&desc, 0, sizeof (desc)) ;
current = psf_ftell (psf) ;
psf_binheader_writef (psf, "Ef8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
} ;
+ if (psf->channel_map && pcaf->chanmap_tag)
+ psf_binheader_writef (psf, "Em8444", chan_MARKER, (sf_count_t) 12, pcaf->chanmap_tag, 0, 0) ;
+
/* Add free chunk so that the actual audio data starts at a multiple 0x1000. */
free_len = 0x1000 - psf->headindex - 16 - 12 ;
while (free_len < 0)
free_len += 0x1000 ;
psf_binheader_writef (psf, "Em8z", free_MARKER, free_len, (int) free_len) ;
- psf_binheader_writef (psf, "Em84", data_MARKER, psf->datalength, 0) ;
+ psf_binheader_writef (psf, "Em84", data_MARKER, psf->datalength + 4, 0) ;
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
if (psf->error)
return psf->error ;
} /* caf_write_header */
+static int
+caf_read_chanmap (SF_PRIVATE * psf, sf_count_t chunk_size)
+{ const AIFF_CAF_CHANNEL_MAP * map_info ;
+ unsigned channel_bitmap, channel_decriptions, bytesread ;
+ int layout_tag ;
+
+ bytesread = psf_binheader_readf (psf, "E444", &layout_tag, &channel_bitmap, &channel_decriptions) ;
+
+ map_info = aiff_caf_of_channel_layout_tag (layout_tag) ;
+
+ psf_log_printf (psf, " Tag : %x\n", layout_tag) ;
+ if (map_info)
+ psf_log_printf (psf, " Layout : %s\n", map_info->name) ;
+
+ if (bytesread < chunk_size)
+ psf_binheader_readf (psf, "j", chunk_size - bytesread) ;
+
+ if (map_info->channel_map != NULL)
+ { size_t chanmap_size = psf->sf.channels * sizeof (psf->channel_map [0]) ;
+
+ free (psf->channel_map) ;
+
+ if ((psf->channel_map = malloc (chanmap_size)) == NULL)
+ return SFE_MALLOC_FAILED ;
+
+ memcpy (psf->channel_map, map_info->channel_map, chanmap_size) ;
+ } ;
+
+ return 0 ;
+} /* caf_read_chanmap */
+
/*
-** Copyright (C) 2008-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2008-2011 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
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
{ SF_FORMAT_SVX, "IFF (Amiga IFF/SVX8/SV16)", "iff" },
{ SF_FORMAT_MAT4, "MAT4 (GNU Octave 2.0 / Matlab 4.2)", "mat" },
{ SF_FORMAT_MAT5, "MAT5 (GNU Octave 2.1 / Matlab 5.0)", "mat" },
+ { SF_FORMAT_MPC2K, "MPC (Akai MPC 2k)", "mpc" },
#if HAVE_EXTERNAL_LIBS
{ SF_FORMAT_OGG, "OGG (OGG Container format)", "oga" },
#endif
{ SF_FORMAT_PAF, "PAF (Ensoniq PARIS)", "paf" },
{ SF_FORMAT_PVF, "PVF (Portable Voice Format)", "pvf" },
{ SF_FORMAT_RAW, "RAW (header-less)", "raw" },
+ { SF_FORMAT_RF64, "RF64 (RIFF 64)", "rf64" },
{ SF_FORMAT_SD2, "SD2 (Sound Designer II)", "sd2" },
{ SF_FORMAT_SDS, "SDS (Midi Sample Dump Standard)", "sds" },
{ SF_FORMAT_IRCAM, "SF (Berkeley/IRCAM/CARL)", "sf" },
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
#include <ctype.h>
#include <math.h>
#include <time.h>
-#ifndef _MSC_VER
#include <sys/time.h>
-#endif
+
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
case 'b' :
charptr = va_arg (argptr, char*) ;
- count = va_arg (argptr, int) ;
+ count = va_arg (argptr, size_t) ;
if (count > 0)
byte_count += header_read (psf, charptr, count) ;
break ;
case 'G' :
charptr = va_arg (argptr, char*) ;
- count = va_arg (argptr, int) ;
+ count = va_arg (argptr, size_t) ;
if (count > 0)
byte_count += header_gets (psf, charptr, count) ;
break ;
case 'p' :
/* Get the seek position first. */
- count = va_arg (argptr, int) ;
+ count = va_arg (argptr, size_t) ;
header_seek (psf, count, SEEK_SET) ;
byte_count = count ;
break ;
case 'j' :
/* Get the seek position first. */
- count = va_arg (argptr, int) ;
+ count = va_arg (argptr, size_t) ;
header_seek (psf, count, SEEK_CUR) ;
byte_count += count ;
break ;
printf ("%08X: ", k) ;
for (m = 0 ; m < 16 && k + m < len ; m++)
{ printf (m == 8 ? " %02X " : "%02X ", data [k + m] & 0xFF) ;
- ascii [m] = isprint (data [k + m]) ? data [k + m] : '.' ;
+ ascii [m] = psf_isprint (data [k + m]) ? data [k + m] : '.' ;
} ;
if (m <= 8) printf (" ") ;
do
{
len -- ;
- cptr [len] = isprint (cptr [len]) ? cptr [len] : '.' ;
+ cptr [len] = psf_isprint (cptr [len]) ? cptr [len] : '.' ;
}
while (len > 0) ;
} /* psf_sanitize_string */
return value ;
} /* psf_rand_int32 */
+void
+append_snprintf (char * dest, size_t maxlen, const char * fmt, ...)
+{ size_t len = strlen (dest) ;
+
+ if (len < maxlen)
+ { va_list ap ;
+
+ va_start (ap, fmt) ;
+ vsnprintf (dest + len, maxlen - len, fmt, ap) ;
+ va_end (ap) ;
+ } ;
+
+ return ;
+} /* append_snprintf */
+
+
+void
+psf_strlcpy_crlf (char *dest, const char *src, size_t destmax, size_t srcmax)
+{ /* Must be minus 2 so it can still expand a single trailing '\n' or '\r'. */
+ char * destend = dest + destmax - 2 ;
+ const char * srcend = src + srcmax ;
+
+ while (dest < destend && src < srcend)
+ { if ((src [0] == '\r' && src [1] == '\n') || (src [0] == '\n' && src [1] == '\r'))
+ { *dest++ = '\r' ;
+ *dest++ = '\n' ;
+ src += 2 ;
+ continue ;
+ } ;
+
+ if (src [0] == '\r')
+ { *dest++ = '\r' ;
+ *dest++ = '\n' ;
+ src += 1 ;
+ continue ;
+ } ;
+
+ if (src [0] == '\n')
+ { *dest++ = '\r' ;
+ *dest++ = '\n' ;
+ src += 1 ;
+ continue ;
+ } ;
+
+ *dest++ = *src++ ;
+ } ;
+
+ /* Make sure dest is terminated. */
+ *dest = 0 ;
+} /* psf_strlcpy_crlf */
+
/*==============================================================================
*/
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
#include "sfconfig.h"
#include <stdlib.h>
+#include <string.h>
#if HAVE_STDINT_H
#include <stdint.h>
+#elif HAVE_INTTYPES_H
+#include <inttypes.h>
#endif
#ifndef SNDFILE_H
#include "sndfile.h"
-#elif HAVE_INTTYPES_H
-#include <inttypes.h>
#endif
#ifdef __cplusplus
#if (SIZEOF_LONG == 8)
# define SF_PLATFORM_S64(x) x##l
-#elif COMPILER_IS_GCC || __SUNPRO_C
+#elif (SIZEOF_LONG_LONG == 8)
+# define SF_PLATFORM_S64(x) x##ll
+#elif COMPILER_IS_GCC
# define SF_PLATFORM_S64(x) x##ll
#elif OS_IS_WIN32
# define SF_PLATFORM_S64(x) x##I64
#define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0])))
+#define NOT(x) (! (x))
+
#if (COMPILER_IS_GCC == 1)
#define SF_MAX(x,y) ({ \
typeof (x) sf_max_x1 = (x) ; \
#define SF_MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
+
+#define SF_MAX_CHANNELS 256
+
+
/*
* Macros for spliting the format file of SF_INFI into contrainer type,
** codec type and endian-ness.
#define SF_CODEC(x) ((x) & SF_FORMAT_SUBMASK)
#define SF_ENDIAN(x) ((x) & SF_FORMAT_ENDMASK)
-
enum
{ /* PEAK chunk location. */
SF_PEAK_START = 42,
enum
{ /* Work in progress. */
+ SF_FORMAT_SPEEX = 0x5000000,
+ SF_FORMAT_OGGFLAC = 0x5000001,
/* Formats supported read only. */
SF_FORMAT_TXW = 0x4030000, /* Yamaha TX16 sampler file */
{ return (size_t) x ;
} /* size_t_of_int */
+typedef SF_BROADCAST_INFO_VAR (16 * 1024) SF_BROADCAST_INFO_16K ;
+
+#if SIZEOF_WCHAR_T == 2
+typedef wchar_t sfwchar_t ;
+#else
+typedef int16_t sfwchar_t ;
+#endif
+
+/*
+** This version of isprint specifically ignores any locale info. Its used for
+** determining which characters can be printed in things like hexdumps.
+*/
+static inline int
+psf_isprint (int ch)
+{ return (ch >= ' ' && ch <= '~') ;
+} /* psf_isprint */
+
/*=======================================================================================
** SF_PRIVATE stuct - a pointer to this struct is passed back to the caller of the
** sf_open_XXXX functions. The caller however has no knowledge of the struct's
** contents.
*/
-
typedef struct
-{ int size ;
- SF_BROADCAST_INFO binfo ;
-} SF_BROADCAST_VAR ;
+{
+ union
+ { char c [SF_FILENAME_LEN] ;
+ sfwchar_t wc [SF_FILENAME_LEN] ;
+ } path ;
+
+ union
+ { char c [SF_FILENAME_LEN] ;
+ sfwchar_t wc [SF_FILENAME_LEN] ;
+ } dir ;
+
+ union
+ { char c [SF_FILENAME_LEN / 4] ;
+ sfwchar_t wc [SF_FILENAME_LEN / 4] ;
+ } name ;
+
+#if USE_WINDOWS_API
+ /*
+ ** These fields can only be used in src/file_io.c.
+ ** They are basically the same as a windows file HANDLE.
+ */
+ void *handle, *hsaved ;
+
+ int use_wchar ;
+#else
+ /* These fields can only be used in src/file_io.c. */
+ int filedes, savedes ;
+#endif
+
+ int do_not_close_descriptor ;
+ int mode ; /* Open mode : SFM_READ, SFM_WRITE or SFM_RDWR. */
+} PSF_FILE ;
+
typedef struct sf_private_tag
{
/* Canary in a coal mine. */
- char canary [64] ;
+ union
+ { /* Place a double here to encourage double alignment. */
+ double d [2] ;
+ char c [16] ;
+ } canary ;
/* Force the compiler to double align the start of buffer. */
union
unsigned char ucbuf [SF_BUFFER_LEN / sizeof (signed char)] ;
} u ;
- char filepath [SF_FILENAME_LEN] ;
- char rsrcpath [SF_FILENAME_LEN] ;
- char directory [SF_FILENAME_LEN] ;
- char filename [SF_FILENAME_LEN / 4] ;
+
+ PSF_FILE file, rsrc ;
char syserr [SF_SYSERR_LEN] ;
int logindex ;
int headindex, headend ;
int has_text ;
- int do_not_close_descriptor ;
-
-#if USE_WINDOWS_API
- /*
- ** These fields can only be used in src/file_io.c.
- ** They are basically the same as a windows file HANDLE.
- */
- void *hfile, *hrsrc, *hsaved ;
-#else
- /* These fields can only be used in src/file_io.c. */
- int filedes, rsrcdes, savedes ;
-#endif
int error ;
- int mode ; /* Open mode : SFM_READ, SFM_WRITE or SFM_RDWR. */
int endian ; /* File endianness : SF_ENDIAN_LITTLE or SF_ENDIAN_BIG. */
int data_endswap ; /* Need to endswap data? */
SF_INSTRUMENT *instrument ;
/* Broadcast (EBU) Info */
- SF_BROADCAST_VAR *broadcast_var ;
+ SF_BROADCAST_INFO_16K *broadcast_16k ;
/* Channel map data (if present) : an array of ints. */
int *channel_map ;
SFE_RDWR_BAD_HEADER,
SFE_CMD_HAS_DATA,
SFE_BAD_BROADCAST_INFO_SIZE,
+ SFE_BAD_BROADCAST_INFO_TOO_BIG,
SFE_STR_NO_SUPPORT,
SFE_STR_NOT_WRITE,
SFE_PAF_VERSION,
SFE_PAF_UNKNOWN_FORMAT,
SFE_PAF_SHORT_HEADER,
+ SFE_PAF_BAD_CHANNELS,
SFE_SVX_NO_FORM,
SFE_SVX_NO_BODY,
int32_t psf_rand_int32 (void) ;
+void append_snprintf (char * dest, size_t maxlen, const char * fmt, ...) ;
+void psf_strlcpy_crlf (char *dest, const char *src, size_t destmax, size_t srcmax) ;
+
/* Functions used when writing file headers. */
int psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...) ;
** some 32 bit OSes. Implementation in file_io.c.
*/
-int psf_fopen (SF_PRIVATE *psf, const char *pathname, int flags) ;
-int psf_set_stdio (SF_PRIVATE *psf, int mode) ;
+int psf_fopen (SF_PRIVATE *psf) ;
+int psf_set_stdio (SF_PRIVATE *psf) ;
int psf_file_valid (SF_PRIVATE *psf) ;
void psf_set_file (SF_PRIVATE *psf, int fd) ;
void psf_init_files (SF_PRIVATE *psf) ;
void psf_use_rsrc (SF_PRIVATE *psf, int on_off) ;
+SNDFILE * psf_open_file (SF_PRIVATE *psf, SF_INFO *sfinfo) ;
+
sf_count_t psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence) ;
sf_count_t psf_fread (void *ptr, sf_count_t bytes, sf_count_t count, SF_PRIVATE *psf) ;
sf_count_t psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t count, SF_PRIVATE *psf) ;
int psf_fclose (SF_PRIVATE *psf) ;
/* Open and close the resource fork of a file. */
-int psf_open_rsrc (SF_PRIVATE *psf, int mode) ;
+int psf_open_rsrc (SF_PRIVATE *psf) ;
int psf_close_rsrc (SF_PRIVATE *psf) ;
/*
/* In progress. Do not currently work. */
+int ogg_vorbis_open (SF_PRIVATE *psf) ;
+int ogg_speex_open (SF_PRIVATE *psf) ;
+int ogg_pcm_open (SF_PRIVATE *psf) ;
+
+
int mpeg_open (SF_PRIVATE *psf) ;
int ogg_open (SF_PRIVATE *psf) ;
int rx2_open (SF_PRIVATE *psf) ;
void pchk4_store (PRIV_CHUNK4 * pchk, int marker, sf_count_t offset, sf_count_t len) ;
int pchk4_find (PRIV_CHUNK4 * pchk, int marker) ;
+/*------------------------------------------------------------------------------------
+** Functions that work like OpenBSD's strlcpy/strlcat to replace strncpy/strncat.
+**
+** See : http://www.gratisoft.us/todd/papers/strlcpy.html
+**
+** These functions are available on *BSD, but are not avaialble everywhere so we
+** implement them here.
+**
+** The argument order has been changed to that of strncpy/strncat to cause
+** compiler errors if code is carelessly converted from one to the other.
+*/
+
+static inline void
+psf_strlcat (char *dest, size_t n, const char *src)
+{ strncat (dest, src, n - strlen (dest) - 1) ;
+ dest [n - 1] = 0 ;
+} /* psf_strlcat */
+
+static inline void
+psf_strlcpy (char *dest, size_t n, const char *src)
+{ strncpy (dest, src, n - 1) ;
+ dest [n - 1] = 0 ;
+} /* psf_strlcpy */
+
/*------------------------------------------------------------------------------------
** Other helper functions.
*/
/* Generate the current date as a string. */
void psf_get_date_str (char *str, int maxlen) ;
-SF_BROADCAST_VAR* broadcast_var_alloc (size_t datasize) ;
+SF_BROADCAST_INFO_16K * broadcast_var_alloc (void) ;
int broadcast_var_set (SF_PRIVATE *psf, const SF_BROADCAST_INFO * data, size_t datasize) ;
int broadcast_var_get (SF_PRIVATE *psf, SF_BROADCAST_INFO * data, size_t datasize) ;
} AUDIO_DETECT ;
int audio_detect (SF_PRIVATE * psf, AUDIO_DETECT *ad, const unsigned char * data, int datalen) ;
-
+int id3_skip (SF_PRIVATE * psf) ;
/*------------------------------------------------------------------------------------
** Helper/debug functions.
#!/usr/bin/python
-# Copyright (C) 2003-2007 Erik de Castro Lopo <erikd@mega-nerd.com>
+# Copyright (C) 2003-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
#
# All rights reserved.
#
( "sf_strerror", 50 ),
( "sf_get_string", 60 ),
( "sf_set_string", 61 ),
+ ( "sf_version_string",68 ),
( "sf_open_fd", 70 ),
+ ( "sf_wchar_open", 71 ),
( "sf_open_virtual", 80 ),
( "sf_write_sync", 90 )
)
print "{"
print " global:"
for name, ordinal in ALL_SYMBOLS:
+ if name == "sf_wchar_open":
+ continue
print " %s ;" % name
print " local:"
print " * ;"
def darwin_symbols (progname, version):
print "# Auto-generated by %s\n" %progname
for name, ordinal in ALL_SYMBOLS:
+ if name == "sf_wchar_open":
+ continue
print "_%s" % name
print
return
def os2_symbols (progname, version, name):
print "; Auto-generated by %s\n" %progname
- print "LIBRARY %s%s.dll" % (name, re.sub ("\..*", "", version))
+ print "LIBRARY %s%s" % (name, re.sub ("\..*", "", version))
print "INITINSTANCE TERMINSTANCE"
print "CODE PRELOAD MOVEABLE DISCARDABLE"
print "DATA PRELOAD MOVEABLE MULTIPLE NONSHARED"
print "EXPORTS\n"
for name, ordinal in ALL_SYMBOLS:
- print "_%-20s @%s" % (name, ordinal)
+ if name == "sf_wchar_open":
+ continue
+ print "_%-20s @%s" % (name, ordinal)
print
return
+def plain_symbols (progname, version, name):
+ for name, ordinal in ALL_SYMBOLS:
+ print name
+
def no_symbols (os_name):
print
print "No known way of restricting exported symbols on '%s'." % os_name
print " win32 (ie wintendo)"
print " cygwin (Cygwin on wintendo)"
print " os2 (OS/2)"
+ print " plain (plain list of symbols)"
print
sys.exit (1)
os_name = sys.argv [1]
version = re.sub ("\.[a-z0-9]+$", "", sys.argv [2])
-if os_name == "linux":
+if os_name == "linux" or os_name == "gnu" or os_name == "binutils":
linux_symbols (progname, version)
elif os_name == "darwin":
darwin_symbols (progname, version)
win32_symbols (progname, version, "cygsndfile")
elif os_name == "os2":
os2_symbols (progname, version, "sndfile")
+elif os_name == "static":
+ plain_symbols (progname, version, "")
else:
no_symbols (os_name)
+++ /dev/null
-; Auto-generated by create_symbols_file.py
-
-LIBRARY cygsndfile-1.dll
-EXPORTS
-
-sf_command @1
-sf_open @2
-sf_close @3
-sf_seek @4
-sf_error @7
-sf_perror @8
-sf_error_str @9
-sf_error_number @10
-sf_format_check @11
-sf_read_raw @16
-sf_readf_short @17
-sf_readf_int @18
-sf_readf_float @19
-sf_readf_double @20
-sf_read_short @21
-sf_read_int @22
-sf_read_float @23
-sf_read_double @24
-sf_write_raw @32
-sf_writef_short @33
-sf_writef_int @34
-sf_writef_float @35
-sf_writef_double @36
-sf_write_short @37
-sf_write_int @38
-sf_write_float @39
-sf_write_double @40
-sf_strerror @50
-sf_get_string @60
-sf_set_string @61
-sf_open_fd @70
-sf_open_virtual @80
-sf_write_sync @90
-
/*
-** Copyright (C) 2003-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2003-2011 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
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
psf->blockwidth = sizeof (double) * psf->sf.channels ;
- if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
{ switch (psf->endian + double64_caps)
{ case (SF_ENDIAN_BIG + DOUBLE_CAN_RW_BE) :
psf->data_endswap = SF_FALSE ;
} ;
} ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ switch (psf->endian + double64_caps)
{ case (SF_ENDIAN_LITTLE + DOUBLE_CAN_RW_LE) :
psf->data_endswap = SF_FALSE ;
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
int
dwd_open (SF_PRIVATE *psf)
-{ int subformat, error = 0 ;
+{ int error = 0 ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = dwd_read_header (psf)))
return error ;
} ;
if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_DWD)
return SFE_BAD_OPEN_FORMAT ;
- subformat = SF_CODEC (psf->sf.format) ;
-
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{
/*-psf->endian = SF_ENDIAN (psf->sf.format) ;
if (CPU_IS_LITTLE_ENDIAN && psf->endian == SF_ENDIAN_CPU)
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
if (bitwidth > 24)
return SFE_DWVW_BAD_BITWIDTH ;
- if (psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
if ((pdwvw = calloc (1, sizeof (DWVW_PRIVATE))) == NULL)
dwvw_read_reset (pdwvw) ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ psf->read_short = dwvw_read_s ;
psf->read_int = dwvw_read_i ;
psf->read_float = dwvw_read_f ;
psf->read_double = dwvw_read_d ;
} ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ psf->write_short = dwvw_write_s ;
psf->write_int = dwvw_write_i ;
psf->write_float = dwvw_write_f ;
return 0 ;
pdwvw = (DWVW_PRIVATE*) psf->codec_data ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ static int last_values [12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ;
/* Write 8 zero samples to fully flush output. */
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2003 Ross Bencina <rbencina@iprimus.com.au>
**
** This program is free software; you can redistribute it and/or modify
*/
static int psf_close_fd (int fd) ;
-static int psf_open_fd (const char * path, int mode) ;
+static int psf_open_fd (PSF_FILE * pfile) ;
static sf_count_t psf_get_filelen_fd (int fd) ;
int
-psf_fopen (SF_PRIVATE *psf, const char *pathname, int open_mode)
+psf_fopen (SF_PRIVATE *psf)
{
psf->error = 0 ;
- psf->filedes = psf_open_fd (pathname, open_mode) ;
+ psf->file.filedes = psf_open_fd (&psf->file) ;
- if (psf->filedes == - SFE_BAD_OPEN_MODE)
+ if (psf->file.filedes == - SFE_BAD_OPEN_MODE)
{ psf->error = SFE_BAD_OPEN_MODE ;
- psf->filedes = -1 ;
+ psf->file.filedes = -1 ;
return psf->error ;
} ;
- if (psf->filedes == -1)
+ if (psf->file.filedes == -1)
psf_log_syserr (psf, errno) ;
- psf->mode = open_mode ;
-
return psf->error ;
} /* psf_fopen */
if (psf->virtual_io)
return 0 ;
- if (psf->do_not_close_descriptor)
- { psf->filedes = -1 ;
+ if (psf->file.do_not_close_descriptor)
+ { psf->file.filedes = -1 ;
return 0 ;
} ;
- if ((retval = psf_close_fd (psf->filedes)) == -1)
+ if ((retval = psf_close_fd (psf->file.filedes)) == -1)
psf_log_syserr (psf, errno) ;
- psf->filedes = -1 ;
+ psf->file.filedes = -1 ;
return retval ;
} /* psf_fclose */
int
-psf_open_rsrc (SF_PRIVATE *psf, int open_mode)
+psf_open_rsrc (SF_PRIVATE *psf)
{
- if (psf->rsrcdes > 0)
+ if (psf->rsrc.filedes > 0)
return 0 ;
/* Test for MacOSX style resource fork on HPFS or HPFS+ filesystems. */
- snprintf (psf->rsrcpath, sizeof (psf->rsrcpath), "%s/rsrc", psf->filepath) ;
+ snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s/rsrc", psf->file.path.c) ;
psf->error = SFE_NO_ERROR ;
- if ((psf->rsrcdes = psf_open_fd (psf->rsrcpath, open_mode)) >= 0)
- { psf->rsrclength = psf_get_filelen_fd (psf->rsrcdes) ;
- if (psf->rsrclength > 0 || (open_mode & SFM_WRITE))
+ if ((psf->rsrc.filedes = psf_open_fd (&psf->rsrc)) >= 0)
+ { psf->rsrclength = psf_get_filelen_fd (psf->rsrc.filedes) ;
+ if (psf->rsrclength > 0 || (psf->rsrc.mode & SFM_WRITE))
return SFE_NO_ERROR ;
- psf_close_fd (psf->rsrcdes) ;
- psf->rsrcdes = -1 ;
+ psf_close_fd (psf->rsrc.filedes) ;
+ psf->rsrc.filedes = -1 ;
} ;
- if (psf->rsrcdes == - SFE_BAD_OPEN_MODE)
+ if (psf->rsrc.filedes == - SFE_BAD_OPEN_MODE)
{ psf->error = SFE_BAD_OPEN_MODE ;
return psf->error ;
} ;
** Now try for a resource fork stored as a separate file in the same
** directory, but preceded with a dot underscore.
*/
- snprintf (psf->rsrcpath, sizeof (psf->rsrcpath), "%s._%s", psf->directory, psf->filename) ;
+ snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s._%s", psf->file.dir.c, psf->file.name.c) ;
psf->error = SFE_NO_ERROR ;
- if ((psf->rsrcdes = psf_open_fd (psf->rsrcpath, open_mode)) >= 0)
- { psf->rsrclength = psf_get_filelen_fd (psf->rsrcdes) ;
+ if ((psf->rsrc.filedes = psf_open_fd (&psf->rsrc)) >= 0)
+ { psf->rsrclength = psf_get_filelen_fd (psf->rsrc.filedes) ;
return SFE_NO_ERROR ;
} ;
** Now try for a resource fork stored in a separate file in the
** .AppleDouble/ directory.
*/
- snprintf (psf->rsrcpath, sizeof (psf->rsrcpath), "%s.AppleDouble/%s", psf->directory, psf->filename) ;
+ snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s.AppleDouble/%s", psf->file.dir.c, psf->file.name.c) ;
psf->error = SFE_NO_ERROR ;
- if ((psf->rsrcdes = psf_open_fd (psf->rsrcpath, open_mode)) >= 0)
- { psf->rsrclength = psf_get_filelen_fd (psf->rsrcdes) ;
+ if ((psf->rsrc.filedes = psf_open_fd (&psf->rsrc)) >= 0)
+ { psf->rsrclength = psf_get_filelen_fd (psf->rsrc.filedes) ;
return SFE_NO_ERROR ;
} ;
/* No resource file found. */
- if (psf->rsrcdes == -1)
+ if (psf->rsrc.filedes == -1)
psf_log_syserr (psf, errno) ;
- psf->rsrcdes = -1 ;
+ psf->rsrc.filedes = -1 ;
return psf->error ;
} /* psf_open_rsrc */
if (psf->virtual_io)
return psf->vio.get_filelen (psf->vio_user_data) ;
- filelen = psf_get_filelen_fd (psf->filedes) ;
+ filelen = psf_get_filelen_fd (psf->file.filedes) ;
if (filelen == -1)
{ psf_log_syserr (psf, errno) ;
return (sf_count_t) -1 ;
} ;
- switch (psf->mode)
+ switch (psf->file.mode)
{ case SFM_WRITE :
filelen = filelen - psf->fileoffset ;
break ;
int
psf_close_rsrc (SF_PRIVATE *psf)
-{
- if (psf->rsrcdes >= 0)
- psf_close_fd (psf->rsrcdes) ;
- psf->rsrcdes = -1 ;
+{ psf_close_fd (psf->rsrc.filedes) ;
+ psf->rsrc.filedes = -1 ;
return 0 ;
} /* psf_close_rsrc */
int
-psf_set_stdio (SF_PRIVATE *psf, int mode)
+psf_set_stdio (SF_PRIVATE *psf)
{ int error = 0 ;
- switch (mode)
+ switch (psf->file.mode)
{ case SFM_RDWR :
error = SFE_OPEN_PIPE_RDWR ;
break ;
case SFM_READ :
- psf->filedes = 0 ;
+ psf->file.filedes = 0 ;
break ;
case SFM_WRITE :
- psf->filedes = 1 ;
+ psf->file.filedes = 1 ;
break ;
default :
void
psf_set_file (SF_PRIVATE *psf, int fd)
-{ psf->filedes = fd ;
+{ psf->file.filedes = fd ;
} /* psf_set_file */
int
psf_file_valid (SF_PRIVATE *psf)
-{ return (psf->filedes >= 0) ? SF_TRUE : SF_FALSE ;
+{ return (psf->file.filedes >= 0) ? SF_TRUE : SF_FALSE ;
} /* psf_set_file */
sf_count_t
psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence)
-{ sf_count_t new_position ;
+{ sf_count_t current_pos, new_position ;
if (psf->virtual_io)
return psf->vio.seek (offset, whence, psf->vio_user_data) ;
+ current_pos = psf_ftell (psf) ;
+
switch (whence)
{ case SEEK_SET :
offset += psf->fileoffset ;
break ;
case SEEK_END :
- if (psf->mode == SFM_WRITE)
- { new_position = lseek (psf->filedes, offset, whence) ;
+ if (psf->file.mode == SFM_WRITE)
+ { new_position = lseek (psf->file.filedes, offset, whence) ;
if (new_position < 0)
psf_log_syserr (psf, errno) ;
** get the offset wrt the start of file.
*/
whence = SEEK_SET ;
- offset = lseek (psf->filedes, 0, SEEK_END) + offset ;
+ offset = lseek (psf->file.filedes, 0, SEEK_END) + offset ;
break ;
- default :
- /* No need to do anything about SEEK_CUR. */
+ case SEEK_CUR :
+ /* Translate a SEEK_CUR into a SEEK_SET. */
+ offset += current_pos ;
+ whence = SEEK_SET ;
break ;
+
+ default :
+ /* We really should not be here. */
+ psf_log_printf (psf, "psf_fseek : whence is %d *****.\n", whence) ;
+ return 0 ;
} ;
- new_position = lseek (psf->filedes, offset, whence) ;
+ if (current_pos != offset)
+ new_position = lseek (psf->file.filedes, offset, whence) ;
+ else
+ new_position = offset ;
if (new_position < 0)
psf_log_syserr (psf, errno) ;
{ /* Break the read down to a sensible size. */
count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ;
- count = read (psf->filedes, ((char*) ptr) + total, (size_t) count) ;
+ count = read (psf->file.filedes, ((char*) ptr) + total, (size_t) count) ;
if (count == -1)
{ if (errno == EINTR)
{ /* Break the writes down to a sensible size. */
count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : items ;
- count = write (psf->filedes, ((const char*) ptr) + total, count) ;
+ count = write (psf->file.filedes, ((const char*) ptr) + total, count) ;
if (count == -1)
{ if (errno == EINTR)
if (psf->is_pipe)
return psf->pipeoffset ;
- pos = lseek (psf->filedes, 0, SEEK_CUR) ;
+ pos = lseek (psf->file.filedes, 0, SEEK_CUR) ;
if (pos == ((sf_count_t) -1))
{ psf_log_syserr (psf, errno) ;
psf_close_fd (int fd)
{ int retval ;
+ if (fd < 0)
+ return 0 ;
+
while ((retval = close (fd)) == -1 && errno == EINTR)
/* Do nothing. */ ;
sf_count_t count ;
while (k < bufsize - 1)
- { count = read (psf->filedes, &(buffer [k]), 1) ;
+ { count = read (psf->file.filedes, &(buffer [k]), 1) ;
if (count == -1)
{ if (errno == EINTR)
if (psf->virtual_io)
return SF_FALSE ;
- if (fstat (psf->filedes, &statbuf) == -1)
+ if (fstat (psf->file.filedes, &statbuf) == -1)
{ psf_log_syserr (psf, errno) ;
/* Default to maximum safety. */
return SF_TRUE ;
if ((sizeof (off_t) < sizeof (sf_count_t)) && len > 0x7FFFFFFF)
return -1 ;
- retval = ftruncate (psf->filedes, len) ;
+ retval = ftruncate (psf->file.filedes, len) ;
if (retval == -1)
psf_log_syserr (psf, errno) ;
void
psf_init_files (SF_PRIVATE *psf)
-{ psf->filedes = -1 ;
- psf->rsrcdes = -1 ;
- psf->savedes = -1 ;
+{ psf->file.filedes = -1 ;
+ psf->rsrc.filedes = -1 ;
+ psf->file.savedes = -1 ;
} /* psf_init_files */
void
psf_use_rsrc (SF_PRIVATE *psf, int on_off)
{
if (on_off)
- { if (psf->filedes != psf->rsrcdes)
- { psf->savedes = psf->filedes ;
- psf->filedes = psf->rsrcdes ;
+ { if (psf->file.filedes != psf->rsrc.filedes)
+ { psf->file.savedes = psf->file.filedes ;
+ psf->file.filedes = psf->rsrc.filedes ;
} ;
}
- else if (psf->filedes == psf->rsrcdes)
- psf->filedes = psf->savedes ;
+ else if (psf->file.filedes == psf->rsrc.filedes)
+ psf->file.filedes = psf->file.savedes ;
return ;
} /* psf_use_rsrc */
static int
-psf_open_fd (const char * pathname, int open_mode)
+psf_open_fd (PSF_FILE * pfile)
{ int fd, oflag, mode ;
/*
exit (1) ;
} ;
- switch (open_mode)
+ switch (pfile->mode)
{ case SFM_READ :
oflag = O_RDONLY | O_BINARY ;
mode = 0 ;
} ;
if (mode == 0)
- fd = open (pathname, oflag) ;
+ fd = open (pfile->path.c, oflag) ;
else
- fd = open (pathname, oflag, mode) ;
+ fd = open (pfile->path.c, oflag, mode) ;
return fd ;
} /* psf_open_fd */
psf_fsync (SF_PRIVATE *psf)
{
#if HAVE_FSYNC
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
- fsync (psf->filedes) ;
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
+ fsync (psf->file.filedes) ;
#else
psf = NULL ;
#endif
#include <io.h>
static int psf_close_handle (HANDLE handle) ;
-static HANDLE psf_open_handle (const char * path, int mode) ;
+static HANDLE psf_open_handle (PSF_FILE * pfile) ;
static sf_count_t psf_get_filelen_handle (HANDLE handle) ;
/* USE_WINDOWS_API */ int
-psf_fopen (SF_PRIVATE *psf, const char *pathname, int open_mode)
+psf_fopen (SF_PRIVATE *psf)
{
psf->error = 0 ;
- psf->hfile = psf_open_handle (pathname, open_mode) ;
+ psf->file.handle = psf_open_handle (&psf->file) ;
- if (psf->hfile == NULL)
+ if (psf->file.handle == NULL)
psf_log_syserr (psf, GetLastError ()) ;
- psf->mode = open_mode ;
-
return psf->error ;
} /* psf_fopen */
if (psf->virtual_io)
return 0 ;
- if (psf->do_not_close_descriptor)
- { psf->hfile = NULL ;
+ if (psf->file.do_not_close_descriptor)
+ { psf->file.handle = NULL ;
return 0 ;
} ;
- if ((retval = psf_close_handle (psf->hfile)) == -1)
+ if ((retval = psf_close_handle (psf->file.handle)) == -1)
psf_log_syserr (psf, GetLastError ()) ;
- psf->hfile = NULL ;
+ psf->file.handle = NULL ;
return retval ;
} /* psf_fclose */
/* USE_WINDOWS_API */ int
-psf_open_rsrc (SF_PRIVATE *psf, int open_mode)
+psf_open_rsrc (SF_PRIVATE *psf)
{
- if (psf->hrsrc != NULL)
+ if (psf->rsrc.handle != NULL)
return 0 ;
/* Test for MacOSX style resource fork on HPFS or HPFS+ filesystems. */
- snprintf (psf->rsrcpath, sizeof (psf->rsrcpath), "%s/rsrc", psf->filepath) ;
+ snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s/rsrc", psf->file.path.c) ;
psf->error = SFE_NO_ERROR ;
- if ((psf->hrsrc = psf_open_handle (psf->rsrcpath, open_mode)) != NULL)
- { psf->rsrclength = psf_get_filelen_handle (psf->hrsrc) ;
+ if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != NULL)
+ { psf->rsrclength = psf_get_filelen_handle (psf->rsrc.handle) ;
return SFE_NO_ERROR ;
} ;
** Now try for a resource fork stored as a separate file in the same
** directory, but preceded with a dot underscore.
*/
- snprintf (psf->rsrcpath, sizeof (psf->rsrcpath), "%s._%s", psf->directory, psf->filename) ;
+ snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s._%s", psf->file.dir.c, psf->file.name.c) ;
psf->error = SFE_NO_ERROR ;
- if ((psf->hrsrc = psf_open_handle (psf->rsrcpath, open_mode)) != NULL)
- { psf->rsrclength = psf_get_filelen_handle (psf->hrsrc) ;
+ if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != NULL)
+ { psf->rsrclength = psf_get_filelen_handle (psf->rsrc.handle) ;
return SFE_NO_ERROR ;
} ;
** Now try for a resource fork stored in a separate file in the
** .AppleDouble/ directory.
*/
- snprintf (psf->rsrcpath, sizeof (psf->rsrcpath), "%s.AppleDouble/%s", psf->directory, psf->filename) ;
+ snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s.AppleDouble/%s", psf->file.dir.c, psf->file.name.c) ;
psf->error = SFE_NO_ERROR ;
- if ((psf->hrsrc = psf_open_handle (psf->rsrcpath, open_mode)) != NULL)
- { psf->rsrclength = psf_get_filelen_handle (psf->hrsrc) ;
- return SFE_NO_ERROR ;
+ if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != NULL)
+ { psf->rsrclength = psf_get_filelen_handle (psf->rsrc.handle) ;
+ return SFE_NO_ERROR ;
} ;
/* No resource file found. */
- if (psf->hrsrc == NULL)
+ if (psf->rsrc.handle == NULL)
psf_log_syserr (psf, GetLastError ()) ;
- psf->hrsrc = NULL ;
+ psf->rsrc.handle = NULL ;
return psf->error ;
} /* psf_open_rsrc */
if (psf->virtual_io)
return psf->vio.get_filelen (psf->vio_user_data) ;
- filelen = psf_get_filelen_handle (psf->hfile) ;
+ filelen = psf_get_filelen_handle (psf->file.handle) ;
if (filelen == -1)
{ psf_log_syserr (psf, errno) ;
return (sf_count_t) -1 ;
} ;
- switch (psf->mode)
+ switch (psf->file.mode)
{ case SFM_WRITE :
filelen = filelen - psf->fileoffset ;
break ;
/* USE_WINDOWS_API */ void
psf_init_files (SF_PRIVATE *psf)
-{ psf->hfile = NULL ;
- psf->hrsrc = NULL ;
- psf->hsaved = NULL ;
+{ psf->file.handle = NULL ;
+ psf->rsrc.handle = NULL ;
+ psf->file.hsaved = NULL ;
} /* psf_init_files */
/* USE_WINDOWS_API */ void
psf_use_rsrc (SF_PRIVATE *psf, int on_off)
{
if (on_off)
- { if (psf->hfile != psf->hrsrc)
- { psf->hsaved = psf->hfile ;
- psf->hfile = psf->hrsrc ;
+ { if (psf->file.handle != psf->rsrc.handle)
+ { psf->file.hsaved = psf->file.handle ;
+ psf->file.handle = psf->rsrc.handle ;
} ;
}
- else if (psf->hfile == psf->hrsrc)
- psf->hfile = psf->hsaved ;
+ else if (psf->file.handle == psf->rsrc.handle)
+ psf->file.handle = psf->file.hsaved ;
return ;
} /* psf_use_rsrc */
/* USE_WINDOWS_API */ static HANDLE
-psf_open_handle (const char * pathname, int open_mode)
+psf_open_handle (PSF_FILE * pfile)
{ DWORD dwDesiredAccess ;
DWORD dwShareMode ;
DWORD dwCreationDistribution ;
HANDLE handle ;
- switch (open_mode)
+ switch (pfile->mode)
{ case SFM_READ :
dwDesiredAccess = GENERIC_READ ;
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE ;
return NULL ;
} ;
- handle = CreateFile (
- pathname, /* pointer to name of the file */
- dwDesiredAccess, /* access (read-write) mode */
- dwShareMode, /* share mode */
- 0, /* pointer to security attributes */
- dwCreationDistribution, /* how to create */
- FILE_ATTRIBUTE_NORMAL, /* file attributes (could use FILE_FLAG_SEQUENTIAL_SCAN) */
- NULL /* handle to file with attributes to copy */
- ) ;
+ if (pfile->use_wchar)
+ handle = CreateFileW (
+ pfile->path.wc, /* pointer to name of the file */
+ dwDesiredAccess, /* access (read-write) mode */
+ dwShareMode, /* share mode */
+ 0, /* pointer to security attributes */
+ dwCreationDistribution, /* how to create */
+ FILE_ATTRIBUTE_NORMAL, /* file attributes (could use FILE_FLAG_SEQUENTIAL_SCAN) */
+ NULL /* handle to file with attributes to copy */
+ ) ;
+ else
+ handle = CreateFile (
+ pfile->path.c, /* pointer to name of the file */
+ dwDesiredAccess, /* access (read-write) mode */
+ dwShareMode, /* share mode */
+ 0, /* pointer to security attributes */
+ dwCreationDistribution, /* how to create */
+ FILE_ATTRIBUTE_NORMAL, /* file attributes (could use FILE_FLAG_SEQUENTIAL_SCAN) */
+ NULL /* handle to file with attributes to copy */
+ ) ;
if (handle == INVALID_HANDLE_VALUE)
return NULL ;
/* USE_WINDOWS_API */ int
psf_close_rsrc (SF_PRIVATE *psf)
-{
- if (psf->hrsrc != NULL)
- psf_close_handle (psf->hrsrc) ;
- psf->hrsrc = NULL ;
+{ psf_close_handle (psf->rsrc.handle) ;
+ psf->rsrc.handle = NULL ;
return 0 ;
} /* psf_close_rsrc */
/* USE_WINDOWS_API */ int
-psf_set_stdio (SF_PRIVATE *psf, int mode)
+psf_set_stdio (SF_PRIVATE *psf)
{ HANDLE handle = NULL ;
int error = 0 ;
- switch (mode)
+ switch (psf->file.mode)
{ case SFM_RDWR :
error = SFE_OPEN_PIPE_RDWR ;
break ;
case SFM_READ :
handle = GetStdHandle (STD_INPUT_HANDLE) ;
- psf->do_not_close_descriptor = 1 ;
+ psf->file.do_not_close_descriptor = 1 ;
break ;
case SFM_WRITE :
handle = GetStdHandle (STD_OUTPUT_HANDLE) ;
- psf->do_not_close_descriptor = 1 ;
+ psf->file.do_not_close_descriptor = 1 ;
break ;
default :
break ;
} ;
- psf->hfile = handle ;
+ psf->file.handle = handle ;
psf->filelength = 0 ;
return error ;
osfhandle = _get_osfhandle (fd) ;
handle = (HANDLE) osfhandle ;
- psf->hfile = handle ;
+ psf->file.handle = handle ;
} /* psf_set_file */
/* USE_WINDOWS_API */ int
psf_file_valid (SF_PRIVATE *psf)
-{ if (psf->hfile == NULL)
+{ if (psf->file.handle == NULL)
return SF_FALSE ;
- if (psf->hfile == INVALID_HANDLE_VALUE)
+ if (psf->file.handle == INVALID_HANDLE_VALUE)
return SF_FALSE ;
return SF_TRUE ;
} /* psf_set_file */
lDistanceToMove = (DWORD) (offset & 0xFFFFFFFF) ;
lDistanceToMoveHigh = (DWORD) ((offset >> 32) & 0xFFFFFFFF) ;
- dwResult = SetFilePointer (psf->hfile, lDistanceToMove, &lDistanceToMoveHigh, dwMoveMethod) ;
+ dwResult = SetFilePointer (psf->file.handle, lDistanceToMove, &lDistanceToMoveHigh, dwMoveMethod) ;
if (dwResult == 0xFFFFFFFF)
dwError = GetLastError () ;
{ /* Break the writes down to a sensible size. */
count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ;
- if (ReadFile (psf->hfile, ((char*) ptr) + total, count, &dwNumberOfBytesRead, 0) == 0)
+ if (ReadFile (psf->file.handle, ((char*) ptr) + total, count, &dwNumberOfBytesRead, 0) == 0)
{ psf_log_syserr (psf, GetLastError ()) ;
break ;
}
{ /* Break the writes down to a sensible size. */
count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ;
- if (WriteFile (psf->hfile, ((const char*) ptr) + total, count, &dwNumberOfBytesWritten, 0) == 0)
+ if (WriteFile (psf->file.handle, ((const char*) ptr) + total, count, &dwNumberOfBytesWritten, 0) == 0)
{ psf_log_syserr (psf, GetLastError ()) ;
break ;
}
lDistanceToMoveLow = 0 ;
lDistanceToMoveHigh = 0 ;
- dwResult = SetFilePointer (psf->hfile, lDistanceToMoveLow, &lDistanceToMoveHigh, FILE_CURRENT) ;
+ dwResult = SetFilePointer (psf->file.handle, lDistanceToMoveLow, &lDistanceToMoveHigh, FILE_CURRENT) ;
if (dwResult == 0xFFFFFFFF)
dwError = GetLastError () ;
/* USE_WINDOWS_API */ static int
psf_close_handle (HANDLE handle)
-{ if (CloseHandle (handle) == 0)
+{ if (handle == NULL)
+ return 0 ;
+
+ if (CloseHandle (handle) == 0)
return -1 ;
return 0 ;
DWORD dwNumberOfBytesRead ;
while (k < bufsize - 1)
- { if (ReadFile (psf->hfile, &(buffer [k]), 1, &dwNumberOfBytesRead, 0) == 0)
+ { if (ReadFile (psf->file.handle, &(buffer [k]), 1, &dwNumberOfBytesRead, 0) == 0)
{ psf_log_syserr (psf, GetLastError ()) ;
break ;
}
if (psf->virtual_io)
return SF_FALSE ;
- if (GetFileType (psf->hfile) == FILE_TYPE_DISK)
+ if (GetFileType (psf->file.handle) == FILE_TYPE_DISK)
return SF_FALSE ;
/* Default to maximum safety. */
/* USE_WINDOWS_API */ void
psf_fsync (SF_PRIVATE *psf)
-{ FlushFileBuffers (psf->hfile) ;
+{ FlushFileBuffers (psf->file.handle) ;
} /* psf_fsync */
lDistanceToMoveLow = (DWORD) (len & 0xFFFFFFFF) ;
lDistanceToMoveHigh = (DWORD) ((len >> 32) & 0xFFFFFFFF) ;
- dwResult = SetFilePointer (psf->hfile, lDistanceToMoveLow, &lDistanceToMoveHigh, FILE_BEGIN) ;
+ dwResult = SetFilePointer (psf->file.handle, lDistanceToMoveLow, &lDistanceToMoveHigh, FILE_BEGIN) ;
if (dwResult == 0xFFFFFFFF)
dwError = GetLastError () ;
** which guarantees that the new portion of the file will be zeroed.
** Not sure if this is important or not.
*/
- if (SetEndOfFile (psf->hfile) == 0)
+ if (SetEndOfFile (psf->file.handle) == 0)
{ retval = -1 ;
psf_log_syserr (psf, GetLastError ()) ;
} ;
} ;
if (mode == 0)
- psf->filedes = open (pathname, oflag) ;
+ psf->file.filedes = open (pathname, oflag) ;
else
- psf->filedes = open (pathname, oflag, mode) ;
+ psf->file.filedes = open (pathname, oflag, mode) ;
- if (psf->filedes == -1)
+ if (psf->file.filedes == -1)
psf_log_syserr (psf, errno) ;
- return psf->filedes ;
+ return psf->file.filedes ;
} /* psf_fopen */
/* Win32 */ sf_count_t
break ;
case SEEK_END :
- if (psf->mode == SFM_WRITE)
- { new_position = _lseeki64 (psf->filedes, offset, whence) ;
+ if (psf->file.mode == SFM_WRITE)
+ { new_position = _lseeki64 (psf->file.filedes, offset, whence) ;
if (new_position < 0)
psf_log_syserr (psf, errno) ;
** get the offset wrt the start of file.
*/
whence = SEEK_SET ;
- offset = _lseeki64 (psf->filedes, 0, SEEK_END) + offset ;
+ offset = _lseeki64 (psf->file.filedes, 0, SEEK_END) + offset ;
break ;
default :
*** Use the _telli64() function instead.
*/
if (offset == 0 && whence == SEEK_CUR)
- new_position = _telli64 (psf->filedes) ;
+ new_position = _telli64 (psf->file.filedes) ;
else
- new_position = _lseeki64 (psf->filedes, offset, whence) ;
+ new_position = _lseeki64 (psf->file.filedes, offset, whence) ;
if (new_position < 0)
psf_log_syserr (psf, errno) ;
{ /* Break the writes down to a sensible size. */
count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ;
- count = read (psf->filedes, ((char*) ptr) + total, (size_t) count) ;
+ count = read (psf->file.filedes, ((char*) ptr) + total, (size_t) count) ;
if (count == -1)
{ if (errno == EINTR)
{ /* Break the writes down to a sensible size. */
count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : items ;
- count = write (psf->filedes, ((const char*) ptr) + total, count) ;
+ count = write (psf->file.filedes, ((const char*) ptr) + total, count) ;
if (count == -1)
{ if (errno == EINTR)
if (psf->virtual_io)
return psf->vio.tell (psf->vio_user_data) ;
- pos = _telli64 (psf->filedes) ;
+ pos = _telli64 (psf->file.filedes) ;
if (pos == ((sf_count_t) -1))
{ psf_log_syserr (psf, errno) ;
psf_fclose (SF_PRIVATE *psf)
{ int retval ;
- while ((retval = close (psf->filedes)) == -1 && errno == EINTR)
+ while ((retval = close (psf->file.filedes)) == -1 && errno == EINTR)
/* Do nothing. */ ;
if (retval == -1)
psf_log_syserr (psf, errno) ;
- psf->filedes = -1 ;
+ psf->file.filedes = -1 ;
return retval ;
} /* psf_fclose */
sf_count_t count ;
while (k < bufsize - 1)
- { count = read (psf->filedes, &(buffer [k]), 1) ;
+ { count = read (psf->file.filedes, &(buffer [k]), 1) ;
if (count == -1)
{ if (errno == EINTR)
return SF_FALSE ;
/* Not sure if this works. */
- if (fstat (psf->filedes, &statbuf) == -1)
+ if (fstat (psf->file.filedes, &statbuf) == -1)
{ psf_log_syserr (psf, errno) ;
/* Default to maximum safety. */
return SF_TRUE ;
*/
struct _stati64 statbuf ;
- if (_fstati64 (psf->filedes, &statbuf))
+ if (_fstati64 (psf->file.filedes, &statbuf))
{ psf_log_syserr (psf, errno) ;
return (sf_count_t) -1 ;
} ;
if (psf->virtual_io)
return psf->vio.get_filelen (psf->vio_user_data) ;
- if ((current = _telli64 (psf->filedes)) < 0)
+ if ((current = _telli64 (psf->file.filedes)) < 0)
{ psf_log_syserr (psf, errno) ;
return (sf_count_t) -1 ;
} ;
** by libsndfile and changing the license to GPL at the same time.
*/
- _lseeki64 (psf->filedes, 0, SEEK_END) ;
+ _lseeki64 (psf->file.filedes, 0, SEEK_END) ;
- if ((filelen = _lseeki64 (psf->filedes, 0, SEEK_END)) < 0)
+ if ((filelen = _lseeki64 (psf->file.filedes, 0, SEEK_END)) < 0)
{ psf_log_syserr (psf, errno) ;
return (sf_count_t) -1 ;
} ;
if (filelen > current)
- _lseeki64 (psf->filedes, current, SEEK_SET) ;
+ _lseeki64 (psf->file.filedes, current, SEEK_SET) ;
- switch (psf->mode)
+ switch (psf->file.mode)
{ case SFM_WRITE :
filelen = filelen - psf->fileoffset ;
break ;
if (len > 0x7FFFFFFF)
return -1 ;
- retval = chsize (psf->filedes, len) ;
+ retval = chsize (psf->file.filedes, len) ;
if (retval == -1)
psf_log_syserr (psf, errno) ;
/*
-** Copyright (C) 2004-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2004-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2004 Tobias Gehrig <tgehrig@ira.uka.de>
**
** This program is free software ; you can redistribute it and/or modify
#include <FLAC/stream_encoder.h>
#include <FLAC/metadata.h>
-#include "sfendian.h"
-
/*------------------------------------------------------------------------------
** Private static functions.
*/
static FLAC__StreamEncoderTellStatus sf_flac_enc_tell_callback (const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) ;
static FLAC__StreamEncoderWriteStatus sf_flac_enc_write_callback (const FLAC__StreamEncoder *encoder, const FLAC__byte buffer [], size_t bytes, unsigned samples, unsigned current_frame, void *client_data) ;
-static const int legal_sample_rates [] =
-{ 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000
-} ;
-
static void
s2flac8_array (const short *src, FLAC__int32 *dest, int count)
{ while (--count >= 0)
{ "comment", SF_STR_COMMENT },
{ "date", SF_STR_DATE },
{ "album", SF_STR_ALBUM },
- { "license", SF_STR_LICENSE }
+ { "license", SF_STR_LICENSE },
+ { "tracknumber", SF_STR_TRACKNUMBER },
+ { "genre", SF_STR_GENRE }
} ;
const char *value, *cptr ;
psf->sf.samplerate = metadata->data.stream_info.sample_rate ;
psf->sf.frames = metadata->data.stream_info.total_samples ;
- psf_log_printf (psf, "FLAC Stream Metadata\n Channels : %d\n Sample rate : %d\n Frames : %D\n", psf->sf.channels, psf->sf.samplerate, psf->sf.frames) ;
+ psf_log_printf (psf, "FLAC Stream Metadata\n Channels : %d\n Sample rate : %d\n", psf->sf.channels, psf->sf.samplerate) ;
+
+ if (psf->sf.frames == 0)
+ { psf_log_printf (psf, " Frames : 0 (bumping to SF_COUNT_MAX)\n") ;
+ psf->sf.frames = SF_COUNT_MAX ;
+ }
+ else
+ psf_log_printf (psf, " Frames : %D\n", psf->sf.frames) ;
switch (metadata->data.stream_info.bits_per_sample)
{ case 8 :
case SF_STR_LICENSE :
key = "license" ;
break ;
+ case SF_STR_TRACKNUMBER :
+ key = "tracknumber" ;
+ break ;
+ case SF_STR_GENRE :
+ key = "genre" ;
+ break ;
default :
continue ;
} ;
FLAC_PRIVATE* pflac = calloc (1, sizeof (FLAC_PRIVATE)) ;
psf->codec_data = pflac ;
- if (psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ if ((error = flac_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_FLAC)
return SFE_BAD_OPEN_FORMAT ;
if (pflac->metadata != NULL)
FLAC__metadata_object_delete (pflac->metadata) ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ FLAC__stream_encoder_finish (pflac->fse) ;
FLAC__stream_encoder_delete (pflac->fse) ;
free (pflac->encbuffer) ;
} ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ FLAC__stream_decoder_finish (pflac->fsd) ;
FLAC__stream_decoder_delete (pflac->fsd) ;
} ;
flac_enc_init (SF_PRIVATE *psf)
{ FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
unsigned bps ;
- int k, found ;
- found = 0 ;
- for (k = 0 ; k < ARRAY_LEN (legal_sample_rates) ; k++)
- if (psf->sf.samplerate == legal_sample_rates [k])
- { found = 1 ;
- break ;
- } ;
-
- if (found == 0)
+ /* To cite the flac FAQ at
+ ** http://flac.sourceforge.net/faq.html#general__samples
+ ** "FLAC supports linear sample rates from 1Hz - 655350Hz in 1Hz
+ ** increments."
+ */
+ if ( psf->sf.samplerate < 1 || psf->sf.samplerate > 655350 )
+ { psf_log_printf (psf, "flac sample rate out of range.\n", psf->sf.samplerate) ;
return SFE_FLAC_BAD_SAMPLE_RATE ;
+ } ;
psf_fseek (psf, 0, SEEK_SET) ;
int
flac_init (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ psf->read_short = flac_read_flac2s ;
psf->read_int = flac_read_flac2i ;
psf->read_float = flac_read_flac2f ;
psf->read_double = flac_read_flac2d ;
} ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ psf->write_short = flac_write_s2flac ;
psf->write_int = flac_write_i2flac ;
psf->write_float = flac_write_f2flac ;
pflac->frame = NULL ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ FLAC__uint64 position ;
if (FLAC__stream_decoder_seek_absolute (pflac->fsd, offset))
{ FLAC__stream_decoder_get_decode_position (pflac->fsd, &position) ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
psf->blockwidth = sizeof (float) * psf->sf.channels ;
- if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
{ switch (psf->endian + float_caps)
{ case (SF_ENDIAN_BIG + FLOAT_CAN_RW_BE) :
psf->data_endswap = SF_FALSE ;
} ;
} ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ switch (psf->endian + float_caps)
{ case (SF_ENDIAN_LITTLE + FLOAT_CAN_RW_LE) :
psf->data_endswap = SF_FALSE ;
else
psf->datalength = 0 ;
- psf->sf.frames = psf->datalength / psf->blockwidth ;
+ psf->sf.frames = psf->blockwidth > 0 ? psf->datalength / psf->blockwidth : 0 ;
return 0 ;
} /* float32_init */
if (CPU_CLIPS_POSITIVE == 0 && tmp > 32767.0)
dest [count] = SHRT_MAX ;
- else if (CPU_CLIPS_NEGATIVE == 0 && tmp < 32768.0)
+ else if (CPU_CLIPS_NEGATIVE == 0 && tmp < -32768.0)
dest [count] = SHRT_MIN ;
else
dest [count] = lrintf (tmp) ;
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
- f2s_array (psf->u.fbuf, readcount, ptr + total, scale) ;
+ convert (psf->u.fbuf, readcount, ptr + total, scale) ;
total += readcount ;
if (readcount < bufferlen)
break ;
+++ /dev/null
-/*
-** Copyright (C) 2001-2004 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.
-*/
-
-/* Version 1.4 */
-
-#ifndef FLOAT_CAST_HEADER
-#define FLOAT_CAST_HEADER
-
-/*============================================================================
-** On Intel Pentium processors (especially PIII and probably P4), converting
-** from float to int is very slow. To meet the C specs, the code produced by
-** most C compilers targeting Pentium needs to change the FPU rounding mode
-** before the float to int conversion is performed.
-**
-** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
-** is this flushing of the pipeline which is so slow.
-**
-** Fortunately the ISO C99 specifications define the functions lrint, lrintf,
-** llrint and llrintf which fix this problem as a side effect.
-**
-** On Unix-like systems, the configure process should have detected the
-** presence of these functions. If they weren't found we have to replace them
-** here with a standard C cast.
-*/
-
-/*
-** The C99 prototypes for lrint and lrintf are as follows:
-**
-** long int lrintf (float x) ;
-** long int lrint (double x) ;
-*/
-
-#include "sfconfig.h"
-
-/*
-** The presence of the required functions are detected during the configure
-** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
-** the sfconfig.h file.
-*/
-
-#define HAVE_LRINT_REPLACEMENT 0
-
-#if (HAVE_LRINT && HAVE_LRINTF)
-
- /*
- ** These defines enable functionality introduced with the 1999 ISO C
- ** standard. They must be defined before the inclusion of math.h to
- ** engage them. If optimisation is enabled, these functions will be
- ** inlined. With optimisation switched off, you have to link in the
- ** maths library using -lm.
- */
-
- #define _ISOC9X_SOURCE 1
- #define _ISOC99_SOURCE 1
-
- #define __USE_ISOC9X 1
- #define __USE_ISOC99 1
-
- #include <math.h>
-
-#elif (defined (__CYGWIN__))
-
- #include <math.h>
-
- #undef HAVE_LRINT_REPLACEMENT
- #define HAVE_LRINT_REPLACEMENT 1
-
- #undef lrint
- #undef lrintf
-
- #define lrint double2int
- #define lrintf float2int
-
- /*
- ** The native CYGWIN lrint and lrintf functions are buggy:
- ** http://sourceware.org/ml/cygwin/2005-06/msg00153.html
- ** http://sourceware.org/ml/cygwin/2005-09/msg00047.html
- ** and slow.
- ** These functions (pulled from the Public Domain MinGW math.h header)
- ** replace the native versions.
- */
-
- static inline long double2int (double in)
- { long retval ;
-
- __asm__ __volatile__
- ( "fistpl %0"
- : "=m" (retval)
- : "t" (in)
- : "st"
- ) ;
-
- return retval ;
- } /* double2int */
-
- static inline long float2int (float in)
- { long retval ;
-
- __asm__ __volatile__
- ( "fistpl %0"
- : "=m" (retval)
- : "t" (in)
- : "st"
- ) ;
-
- return retval ;
- } /* float2int */
-
-#elif (defined (WIN32) || defined (_WIN32)) && !defined(_WIN64)
-
- #undef HAVE_LRINT_REPLACEMENT
- #define HAVE_LRINT_REPLACEMENT 1
-
- #include <math.h>
-
- /*
- ** Win32 doesn't seem to have these functions.
- ** Therefore implement inline versions of these functions here.
- */
-
- __inline long int
- lrint (double flt)
- { int intgr ;
-
- _asm
- { fld flt
- fistp intgr
- } ;
-
- return intgr ;
- }
-
- __inline long int
- lrintf (float flt)
- { int intgr ;
-
- _asm
- { fld flt
- fistp intgr
- } ;
-
- return intgr ;
- }
-
-#elif defined(_WIN64)
- __inline long int lrint(double x)
- {
- return (long int) (x);
- }
- __inline long int lrintf(float x)
- {
- return (long int) (x);
- }
-#elif (defined (__MWERKS__) && defined (macintosh))
-
- /* This MacOS 9 solution was provided by Stephane Letz */
-
- #undef HAVE_LRINT_REPLACEMENT
- #define HAVE_LRINT_REPLACEMENT 1
- #include <math.h>
-
- #undef lrint
- #undef lrintf
-
- #define lrint double2int
- #define lrintf float2int
-
- inline int
- float2int (register float in)
- { long res [2] ;
-
- asm
- { fctiw in, in
- stfd in, res
- }
- return res [1] ;
- } /* float2int */
-
- inline int
- double2int (register double in)
- { long res [2] ;
-
- asm
- { fctiw in, in
- stfd in, res
- }
- return res [1] ;
- } /* double2int */
-
-#elif (defined (__MACH__) && defined (__APPLE__))
-
- /* For Apple MacOSX. */
-
- #undef HAVE_LRINT_REPLACEMENT
- #define HAVE_LRINT_REPLACEMENT 1
- #include <math.h>
-
- #undef lrint
- #undef lrintf
-
- #define lrint double2int
- #define lrintf float2int
-
- inline static long
- float2int (register float in)
- { int res [2] ;
-
- __asm__ __volatile__
- ( "fctiw %1, %1\n\t"
- "stfd %1, %0"
- : "=m" (res) /* Output */
- : "f" (in) /* Input */
- : "memory"
- ) ;
-
- return res [1] ;
- } /* lrintf */
-
- inline static long
- double2int (register double in)
- { int res [2] ;
-
- __asm__ __volatile__
- ( "fctiw %1, %1\n\t"
- "stfd %1, %0"
- : "=m" (res) /* Output */
- : "f" (in) /* Input */
- : "memory"
- ) ;
-
- return res [1] ;
- } /* lrint */
-
-#else
- #ifndef __sgi
- #warning "Don't have the functions lrint() and lrintf()."
- #warning "Replacing these functions with a standard C cast."
- #endif
-
- #include <math.h>
-
- #define lrint(dbl) ((long) (dbl))
- #define lrintf(flt) ((long) (flt))
-
-#endif
-
-
-#endif /* FLOAT_CAST_HEADER */
-
-/*
-** 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: 42db1693-ff61-4051-bac1-e4d24c4e30b7
-*/
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
if (psf->dataend > 0)
psf->datalength -= psf->filelength - psf->dataend ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ pg72x->private = g72x_reader_init (codec, &(pg72x->blocksize), &(pg72x->samplesperblock)) ;
if (pg72x->private == NULL)
return SFE_MALLOC_FAILED ;
psf_g72x_decode_block (psf, pg72x) ;
}
- else if (psf->mode == SFM_WRITE)
+ else if (psf->file.mode == SFM_WRITE)
{ pg72x->private = g72x_writer_init (codec, &(pg72x->blocksize), &(pg72x->samplesperblock)) ;
if (pg72x->private == NULL)
return SFE_MALLOC_FAILED ;
** return PSF_SEEK_ERROR ;
** } ;
**
-** if (psf->mode == SFM_READ)
+** if (psf->file.mode == SFM_READ)
** { psf_fseek (psf, psf->dataoffset + newblock * pg72x->blocksize, SEEK_SET) ;
** pg72x->block_curr = newblock ;
** psf_g72x_decode_block (psf, pg72x) ;
pg72x = (G72x_PRIVATE*) psf->codec_data ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ /* If a block has been partially assembled, write it out
** as the final block.
*/
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
return SFE_INTERNAL ;
} ;
- if (psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
psf->sf.seekable = SF_FALSE ;
break ;
} ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ if (psf->datalength % pgsm610->blocksize == 0)
pgsm610->blocks = psf->datalength / pgsm610->blocksize ;
else if (psf->datalength % pgsm610->blocksize == 1 && pgsm610->blocksize == GSM610_BLOCKSIZE)
psf->read_double = gsm610_read_d ;
} ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ pgsm610->blockcount = 0 ;
pgsm610->samplecount = 0 ;
newblock = offset / pgsm610->samplesperblock ;
newsample = offset % pgsm610->samplesperblock ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ if (psf->read_current != newblock * pgsm610->samplesperblock + newsample)
{ psf_fseek (psf, psf->dataoffset + newblock * pgsm610->samplesperblock, SEEK_SET) ;
pgsm610->blockcount = newblock ;
pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ /* If a block has been partially assembled, write it out
** as the final block.
*/
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
if (psf->is_pipe)
return SFE_HTK_NO_PIPE ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = htk_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_HTK)
return SFE_BAD_OPEN_FORMAT ;
static int
htk_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
htk_write_header (psf, SF_TRUE) ;
return 0 ;
return SFE_HTK_NOT_WAVEFORM ;
psf->sf.channels = 1 ;
- psf->sf.samplerate = 10000000 / sample_period ;
- psf_log_printf (psf, "HTK Waveform file\n Sample Count : %d\n Sample Period : %d => %d Hz\n",
- sample_count, sample_period, psf->sf.samplerate) ;
+ if (sample_period > 0)
+ { psf->sf.samplerate = 10000000 / sample_period ;
+ psf_log_printf (psf, "HTK Waveform file\n Sample Count : %d\n Sample Period : %d => %d Hz\n",
+ sample_count, sample_period, psf->sf.samplerate) ;
+ }
+ else
+ { psf->sf.samplerate = 16000 ;
+ psf_log_printf (psf, "HTK Waveform file\n Sample Count : %d\n Sample Period : %d (should be > 0) => Guessed sample rate %d Hz\n",
+ sample_count, sample_period, psf->sf.samplerate) ;
+ } ;
psf->sf.format = SF_FORMAT_HTK | SF_FORMAT_PCM_16 ;
psf->bytewidth = 2 ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
return SFE_INTERNAL ;
} ;
- if (psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
if ((error = ima_reader_init (psf, blockalign, samplesperblock)))
return error ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
if ((error = ima_writer_init (psf, blockalign)))
return error ;
aiff_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
{ int error ;
- if (psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
if ((error = ima_reader_init (psf, blockalign, samplesperblock)))
return error ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
if ((error = ima_writer_init (psf, blockalign)))
return error ;
pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ /* If a block has been partially assembled, write it out
** as the final block.
*/
{ IMA_ADPCM_PRIVATE *pima ;
int pimasize, count ;
- if (psf->mode != SFM_READ)
+ if (psf->file.mode != SFM_READ)
return SFE_BAD_MODE_RW ;
pimasize = sizeof (IMA_ADPCM_PRIVATE) + blockalign * psf->sf.channels + 3 * psf->sf.channels * samplesperblock ;
- if (! (pima = malloc (pimasize)))
+ if (! (pima = calloc (1, pimasize)))
return SFE_MALLOC_FAILED ;
psf->codec_data = (void*) pima ;
- memset (pima, 0, pimasize) ;
-
pima->samples = pima->data ;
pima->block = (unsigned char*) (pima->data + samplesperblock * psf->sf.channels) ;
default :
psf_log_printf (psf, "ima_reader_init: bad psf->sf.format\n") ;
return SFE_INTERNAL ;
- break ;
} ;
pima->decode_block (psf, pima) ; /* Read first block. */
static int
aiff_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
{ unsigned char *blockdata ;
- int chan, k, diff, bytecode ;
- short step, stepindx, predictor, *sampledata ;
+ int chan, k, diff, bytecode, predictor ;
+ short step, stepindx, *sampledata ;
static int count = 0 ;
count ++ ;
if (bytecode & 8) diff = -diff ;
predictor += diff ;
+ if (predictor < -32768)
+ predictor = -32768 ;
+ else if (predictor > 32767)
+ predictor = 32767 ;
+
pima->samples [pima->channels * k + chan] = predictor ;
} ;
} ;
{ blockindx = chan * pima->blocksize + 2 + indx / 2 ;
pima->block [blockindx] = pima->samples [indx] & 0x0F ;
- pima->block [blockindx] |= (pima->samples [indx + pima->channels] << 4) & 0xF0 ;
+ pima->block [blockindx] |= (pima->samples [indx + chan] << 4) & 0xF0 ;
} ;
} ;
static int
wav_w64_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
-{ int chan, k, current, blockindx, indx, indxstart, diff ;
+{ int chan, k, predictor, blockindx, indx, indxstart, diff ;
short step, bytecode, stepindx [2] ;
pima->blockcount ++ ;
/* Read and check the block header. */
for (chan = 0 ; chan < pima->channels ; chan++)
- { current = pima->block [chan*4] | (pima->block [chan*4+1] << 8) ;
- if (current & 0x8000)
- current -= 0x10000 ;
+ { predictor = pima->block [chan*4] | (pima->block [chan*4+1] << 8) ;
+ if (predictor & 0x8000)
+ predictor -= 0x10000 ;
stepindx [chan] = pima->block [chan*4+2] ;
stepindx [chan] = clamp_ima_step_index (stepindx [chan]) ;
if (pima->block [chan*4+3] != 0)
psf_log_printf (psf, "IMA ADPCM synchronisation error.\n") ;
- pima->samples [chan] = current ;
+ pima->samples [chan] = predictor ;
} ;
/*
bytecode = pima->samples [k] & 0xF ;
step = ima_step_size [stepindx [chan]] ;
- current = pima->samples [k - pima->channels] ;
+ predictor = pima->samples [k - pima->channels] ;
diff = step >> 3 ;
if (bytecode & 1)
if (bytecode & 8)
diff = -diff ;
- current += diff ;
+ predictor += diff ;
- if (current > 32767)
- current = 32767 ;
- else if (current < -32768)
- current = -32768 ;
+ if (predictor > 32767)
+ predictor = 32767 ;
+ else if (predictor < -32768)
+ predictor = -32768 ;
stepindx [chan] += ima_indx_adjust [bytecode] ;
stepindx [chan] = clamp_ima_step_index (stepindx [chan]) ;
- pima->samples [k] = current ;
+ pima->samples [k] = predictor ;
} ;
return 1 ;
int samplesperblock ;
unsigned int pimasize ;
- if (psf->mode != SFM_WRITE)
+ if (psf->file.mode != SFM_WRITE)
return SFE_BAD_MODE_RW ;
samplesperblock = 2 * (blockalign - 4 * psf->sf.channels) / psf->sf.channels + 1 ;
default :
psf_log_printf (psf, "ima_reader_init: bad psf->sf.format\n") ;
return SFE_INTERNAL ;
- break ;
} ;
psf->write_short = ima_write_s ;
/*
+** Copyright (C) 2007-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (c) 2007 <robs@users.sourceforge.net>
-** Copyright (C) 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** 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
/* ADPCM: IMA, OKI <==> 16-bit PCM. */
+#include "sfconfig.h"
+
#include <string.h>
/* Set up for libsndfile environment: */
/*
** The codec expects an even number of input samples.
- **
+ **
** Samples should always be passed in even length blocks. If the last block to
** be encoded is odd length, extend that block by one zero valued sample.
*/
/*
+** Copyright (C) 2007-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (c) 2007 <robs@users.sourceforge.net>
-** Copyright (C) 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** 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
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
interleave_init (SF_PRIVATE *psf)
{ INTERLEAVE_DATA *pdata ;
- if (psf->mode != SFM_READ)
+ if (psf->file.mode != SFM_READ)
return SFE_INTERLEAVE_MODE ;
if (psf->interleave)
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
{ int subformat ;
int error = SFE_NO_ERROR ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = ircam_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_IRCAM)
return SFE_BAD_OPEN_FORMAT ;
sf_strerror @50
sf_get_string @60
sf_set_string @61
+sf_version_string @68
sf_open_fd @70
+sf_wchar_open @71
sf_open_virtual @80
sf_write_sync @90
+++ /dev/null
-; Auto-generated by create_symbols_file.py
-
-LIBRARY libsndfile-1.dll
-EXPORTS
-
-sf_command @1
-sf_open @2
-sf_close @3
-sf_seek @4
-sf_error @7
-sf_perror @8
-sf_error_str @9
-sf_error_number @10
-sf_format_check @11
-sf_read_raw @16
-sf_readf_short @17
-sf_readf_int @18
-sf_readf_float @19
-sf_readf_double @20
-sf_read_short @21
-sf_read_int @22
-sf_read_float @23
-sf_read_double @24
-sf_write_raw @32
-sf_writef_short @33
-sf_writef_int @34
-sf_writef_float @35
-sf_writef_double @36
-sf_write_short @37
-sf_write_int @38
-sf_write_float @39
-sf_write_double @40
-sf_strerror @50
-sf_get_string @60
-sf_set_string @61
-sf_open_fd @70
-sf_open_virtual @80
-sf_write_sync @90
-
/*
-** Copyright (C) 2003-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2003-2011 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
/*
-** Copyright (C) 2003-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2003-2011 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
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
mat4_open (SF_PRIVATE *psf)
{ int subformat, error = 0 ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = mat4_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
static int
mat4_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
mat4_write_header (psf, SF_TRUE) ;
return 0 ;
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
mat5_open (SF_PRIVATE *psf)
{ int subformat, error = 0 ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = mat5_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
static int
mat5_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
mat5_write_header (psf, SF_TRUE) ;
return 0 ;
/*
-** Copyright (C) 2008-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2008-2011 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
** 1 byte: loopMode (0 no loop, 1 forward looping)
** 1 byte: number of beat in loop
** 1 uint16: sampleRate
-**
+**
** DATA
** Data are always non compressed 16 bits interleaved
*/
int
mpc2k_open (SF_PRIVATE *psf)
-{ int subformat ;
- int error = 0 ;
+{ int error = 0 ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = mpc2k_read_header (psf)))
return error ;
} ;
if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_MPC2K)
return SFE_BAD_OPEN_FORMAT ;
- subformat = SF_CODEC (psf->sf.format) ;
-
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (mpc2k_write_header (psf, SF_FALSE))
return psf->error ;
static int
mpc2k_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
mpc2k_write_header (psf, SF_TRUE) ;
return 0 ;
if (psf->is_pipe == SF_FALSE)
psf_fseek (psf, 0, SEEK_SET) ;
- snprintf (sample_name, sizeof (sample_name), "%s ", psf->filename) ;
+ snprintf (sample_name, sizeof (sample_name), "%s ", psf->file.name.c) ;
psf_binheader_writef (psf, "e11b", 1, 4, sample_name, make_size_t (HEADER_NAME_LEN)) ;
psf_binheader_writef (psf, "e111", 100, 0, (psf->sf.channels - 1) & 1) ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
return SFE_INTERNAL ;
} ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
samplesperblock = 2 + 2 * (blockalign - 7 * psf->sf.channels) / psf->sf.channels ;
pmssize = sizeof (MSADPCM_PRIVATE) + blockalign + 3 * psf->sf.channels * samplesperblock ;
- if (! (psf->codec_data = malloc (pmssize)))
+ if (! (psf->codec_data = calloc (1, pmssize)))
return SFE_MALLOC_FAILED ;
pms = (MSADPCM_PRIVATE*) psf->codec_data ;
- memset (pms, 0, pmssize) ;
pms->samples = pms->dummydata ;
pms->block = (unsigned char*) (pms->dummydata + psf->sf.channels * samplesperblock) ;
return SFE_INTERNAL ;
} ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ pms->dataremaining = psf->datalength ;
if (psf->datalength % pms->blocksize)
psf->read_double = msadpcm_read_d ;
} ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ pms->samples = pms->dummydata ;
pms->samplecount = 0 ;
pms = (MSADPCM_PRIVATE*) psf->codec_data ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ /* Now we know static int for certain the length of the file we can
** re-write the header.
*/
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
nist_open (SF_PRIVATE *psf)
{ int error ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = nist_read_header (psf)))
return error ;
} ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
static int
nist_read_header (SF_PRIVATE *psf)
{ char *psf_header ;
- int bitwidth = 0, bytes = 0, count, encoding ;
+ int bitwidth = 0, count, encoding ;
+ unsigned bytes = 0 ;
char str [64], *cptr ;
long samples ;
- psf->sf.format = SF_FORMAT_NIST ;
-
psf_header = psf->u.cbuf ;
if (sizeof (psf->header) <= NIST_HEADER_LENGTH)
{ sscanf (cptr, "sample_coding -s%d %63s", &count, str) ;
if (strcmp (str, "pcm") == 0)
+ { /* Correct this later when we find out the bitwidth. */
encoding = SF_FORMAT_PCM_U8 ;
+ }
else if (strcmp (str, "alaw") == 0)
encoding = SF_FORMAT_ALAW ;
else if ((strcmp (str, "ulaw") == 0) || (strcmp (str, "mu-law") == 0))
psf->endian = (CPU_IS_BIG_ENDIAN) ? SF_ENDIAN_BIG : SF_ENDIAN_LITTLE ;
/* This is where we figure out endian-ness. */
- if ((cptr = strstr (psf_header, "sample_byte_format -s")))
- { sscanf (cptr, "sample_byte_format -s%d %8s", &bytes, str) ;
+ if ((cptr = strstr (psf_header, "sample_byte_format -s"))
+ && sscanf (cptr, "sample_byte_format -s%u %8s", &bytes, str) == 2)
+ {
+ if (bytes != strlen (str))
+ psf_log_printf (psf, "Weird sample_byte_format : strlen '%s' != %d\n", str, bytes) ;
+
if (bytes > 1)
{ if (psf->bytewidth == 0)
psf->bytewidth = bytes ;
- else if (psf->bytewidth != bytes)
+ else if (psf->bytewidth - bytes != 0)
{ psf_log_printf (psf, "psf->bytewidth (%d) != bytes (%d)\n", psf->bytewidth, bytes) ;
return SFE_NIST_BAD_ENCODING ;
} ;
- if (strstr (str, "01") == str)
+ if (strcmp (str, "01") == 0)
psf->endian = SF_ENDIAN_LITTLE ;
- else if (strstr (str, "10"))
+ else if (strcmp (str, "10") == 0)
psf->endian = SF_ENDIAN_BIG ;
else
{ psf_log_printf (psf, "Weird endian-ness : %s\n", str) ;
else
return SFE_UNIMPLEMENTED ;
+ /* Sanitize psf->sf.format. */
+ switch (SF_CODEC (psf->sf.format))
+ { case SF_FORMAT_ULAW :
+ case SF_FORMAT_ALAW :
+ case SF_FORMAT_PCM_U8 :
+ /* Blank out endian bits. */
+ psf->sf.format = SF_FORMAT_NIST | SF_CODEC (psf->sf.format) ;
+ break ;
+
+ default :
+ break ;
+ } ;
+
return 0 ;
} /* nist_read_header */
static int
nist_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
nist_write_header (psf, SF_TRUE) ;
return 0 ;
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2007 John ffitch
**
** This program is free software ; you can redistribute it and/or modify
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-/*
-** Much of this code is based on the examples in libvorbis from the
-** XIPHOPHORUS Company http://www.xiph.org/ which has a BSD-style Licence
-** Copyright (c) 2002, Xiph.org Foundation
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions
-** are met:
-**
-** - Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-**
-** - Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-**
-** - Neither the name of the Xiph.org Foundation nor the names of its
-** 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 FOUNDATION
-** 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 <stdio.h>
#if HAVE_EXTERNAL_LIBS
-#include <vorbis/codec.h>
-#include <vorbis/vorbisenc.h>
+#include <ogg/ogg.h>
-typedef int convert_func (int, void *, int, int, float **) ;
+#include "ogg.h"
-static int ogg_read_header (SF_PRIVATE *psf, int log_data) ;
-static int ogg_write_header (SF_PRIVATE *psf, int calc_length) ;
static int ogg_close (SF_PRIVATE *psf) ;
-static int ogg_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
-static sf_count_t ogg_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
-static sf_count_t ogg_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
-static sf_count_t ogg_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
-static sf_count_t ogg_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
-static sf_count_t ogg_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
-static sf_count_t ogg_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
-static sf_count_t ogg_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
-static sf_count_t ogg_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
-static sf_count_t ogg_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
-static sf_count_t ogg_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn) ;
-static sf_count_t ogg_length (SF_PRIVATE *psf) ;
+static int ogg_stream_classify (SF_PRIVATE *psf, OGG_PRIVATE * odata) ;
+static int ogg_page_classify (SF_PRIVATE * psf, const ogg_page * og) ;
-typedef struct
-{ int id ;
- const char *name ;
-} STR_PAIRS ;
+int
+ogg_open (SF_PRIVATE *psf)
+{ OGG_PRIVATE* odata = calloc (1, sizeof (OGG_PRIVATE)) ;
+ sf_count_t pos = psf_ftell (psf) ;
+ int error = 0 ;
-static STR_PAIRS vorbis_metatypes [] =
-{ { SF_STR_TITLE, "Title" },
- { SF_STR_COPYRIGHT, "Copyright" },
- { SF_STR_SOFTWARE, "Software" },
- { SF_STR_ARTIST, "Artist" },
- { SF_STR_COMMENT, "Comment" },
- { SF_STR_DATE, "Date" },
- { SF_STR_ALBUM, "Album" },
- { SF_STR_LICENSE, "License" },
-} ;
+ psf->container_data = odata ;
+ psf->container_close = ogg_close ;
+
+ if (psf->file.mode == SFM_RDWR)
+ return SFE_BAD_MODE_RW ;
+
+ if (psf->file.mode == SFM_READ)
+ if ((error = ogg_stream_classify (psf, odata)) != 0)
+ return error ;
-typedef struct
-{ /* Sync and verify incoming physical bitstream */
- ogg_sync_state oy ;
- /* Take physical pages, weld into a logical stream of packets */
- ogg_stream_state os ;
- /* One Ogg bitstream page. Vorbis packets are inside */
- ogg_page og ;
- /* One raw packet of data for decode */
- ogg_packet op ;
- int eos ;
-} OGG_PRIVATE ;
+ /* Reset everything to an initial state. */
+ ogg_sync_clear (&odata->osync) ;
+ ogg_stream_clear (&odata->ostream) ;
+ psf_fseek (psf, pos, SEEK_SET) ;
-typedef struct
-{ /* Count current location */
- sf_count_t loc ;
- /* Struct that stores all the static vorbis bitstream settings */
- vorbis_info vi ;
- /* Struct that stores all the bitstream user comments */
- vorbis_comment vc ;
- /* Ventral working state for the packet->PCM decoder */
- vorbis_dsp_state vd ;
- /* Local working space for packet->PCM decode */
- vorbis_block vb ;
+ switch (psf->sf.format)
+ { case SF_FORMAT_OGG | SF_FORMAT_VORBIS :
+ return ogg_vorbis_open (psf) ;
+
+ case SF_FORMAT_OGGFLAC :
+ free (psf->container_data) ;
+ psf->container_data = NULL ;
+ psf->container_close = NULL ;
+ return flac_open (psf) ;
+
+#if ENABLE_EXPERIMENTAL_CODE
+ case SF_FORMAT_OGG | SF_FORMAT_SPEEX :
+ return ogg_speex_open (psf) ;
+
+ case SF_FORMAT_OGG | SF_FORMAT_PCM_16 :
+ case SF_FORMAT_OGG | SF_FORMAT_PCM_24 :
+ return ogg_pcm_open (psf) ;
+#endif
+
+ default :
+ break ;
+ } ;
+
+ psf_log_printf (psf, "%s : mode should be SFM_READ or SFM_WRITE.\n", __func__) ;
+ return SFE_INTERNAL ;
+} /* ogg_open */
- /* Encoding quality in range [0.0, 1.0]. */
- double quality ;
-} VORBIS_PRIVATE ;
static int
-ogg_read_header (SF_PRIVATE *psf, int log_data)
-{
- OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
- VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
- char *buffer ;
- int bytes ;
- int i, nn ;
+ogg_close (SF_PRIVATE *psf)
+{ OGG_PRIVATE* odata = psf->container_data ;
+
+ ogg_sync_clear (&odata->osync) ;
+ ogg_stream_clear (&odata->ostream) ;
+
+ return 0 ;
+} /* ogg_close */
+
+static int
+ogg_stream_classify (SF_PRIVATE *psf, OGG_PRIVATE* odata)
+{ char *buffer ;
+ int bytes, nn ;
+
+ /* Call this here so it only gets called once, so no memory is leaked. */
+ ogg_sync_init (&odata->osync) ;
odata->eos = 0 ;
/* Weird stuff happens if these aren't called. */
- ogg_stream_reset (&odata->os) ;
- ogg_sync_reset (&odata->oy) ;
+ ogg_stream_reset (&odata->ostream) ;
+ ogg_sync_reset (&odata->osync) ;
/*
** Grab some data at the head of the stream. We want the first page
*/
/* Expose the buffer */
- buffer = ogg_sync_buffer (&odata->oy, 4096L) ;
+ buffer = ogg_sync_buffer (&odata->osync, 4096L) ;
/* Grab the part of the header that has already been read. */
memcpy (buffer, psf->header, psf->headindex) ;
/* Submit a 4k block to libvorbis' Ogg layer */
bytes += psf_fread (buffer + psf->headindex, 1, 4096 - psf->headindex, psf) ;
- ogg_sync_wrote (&odata->oy, bytes) ;
+ ogg_sync_wrote (&odata->osync, bytes) ;
/* Get the first page. */
- if ((nn = ogg_sync_pageout (&odata->oy, &odata->og)) != 1)
+ if ((nn = ogg_sync_pageout (&odata->osync, &odata->opage)) != 1)
{
/* Have we simply run out of data? If so, we're done. */
if (bytes < 4096)
** Get the serial number and set up the rest of decode.
** Serialno first ; use it to set up a logical stream.
*/
- ogg_stream_clear (&odata->os) ;
- ogg_stream_init (&odata->os, ogg_page_serialno (&odata->og)) ;
+ ogg_stream_clear (&odata->ostream) ;
+ ogg_stream_init (&odata->ostream, ogg_page_serialno (&odata->opage)) ;
- /*
- ** This function (ogg_read_header) gets called multiple times, so the OGG
- ** and vorbis structs have to be cleared every time we pass through to
- ** prevent memory leaks.
- */
- vorbis_block_clear (&vdata->vb) ;
- vorbis_dsp_clear (&vdata->vd) ;
- vorbis_comment_clear (&vdata->vc) ;
- vorbis_info_clear (&vdata->vi) ;
-
- /*
- ** Extract the initial header from the first page and verify that the
- ** Ogg bitstream is in fact Vorbis data.
- **
- ** I handle the initial header first instead of just having the code
- ** read all three Vorbis headers at once because reading the initial
- ** header is an easy way to identify a Vorbis bitstream and it's
- ** useful to see that functionality seperated out.
- */
- vorbis_info_init (&vdata->vi) ;
- vorbis_comment_init (&vdata->vc) ;
-
- if (ogg_stream_pagein (&odata->os, &odata->og) < 0)
+ if (ogg_stream_pagein (&odata->ostream, &odata->opage) < 0)
{ /* Error ; stream version mismatch perhaps. */
psf_log_printf (psf, "Error reading first page of Ogg bitstream data\n") ;
return SFE_MALFORMED_FILE ;
} ;
- if (ogg_stream_packetout (&odata->os, &odata->op) != 1)
+ if (ogg_stream_packetout (&odata->ostream, &odata->opacket) != 1)
{ /* No page? must not be vorbis. */
psf_log_printf (psf, "Error reading initial header packet.\n") ;
return SFE_MALFORMED_FILE ;
} ;
- if (vorbis_synthesis_headerin (&vdata->vi, &vdata->vc, &odata->op) < 0)
- { /* Error case ; not a vorbis header. */
- psf_log_printf (psf, "This Ogg bitstream does not contain Vorbis audio data.\n") ;
- return SFE_MALFORMED_FILE ;
- } ;
-
- /*
- ** Common Ogg metadata fields?
- ** TITLE, VERSION, ALBUM, TRACKNUMBER, ARTIST, PERFORMER, COPYRIGHT, LICENSE,
- ** ORGANIZATION, DESCRIPTION, GENRE, DATE, LOCATION, CONTACT, ISRC,
- */
-
- if (log_data)
- { int k ;
-
- for (k = 0 ; k < ARRAY_LEN (vorbis_metatypes) ; k++)
- { char *dd ;
-
- dd = vorbis_comment_query (&vdata->vc, vorbis_metatypes [k].name, 0) ;
- if (dd == NULL)
- continue ;
- psf_store_string (psf, vorbis_metatypes [k].id, dd) ;
- } ;
- } ;
-
- /*
- ** At this point, we're sure we're Vorbis. We've set up the logical (Ogg)
- ** bitstream decoder. Get the comment and codebook headers and set up the
- ** Vorbis decoder.
- **
- ** The next two packets in order are the comment and codebook headers.
- ** They're likely large and may span multiple pages. Thus we reead
- ** and submit data until we get our two pacakets, watching that no
- ** pages are missing. If a page is missing, error out ; losing a
- ** header page is the only place where missing data is fatal.
- */
-
- i = 0 ; /* Count of number of packets read */
- while (i < 2)
- { int result = ogg_sync_pageout (&odata->oy, &odata->og) ;
- if (result == 0)
- { /* Need more data */
- buffer = ogg_sync_buffer (&odata->oy, 4096) ;
- bytes = psf_fread (buffer, 1, 4096, psf) ;
-
- if (bytes == 0 && i < 2)
- { psf_log_printf (psf, "End of file before finding all Vorbis headers!\n") ;
- return SFE_MALFORMED_FILE ;
- } ;
- nn = ogg_sync_wrote (&odata->oy, bytes) ;
- }
- else if (result == 1)
- { /*
- ** Don't complain about missing or corrupt data yet. We'll
- ** catch it at the packet output phase.
- **
- ** We can ignore any errors here as they'll also become apparent
- ** at packetout.
- */
- nn = ogg_stream_pagein (&odata->os, &odata->og) ;
- while (i < 2)
- { result = ogg_stream_packetout (&odata->os, &odata->op) ;
- if (result == 0)
- break ;
- if (result < 0)
- { /* Uh oh ; data at some point was corrupted or missing!
- ** We can't tolerate that in a header. Die. */
- psf_log_printf (psf, "Corrupt secondary header. Exiting.\n") ;
- return SFE_MALFORMED_FILE ;
- } ;
-
- vorbis_synthesis_headerin (&vdata->vi, &vdata->vc, &odata->op) ;
- i++ ;
- } ;
- } ;
- } ;
-
- if (log_data)
- { int printed_metadata_msg = 0 ;
- int k ;
-
- psf_log_printf (psf, "\nBitstream is %d channel, %D Hz\n", vdata->vi.channels, vdata->vi.rate) ;
- psf_log_printf (psf, "Encoded by: %s\n", vdata->vc.vendor) ;
-
- /* Throw the comments plus a few lines about the bitstream we're decoding. */
- for (k = 0 ; k < ARRAY_LEN (vorbis_metatypes) ; k++)
- { char *dd ;
-
- dd = vorbis_comment_query (&vdata->vc, vorbis_metatypes [k].name, 0) ;
- if (dd == NULL)
- continue ;
-
- if (printed_metadata_msg == 0)
- { psf_log_printf (psf, "Metadata :\n") ;
- printed_metadata_msg = 1 ;
- } ;
-
- psf_store_string (psf, vorbis_metatypes [k].id, dd) ;
- psf_log_printf (psf, " %-10s : %s\n", vorbis_metatypes [k].name, dd) ;
- } ;
-
- psf_log_printf (psf, "End\n") ;
- } ;
-
- psf->sf.samplerate = vdata->vi.rate ;
- psf->sf.channels = vdata->vi.channels ;
- psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
-
- /* OK, got and parsed all three headers. Initialize the Vorbis
- ** packet->PCM decoder.
- ** Central decode state. */
- vorbis_synthesis_init (&vdata->vd, &vdata->vi) ;
-
- /* Local state for most of the decode so multiple block decodes can
- ** proceed in parallel. We could init multiple vorbis_block structures
- ** for vd here. */
- vorbis_block_init (&vdata->vd, &vdata->vb) ;
-
- vdata->loc = 0 ;
-
- return 0 ;
-} /* ogg_read_header */
-
-static int
-ogg_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
-{
- OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
- VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
- int k, ret ;
-
- vorbis_info_init (&vdata->vi) ;
-
- /* The style of encoding should be selectable here, VBR quality mode. */
- ret = vorbis_encode_init_vbr (&vdata->vi, psf->sf.channels, psf->sf.samplerate, vdata->quality) ;
-
-#if 0
- ret = vorbis_encode_init (&vdata->vi, psf->sf.channels, psf->sf.samplerate, -1, 128000, -1) ; /* average bitrate mode */
- ret = ( vorbis_encode_setup_managed (&vdata->vi, psf->sf.channels,
- psf->sf.samplerate, -1, 128000, -1) ||
- vorbis_encode_ctl (&vdata->vi, OV_ECTL_RATEMANAGE_AVG, NULL) ||
- vorbis_encode_setup_init (&vdata->vi)) ;
-#endif
- if (ret)
- return SFE_BAD_OPEN_FORMAT ;
-
- vdata->loc = 0 ;
-
- /* add a comment */
- vorbis_comment_init (&vdata->vc) ;
-
- vorbis_comment_add_tag (&vdata->vc, "ENCODER", "libsndfile") ;
- for (k = 0 ; k < SF_MAX_STRINGS ; k++)
- { const char * name ;
-
- if (psf->strings [k].type == 0)
- break ;
-
- switch (psf->strings [k].type)
- { case SF_STR_TITLE : name = "TITLE" ; break ;
- case SF_STR_COPYRIGHT : name = "COPYRIGHT" ; break ;
- case SF_STR_SOFTWARE : name = "SOFTWARE" ; break ;
- case SF_STR_ARTIST : name = "ARTIST" ; break ;
- case SF_STR_COMMENT : name = "COMMENT" ; break ;
- case SF_STR_DATE : name = "DATE" ; break ;
- case SF_STR_ALBUM : name = "ALBUM" ; break ;
- case SF_STR_LICENSE : name = "LICENSE" ; break ;
- default : continue ;
- } ;
-
- vorbis_comment_add_tag (&vdata->vc, name, psf->strings [k].str) ;
- } ;
-
- /* set up the analysis state and auxiliary encoding storage */
- vorbis_analysis_init (&vdata->vd, &vdata->vi) ;
- vorbis_block_init (&vdata->vd, &vdata->vb) ;
-
- /*
- ** Set up our packet->stream encoder.
- ** Pick a random serial number ; that way we can more likely build
- ** chained streams just by concatenation.
- */
-
- ogg_stream_init (&odata->os, psf_rand_int32 ()) ;
-
- /* Vorbis streams begin with three headers ; the initial header (with
- most of the codec setup parameters) which is mandated by the Ogg
- bitstream spec. The second header holds any comment fields. The
- third header holds the bitstream codebook. We merely need to
- make the headers, then pass them to libvorbis one at a time ;
- libvorbis handles the additional Ogg bitstream constraints */
-
- { ogg_packet header ;
- ogg_packet header_comm ;
- ogg_packet header_code ;
- int result ;
-
- vorbis_analysis_headerout (&vdata->vd, &vdata->vc, &header, &header_comm, &header_code) ;
- ogg_stream_packetin (&odata->os, &header) ; /* automatically placed in its own page */
- ogg_stream_packetin (&odata->os, &header_comm) ;
- ogg_stream_packetin (&odata->os, &header_code) ;
-
- /* This ensures the actual
- * audio data will start on a new page, as per spec
- */
- while ((result = ogg_stream_flush (&odata->os, &odata->og)) != 0)
- { psf_fwrite (odata->og.header, 1, odata->og.header_len, psf) ;
- psf_fwrite (odata->og.body, 1, odata->og.body_len, psf) ;
- } ;
- }
-
- return 0 ;
-} /* ogg_write_header */
-
-static int
-ogg_close (SF_PRIVATE *psf)
-{
- OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
- VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
-
- if (odata == NULL || vdata == NULL)
- return 0 ;
-
- /* Clean up this logical bitstream ; before exit we shuld see if we're
- ** followed by another [chained]. */
-
- if (psf->mode == SFM_WRITE)
- {
- if (psf->write_current <= 0)
- ogg_write_header (psf, 0) ;
-
- vorbis_analysis_wrote (&vdata->vd, 0) ;
- while (vorbis_analysis_blockout (&vdata->vd, &vdata->vb) == 1)
- {
-
- /* analysis, assume we want to use bitrate management */
- vorbis_analysis (&vdata->vb, NULL) ;
- vorbis_bitrate_addblock (&vdata->vb) ;
-
- while (vorbis_bitrate_flushpacket (&vdata->vd, &odata->op))
- { /* weld the packet into the bitstream */
- ogg_stream_packetin (&odata->os, &odata->op) ;
-
- /* write out pages (if any) */
- while (!odata->eos)
- { int result = ogg_stream_pageout (&odata->os, &odata->og) ;
- if (result == 0) break ;
- psf_fwrite (odata->og.header, 1, odata->og.header_len, psf) ;
- psf_fwrite (odata->og.body, 1, odata->og.body_len, psf) ;
-
- /* this could be set above, but for illustrative purposes, I do
- it here (to show that vorbis does know where the stream ends) */
-
- if (ogg_page_eos (&odata->og)) odata->eos = 1 ;
- }
- }
- }
- }
-
- /* ogg_page and ogg_packet structs always point to storage in
- libvorbis. They are never freed or manipulated directly */
-
- vorbis_block_clear (&vdata->vb) ;
- vorbis_dsp_clear (&vdata->vd) ;
- vorbis_comment_clear (&vdata->vc) ;
- vorbis_info_clear (&vdata->vi) ; /* must be called last */
- /* should look here to reopen if chained */
-
- /* OK, clean up the framer */
- ogg_sync_clear (&odata->oy) ;
- ogg_stream_clear (&odata->os) ;
-
- return 0 ;
-} /* ogg_close */
-
-int
-ogg_open (SF_PRIVATE *psf)
-{ OGG_PRIVATE* odata = calloc (1, sizeof (OGG_PRIVATE)) ;
- VORBIS_PRIVATE* vdata = calloc (1, sizeof (VORBIS_PRIVATE)) ;
- int error = 0 ;
-
- psf->container_data = odata ;
- psf->codec_data = vdata ;
-
- if (psf->mode == SFM_RDWR)
- return SFE_BAD_MODE_RW ;
-
-#if HAVE_VORBIS_VERSION_STRING
- psf_log_printf (psf, "Vorbis library version : %s\n", vorbis_version_string ()) ;
-#endif
-
- if (psf->mode == SFM_READ)
- { /* Call this here so it only gets called once, so no memory is leaked. */
- ogg_sync_init (&odata->oy) ;
-
- if ((error = ogg_read_header (psf, 1)))
- return error ;
-
- psf->read_short = ogg_read_s ;
- psf->read_int = ogg_read_i ;
- psf->read_float = ogg_read_f ;
- psf->read_double = ogg_read_d ;
- psf->sf.frames = ogg_length (psf) ;
- } ;
-
- psf->container_close = ogg_close ;
- if (psf->mode == SFM_WRITE)
- {
- /* Set the default vorbis quality here. */
- vdata->quality = 0.4 ;
-
- psf->write_header = ogg_write_header ;
- psf->write_short = ogg_write_s ;
- psf->write_int = ogg_write_i ;
- psf->write_float = ogg_write_f ;
- psf->write_double = ogg_write_d ;
-
- psf->sf.frames = SF_COUNT_MAX ; /* Unknown really */
- psf->str_flags = SF_STR_ALLOW_START ;
- } ;
-
- psf->bytewidth = 1 ;
- psf->blockwidth = psf->bytewidth * psf->sf.channels ;
-
- psf->seek = ogg_seek ;
- psf->command = ogg_command ;
-
- /* FIXME, FIXME, FIXME : Hack these here for now and correct later. */
- psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
- psf->sf.sections = 1 ;
+ odata->codec = ogg_page_classify (psf, &odata->opage) ;
- psf->datalength = 1 ;
- psf->dataoffset = 0 ;
- /* End FIXME. */
-
- return error ;
-} /* ogg_open */
-
-static int
-ogg_command (SF_PRIVATE *psf, int command, void * data, int datasize)
-{ VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
-
- switch (command)
- { case SFC_SET_VBR_ENCODING_QUALITY :
- if (data == NULL || datasize != sizeof (double))
- return 1 ;
-
- if (psf->have_written)
- return 1 ;
-
- vdata->quality = *((double *) data) ;
-
- /* Clip range. */
- vdata->quality = SF_MAX (0.0, SF_MIN (1.0, vdata->quality)) ;
-
- psf_log_printf (psf, "%s : Setting SFC_SET_VBR_ENCODING_QUALITY to %f.\n", __func__, vdata->quality) ;
- break ;
-
- default :
+ switch (odata->codec)
+ { case OGG_VORBIS :
+ psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
return 0 ;
- } ;
-
- return 0 ;
-} /* ogg_command */
-
-static int
-ogg_rnull (int samples, void *UNUSED (vptr), int UNUSED (off) , int channels, float **UNUSED (pcm))
-{
- return samples * channels ;
-} /* ogg_rnull */
-
-static int
-ogg_rshort (int samples, void *vptr, int off, int channels, float **pcm)
-{
- short *ptr = (short*) vptr + off ;
- int i = 0, j, n ;
- for (j = 0 ; j < samples ; j++)
- for (n = 0 ; n < channels ; n++)
- ptr [i++] = lrintf (pcm [n][j] * 32767.0f) ;
- return i ;
-} /* ogg_rshort */
-
-static int
-ogg_rint (int samples, void *vptr, int off, int channels, float **pcm)
-{
- int *ptr = (int*) vptr + off ;
- int i = 0, j, n ;
-
- for (j = 0 ; j < samples ; j++)
- for (n = 0 ; n < channels ; n++)
- ptr [i++] = lrintf (pcm [n][j] * 2147483647.0f) ;
- return i ;
-} /* ogg_rint */
-
-static int
-ogg_rfloat (int samples, void *vptr, int off, int channels, float **pcm)
-{
- float *ptr = (float*) vptr + off ;
- int i = 0, j, n ;
- for (j = 0 ; j < samples ; j++)
- for (n = 0 ; n < channels ; n++)
- ptr [i++] = pcm [n][j] ;
- return i ;
-} /* ogg_rfloat */
-
-static int
-ogg_rdouble (int samples, void *vptr, int off, int channels, float **pcm)
-{
- double *ptr = (double*) vptr + off ;
- int i = 0, j, n ;
- for (j = 0 ; j < samples ; j++)
- for (n = 0 ; n < channels ; n++)
- ptr [i++] = pcm [n][j] ;
- return i ;
-} /* ogg_rdouble */
-
-
-static sf_count_t
-ogg_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn)
-{
- VORBIS_PRIVATE *vdata = psf->codec_data ;
- OGG_PRIVATE *odata = psf->container_data ;
- int len, samples, i = 0 ;
- float **pcm ;
-
- len = lens / psf->sf.channels ;
-
- while ((samples = vorbis_synthesis_pcmout (&vdata->vd, &pcm)) > 0)
- { if (samples > len) samples = len ;
- i += transfn (samples, ptr, i, psf->sf.channels, pcm) ;
- len -= samples ;
- /* tell libvorbis how many samples we actually consumed */
- vorbis_synthesis_read (&vdata->vd, samples) ;
- vdata->loc += samples ;
- if (len == 0)
- return i ; /* Is this necessary */
- }
- goto start0 ; /* Jump into the nasty nest */
- while (len > 0 && !odata->eos)
- {
- while (len > 0 && !odata->eos)
- { int result = ogg_sync_pageout (&odata->oy, &odata->og) ;
- if (result == 0) break ; /* need more data */
- if (result < 0)
- { /* missing or corrupt data at this page position */
- psf_log_printf (psf, "Corrupt or missing data in bitstream ; continuing...\n") ;
- }
- else
- { /* can safely ignore errors at this point */
- ogg_stream_pagein (&odata->os, &odata->og) ;
- start0:
- while (1)
- { result = ogg_stream_packetout (&odata->os, &odata->op) ;
- if (result == 0)
- break ; /* need more data */
- if (result < 0)
- { /* missing or corrupt data at this page position */
- /* no reason to complain ; already complained above */
- }
- else
- { /* we have a packet. Decode it */
- if (vorbis_synthesis (&vdata->vb, &odata->op) == 0) /* test for success! */
- vorbis_synthesis_blockin (&vdata->vd, &vdata->vb) ;
- /*
- **pcm is a multichannel float vector. In stereo, for
- example, pcm [0] is left, and pcm [1] is right. samples is
- the size of each channel. Convert the float values
- (-1.<=range<=1.) to whatever PCM format and write it out */
-
- while ((samples = vorbis_synthesis_pcmout (&vdata->vd, &pcm)) > 0)
- { if (samples>len) samples = len ;
- i += transfn (samples, ptr, i, psf->sf.channels, pcm) ;
- len -= samples ;
- /* tell libvorbis how many samples we actually consumed */
- vorbis_synthesis_read (&vdata->vd, samples) ;
- vdata->loc += samples ;
- if (len == 0)
- return i ; /* Is this necessary */
- } ;
- }
- }
- if (ogg_page_eos (&odata->og)) odata->eos = 1 ;
- }
- }
- if (!odata->eos)
- { char *buffer ;
- int bytes ;
- buffer = ogg_sync_buffer (&odata->oy, 4096) ;
- bytes = psf_fread (buffer, 1, 4096, psf) ;
- ogg_sync_wrote (&odata->oy, bytes) ;
- if (bytes == 0) odata->eos = 1 ;
- }
- }
- return i ;
-} /* ogg_read_sample */
-
-static sf_count_t
-ogg_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t lens)
-{ return ogg_read_sample (psf, (void*) ptr, lens, ogg_rshort) ;
-} /* ogg_read_s */
-
-static sf_count_t
-ogg_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t lens)
-{ return ogg_read_sample (psf, (void*) ptr, lens, ogg_rint) ;
-} /* ogg_read_i */
-
-static sf_count_t
-ogg_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t lens)
-{ return ogg_read_sample (psf, (void*) ptr, lens, ogg_rfloat) ;
-} /* ogg_read_f */
-
-static sf_count_t
-ogg_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t lens)
-{ return ogg_read_sample (psf, (void*) ptr, lens, ogg_rdouble) ;
-} /* ogg_read_d */
-
-/*==============================================================================
-*/
-
-static void
-ogg_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata, int in_frames)
-{
- vorbis_analysis_wrote (&vdata->vd, in_frames) ;
-
- /*
- ** Vorbis does some data preanalysis, then divvies up blocks for
- ** more involved (potentially parallel) processing. Get a single
- ** block for encoding now.
- */
- while (vorbis_analysis_blockout (&vdata->vd, &vdata->vb) == 1)
- {
- /* analysis, assume we want to use bitrate management */
- vorbis_analysis (&vdata->vb, NULL) ;
- vorbis_bitrate_addblock (&vdata->vb) ;
-
- while (vorbis_bitrate_flushpacket (&vdata->vd, &odata->op))
- {
- /* weld the packet into the bitstream */
- ogg_stream_packetin (&odata->os, &odata->op) ;
-
- /* write out pages (if any) */
- while (!odata->eos)
- { int result = ogg_stream_pageout (&odata->os, &odata->og) ;
- if (result == 0)
- break ;
- psf_fwrite (odata->og.header, 1, odata->og.header_len, psf) ;
- psf_fwrite (odata->og.body, 1, odata->og.body_len, psf) ;
-
- /* This could be set above, but for illustrative purposes, I do
- ** it here (to show that vorbis does know where the stream ends) */
- if (ogg_page_eos (&odata->og))
- odata->eos = 1 ;
- } ;
- } ;
- } ;
-
- vdata->loc += in_frames ;
-} /* ogg_write_data */
-
-
-static sf_count_t
-ogg_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t lens)
-{
- int i, m, j = 0 ;
- OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
- VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
- int in_frames = lens / psf->sf.channels ;
- float **buffer = vorbis_analysis_buffer (&vdata->vd, in_frames) ;
- for (i = 0 ; i < in_frames ; i++)
- for (m = 0 ; m < psf->sf.channels ; m++)
- buffer [m][i] = (float) (ptr [j++]) / 32767.0f ;
-
- ogg_write_samples (psf, odata, vdata, in_frames) ;
-
- return lens ;
-} /* ogg_write_s */
-
-static sf_count_t
-ogg_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t lens)
-{ int i, m, j = 0 ;
- OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
- VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
- int in_frames = lens / psf->sf.channels ;
- float **buffer = vorbis_analysis_buffer (&vdata->vd, in_frames) ;
- for (i = 0 ; i < in_frames ; i++)
- for (m = 0 ; m < psf->sf.channels ; m++)
- buffer [m][i] = (float) (ptr [j++]) / 2147483647.0f ;
-
- ogg_write_samples (psf, odata, vdata, in_frames) ;
-
- return lens ;
-} /* ogg_write_i */
-
-static sf_count_t
-ogg_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t lens)
-{ int i, m, j = 0 ;
- OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
- VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
- int in_frames = lens / psf->sf.channels ;
- float **buffer = vorbis_analysis_buffer (&vdata->vd, in_frames) ;
- for (i = 0 ; i < in_frames ; i++)
- for (m = 0 ; m < psf->sf.channels ; m++)
- buffer [m][i] = ptr [j++] ;
-
- ogg_write_samples (psf, odata, vdata, in_frames) ;
-
- return lens ;
-} /* ogg_write_f */
-
-static sf_count_t
-ogg_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t lens)
-{ int i, m, j = 0 ;
- OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
- VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
- int in_frames = lens / psf->sf.channels ;
- float **buffer = vorbis_analysis_buffer (&vdata->vd, in_frames) ;
- for (i = 0 ; i < in_frames ; i++)
- for (m = 0 ; m < psf->sf.channels ; m++)
- buffer [m][i] = (float) ptr [j++] ;
-
- ogg_write_samples (psf, odata, vdata, in_frames) ;
-
- return lens ;
-} /* ogg_write_d */
-
-static sf_count_t
-ogg_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
-{
- OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
- VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
-
- if (odata == NULL || vdata == NULL)
- return 0 ;
-
- if (offset < 0)
- { psf->error = SFE_BAD_SEEK ;
- return ((sf_count_t) -1) ;
- } ;
-
- if (psf->mode == SFM_READ)
- { sf_count_t target = offset - vdata->loc ;
- if (target < 0)
- { /* 12 to allow for OggS bit */
- psf_fseek (psf, 12, SEEK_SET) ;
- ogg_read_header (psf, 0) ; /* Reset state */
- target = offset ;
- } ;
-
- while (target > 0)
- { sf_count_t m = target > 4096 ? 4096 : target ;
+ case OGG_FLAC :
+ case OGG_FLAC0 :
+ psf->sf.format = SF_FORMAT_OGGFLAC ;
+ return 0 ;
- /*
- ** Need to multiply by channels here because the seek is done in
- ** terms of frames and the read function is done in terms of
- ** samples.
- */
- ogg_read_sample (psf, (void *) NULL, m * psf->sf.channels, ogg_rnull) ;
+ case OGG_SPEEX :
+ psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_SPEEX ;
+ return 0 ;
- target -= m ;
- } ;
+ case OGG_PCM :
+ psf_log_printf (psf, "Detected Ogg/PCM data. This is not supported yet.\n") ;
+ return SFE_UNIMPLEMENTED ;
- return vdata->loc ;
+ default :
+ break ;
} ;
- return 0 ;
-} /* ogg_seek */
+ psf_log_printf (psf, "This Ogg bitstream contains some uknown data type.\n") ;
+ return SFE_UNIMPLEMENTED ;
+} /* ogg_stream_classify */
/*==============================================================================
-** Most of the following code was snipped from Mike Smith's ogginfo utility
-** which is part of vorbis-tools.
-** Vorbis tools is released under the GPL but Mike has kindly allowed the
-** following to be relicensed as LGPL for libsndfile.
*/
-typedef struct
-{
- int isillegal ;
- int shownillegal ;
- int isnew ;
- int end ;
-
- uint32_t serial ; /* must be 32 bit unsigned */
- ogg_stream_state os ;
-
- vorbis_info vi ;
- vorbis_comment vc ;
- sf_count_t lastgranulepos ;
- int doneheaders ;
-} stream_processor ;
-
-typedef struct
-{
- stream_processor *streams ;
- int allocated ;
- int used ;
- int in_headers ;
-} stream_set ;
-
-static stream_set *
-create_stream_set (void)
-{ stream_set *set = calloc (1, sizeof (stream_set)) ;
-
- set->streams = calloc (5, sizeof (stream_processor)) ;
- set->allocated = 5 ;
- set->used = 0 ;
-
- return set ;
-} /* create_stream_set */
-
-static void
-vorbis_end (stream_processor *stream, sf_count_t * len)
-{ *len += stream->lastgranulepos ;
- vorbis_comment_clear (&stream->vc) ;
- vorbis_info_clear (&stream->vi) ;
-} /* vorbis_end */
-
-static void
-free_stream_set (stream_set *set, sf_count_t * len)
-{ int i ;
-
- for (i = 0 ; i < set->used ; i++)
- { if (!set->streams [i].end)
- vorbis_end (&set->streams [i], len) ;
- ogg_stream_clear (&set->streams [i].os) ;
- } ;
-
- free (set->streams) ;
- free (set) ;
-} /* free_stream_set */
-
-static int
-streams_open (stream_set *set)
-{ int i, res = 0 ;
-
- for (i = 0 ; i < set->used ; i++)
- if (!set->streams [i].end)
- res ++ ;
- return res ;
-} /* streams_open */
-
-static stream_processor *
-find_stream_processor (stream_set *set, ogg_page *page)
-{ uint32_t serial = ogg_page_serialno (page) ;
- int i, found = 0 ;
- int invalid = 0 ;
-
- stream_processor *stream ;
-
- for (i = 0 ; i < set->used ; i++)
- {
- if (serial == set->streams [i].serial)
- { /* We have a match! */
- found = 1 ;
- stream = & (set->streams [i]) ;
-
- set->in_headers = 0 ;
- /* if we have detected EOS, then this can't occur here. */
- if (stream->end)
- { stream->isillegal = 1 ;
- return stream ;
- }
-
- stream->isnew = 0 ;
- stream->end = ogg_page_eos (page) ;
- stream->serial = serial ;
- return stream ;
- } ;
- } ;
-
- /* If there are streams open, and we've reached the end of the
- ** headers, then we can't be starting a new stream.
- ** XXX: might this sometimes catch ok streams if EOS flag is missing,
- ** but the stream is otherwise ok?
- */
- if (streams_open (set) && !set->in_headers)
- invalid = 1 ;
-
- set->in_headers = 1 ;
-
- if (set->allocated < set->used)
- stream = &set->streams [set->used] ;
- else
- { set->allocated += 5 ;
- set->streams = realloc (set->streams, sizeof (stream_processor) * set->allocated) ;
- stream = &set->streams [set->used] ;
- } ;
-
- set->used++ ;
-
- stream->isnew = 1 ;
- stream->isillegal = invalid ;
-
- {
- int res ;
- ogg_packet packet ;
-
- /* We end up processing the header page twice, but that's ok. */
- ogg_stream_init (&stream->os, serial) ;
- ogg_stream_pagein (&stream->os, page) ;
- res = ogg_stream_packetout (&stream->os, &packet) ;
- if (res <= 0)
- return NULL ;
- else if (packet.bytes >= 7 && memcmp (packet.packet, "\x01vorbis", 7) == 0)
- {
- stream->lastgranulepos = 0 ;
- vorbis_comment_init (&stream->vc) ;
- vorbis_info_init (&stream->vi) ;
- } ;
-
- res = ogg_stream_packetout (&stream->os, &packet) ;
-
- /* re-init, ready for processing */
- ogg_stream_clear (&stream->os) ;
- ogg_stream_init (&stream->os, serial) ;
- }
-
- stream->end = ogg_page_eos (page) ;
- stream->serial = serial ;
-
- return stream ;
-} /* find_stream_processor */
+static struct
+{ const char *str, *name ;
+ int len, codec ;
+} codec_lookup [] =
+{ { "Annodex", "Annodex", 8, OGG_ANNODEX },
+ { "AnxData", "AnxData", 7, OGG_ANXDATA },
+ { "\177FLAC", "Flac1", 5, OGG_FLAC },
+ { "fLaC", "Flac0", 4, OGG_FLAC0 },
+ { "PCM ", "PCM", 8, OGG_PCM },
+ { "Speex", "Speex", 5, OGG_SPEEX },
+ { "\001vorbis", "Vorbis", 7, OGG_VORBIS },
+} ;
static int
-ogg_length_get_next_page (SF_PRIVATE *psf, ogg_sync_state * osync, ogg_page *page)
-{ static const int CHUNK_SIZE = 4500 ;
+ogg_page_classify (SF_PRIVATE * psf, const ogg_page * og)
+{ int k, len ;
- while (ogg_sync_pageout (osync, page) <= 0)
- { char * buffer = ogg_sync_buffer (osync, CHUNK_SIZE) ;
- int bytes = psf_fread (buffer, 1, 4096, psf) ;
+ for (k = 0 ; k < ARRAY_LEN (codec_lookup) ; k++)
+ { if (codec_lookup [k].len > og->body_len)
+ continue ;
- if (bytes <= 0)
- { ogg_sync_wrote (osync, 0) ;
- return 0 ;
+ if (memcmp (og->body, codec_lookup [k].str, codec_lookup [k].len) == 0)
+ { psf_log_printf (psf, "Ogg stream data : %s\n", codec_lookup [k].name) ;
+ psf_log_printf (psf, "Stream serialno : %010D\n", (int64_t) ogg_page_serialno (og)) ;
+ return codec_lookup [k].codec ;
} ;
-
- ogg_sync_wrote (osync, bytes) ;
} ;
- return 1 ;
-} /* ogg_length_get_next_page */
+ len = og->body_len < 8 ? og->body_len : 8 ;
-static sf_count_t
-ogg_length_aux (SF_PRIVATE * psf)
-{
- ogg_sync_state osync ;
- ogg_page page ;
- int gotpage = 0 ;
- sf_count_t len = 0 ;
- stream_set *processors ;
-
- processors = create_stream_set () ;
- if (processors == NULL)
- return 0 ; // out of memory?
+ psf_log_printf (psf, "Ogg_stream data : '") ;
+ for (k = 0 ; k < len ; k++)
+ psf_log_printf (psf, "%c", isprint (og->body [k]) ? og->body [k] : '.') ;
+ psf_log_printf (psf, "' ") ;
+ for (k = 0 ; k < len ; k++)
+ psf_log_printf (psf, " %02x", og->body [k] & 0xff) ;
+ psf_log_printf (psf, "\n") ;
- ogg_sync_init (&osync) ;
-
- while (ogg_length_get_next_page (psf, &osync, &page))
- {
- stream_processor *p = find_stream_processor (processors, &page) ;
- gotpage = 1 ;
-
- if (!p)
- { len = 0 ;
- break ;
- } ;
-
- if (p->isillegal && !p->shownillegal)
- {
- p->shownillegal = 1 ;
- /* If it's a new stream, we want to continue processing this page
- ** anyway to suppress additional spurious errors
- */
- if (!p->isnew) continue ;
- } ;
-
- if (!p->isillegal)
- { ogg_packet packet ;
- int header = 0 ;
-
- ogg_stream_pagein (&p->os, &page) ;
- if (p->doneheaders < 3)
- header = 1 ;
-
- while (ogg_stream_packetout (&p->os, &packet) > 0)
- {
- if (p->doneheaders < 3)
- { if (vorbis_synthesis_headerin (&p->vi, &p->vc, &packet) < 0)
- continue ;
- p->doneheaders ++ ;
- } ;
- } ;
- if (!header)
- { sf_count_t gp = ogg_page_granulepos (&page) ;
- if (gp > 0) p->lastgranulepos = gp ;
- } ;
- if (p->end)
- { vorbis_end (p, &len) ;
- p->isillegal = 1 ;
- } ;
- } ;
- } ;
-
- ogg_sync_clear (&osync) ;
- free_stream_set (processors, &len) ;
-
- return len ;
-} /* ogg_length_aux */
-
-static sf_count_t
-ogg_length (SF_PRIVATE *psf)
-{ sf_count_t length ;
- int error ;
-
- if (psf->sf.seekable == 0)
- return SF_COUNT_MAX ;
-
- psf_fseek (psf, 0, SEEK_SET) ;
- length = ogg_length_aux (psf) ;
-
- psf_fseek (psf, 12, SEEK_SET) ;
- if ((error = ogg_read_header (psf, 0)) != 0)
- psf->error = error ;
-
- return length ;
-} /* ogg_length */
+ return 0 ;
+} /* ogg_page_classify */
#else /* HAVE_EXTERNAL_LIBS */
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
psf->dataoffset = PAF_HEADER_LENGTH ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = paf_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_PAF)
return SFE_BAD_OPEN_FORMAT ;
{ PAF_FMT paf_fmt ;
int marker ;
+ if (psf->filelength < PAF_HEADER_LENGTH)
+ return SFE_PAF_SHORT_HEADER ;
+
memset (&paf_fmt, 0, sizeof (paf_fmt)) ;
psf_binheader_readf (psf, "pm", 0, &marker) ;
psf->endian = SF_ENDIAN_BIG ;
} ;
- if (psf->filelength < PAF_HEADER_LENGTH)
- return SFE_PAF_SHORT_HEADER ;
+ if (paf_fmt.channels > SF_MAX_CHANNELS)
+ return SFE_PAF_BAD_CHANNELS ;
psf->datalength = psf->filelength - psf->dataoffset ;
*/
psf->last_op = 0 ;
- if (! (psf->codec_data = malloc (paf24size)))
+ if (! (psf->codec_data = calloc (1, paf24size)))
return SFE_MALLOC_FAILED ;
ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
- memset (ppaf24, 0, paf24size) ;
ppaf24->channels = psf->sf.channels ;
ppaf24->samples = ppaf24->data ;
ppaf24->blocksize = PAF24_BLOCK_SIZE * ppaf24->channels ;
ppaf24->samplesperblock = PAF24_SAMPLES_PER_BLOCK ;
- if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
{ paf24_read_block (psf, ppaf24) ; /* Read first block. */
psf->read_short = paf24_read_s ;
psf->read_double = paf24_read_d ;
} ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ psf->write_short = paf24_write_s ;
psf->write_int = paf24_write_i ;
psf->write_float = paf24_write_f ;
psf->datalength = psf->filelength - psf->dataoffset ;
if (psf->datalength % PAF24_BLOCK_SIZE)
- { if (psf->mode == SFM_READ)
+ { if (psf->file.mode == SFM_READ)
psf_log_printf (psf, "*** Warning : file seems to be truncated.\n") ;
ppaf24->max_blocks = psf->datalength / ppaf24->blocksize + 1 ;
}
ppaf24->max_blocks = psf->datalength / ppaf24->blocksize ;
ppaf24->read_block = 0 ;
- if (psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_RDWR)
ppaf24->write_block = ppaf24->max_blocks ;
else
ppaf24->write_block = 0 ;
ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (ppaf24->write_count > 0)
paf24_write_block (psf, ppaf24) ;
} ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
else
psf->data_endswap = (psf->endian == SF_ENDIAN_LITTLE) ? SF_FALSE : SF_TRUE ;
- if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
{ switch (psf->bytewidth * 0x10000 + psf->endian + chars)
{ case (0x10000 + SF_ENDIAN_BIG + SF_CHARS_SIGNED) :
case (0x10000 + SF_ENDIAN_LITTLE + SF_CHARS_SIGNED) :
} ;
} ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ switch (psf->bytewidth * 0x10000 + psf->endian + chars)
{ case (0x10000 + SF_ENDIAN_BIG + SF_CHARS_SIGNED) :
case (0x10000 + SF_ENDIAN_LITTLE + SF_CHARS_SIGNED) :
else
psf->datalength = 0 ;
- psf->sf.frames = psf->datalength / psf->blockwidth ;
+ psf->sf.frames = psf->blockwidth > 0 ? psf->datalength / psf->blockwidth : 0 ;
return 0 ;
} /* pcm_init */
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
{ int subformat ;
int error = 0 ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = pvf_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_PVF)
return SFE_BAD_OPEN_FORMAT ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
/*
-** Copyright (C) 2008-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2008-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2009 Uli Franke <cls@nebadje.org>
**
** 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
/*
** This format documented at:
** http://www.sr.se/utveckling/tu/bwf/prog/RF_64v1_4.pdf
+**
+** But this may be a better reference:
+** http://www.ebu.ch/CMSimages/en/tec_doc_t3306-2007_tcm6-42570.pdf
*/
#include "sfconfig.h"
#define fact_MARKER MAKE_MARKER ('f', 'a', 'c', 't')
#define data_MARKER MAKE_MARKER ('d', 'a', 't', 'a')
+#define bext_MARKER MAKE_MARKER ('b', 'e', 'x', 't')
+#define OggS_MARKER MAKE_MARKER ('O', 'g', 'g', 'S')
+#define wvpk_MARKER MAKE_MARKER ('w', 'v', 'p', 'k')
+
/*------------------------------------------------------------------------------
** Typedefs.
*/
** Private static functions.
*/
-static int rf64_read_header (SF_PRIVATE *psf) ;
+static int rf64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock) ;
static int rf64_write_header (SF_PRIVATE *psf, int calc_length) ;
static int rf64_close (SF_PRIVATE *psf) ;
+static int rf64_command (SF_PRIVATE *psf, int command, void * UNUSED (data), int datasize) ;
/*------------------------------------------------------------------------------
** Public function.
rf64_open (SF_PRIVATE *psf)
{ WAV_PRIVATE *wpriv ;
int subformat, error = 0 ;
+ int blockalign, framesperblock ;
if ((wpriv = calloc (1, sizeof (WAV_PRIVATE))) == NULL)
return SFE_MALLOC_FAILED ;
psf->container_data = wpriv ;
+ wpriv->wavex_ambisonic = SF_AMBISONIC_NONE ;
/* All RF64 files are little endian. */
psf->endian = SF_ENDIAN_LITTLE ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
- { if ((error = rf64_read_header (psf)) != 0)
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
+ { if ((error = rf64_read_header (psf, &blockalign, &framesperblock)) != 0)
return error ;
} ;
subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
} ;
psf->container_close = rf64_close ;
+ psf->command = rf64_command ;
switch (subformat)
{ case SF_FORMAT_PCM_U8 :
/*------------------------------------------------------------------------------
*/
+enum
+{ HAVE_ds64 = 0x01,
+ HAVE_fmt = 0x02,
+ HAVE_bext = 0x04,
+ HAVE_data = 0x08
+} ;
+
+#define HAVE_CHUNK(CHUNK) ((parsestage & CHUNK) != 0)
static int
-rf64_read_header (SF_PRIVATE *psf)
-{ WAV_PRIVATE *wpriv ;
- sf_count_t riff_size, data_size ;
- unsigned int size32 ;
- int marker, marks [2], error, done = 0 ;
+rf64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
+{ WAV_PRIVATE *wpriv ;
+ WAV_FMT *wav_fmt ;
+ sf_count_t riff_size = 0, frame_count = 0, ds64_datalength = 0 ;
+ unsigned int size32, parsestage = 0 ;
+ int marker, marks [2], error, done = 0, format = 0 ;
if ((wpriv = psf->container_data) == NULL)
return SFE_INTERNAL ;
+ wav_fmt = &wpriv->wav_fmt ;
/* Set position to start of file to begin reading header. */
psf_binheader_readf (psf, "pmmm", 0, &marker, marks, marks + 1) ;
- if (marker != RF64_MARKER || marks [0] != FFFF_MARKER || marks [1] != WAVE_MARKER)
+ if (marker != RF64_MARKER || marks [1] != WAVE_MARKER)
return SFE_RF64_NOT_RF64 ;
- psf_log_printf (psf, "%M\n %M\n", RF64_MARKER, WAVE_MARKER) ;
+ if (marks [0] == FFFF_MARKER)
+ psf_log_printf (psf, "%M\n %M\n", RF64_MARKER, WAVE_MARKER) ;
+ else
+ psf_log_printf (psf, "%M : 0x%x (should be 0xFFFFFFFF)\n %M\n", RF64_MARKER, WAVE_MARKER) ;
- while (! done)
+ while (NOT (done))
{ psf_binheader_readf (psf, "em4", &marker, &size32) ;
switch (marker)
{ case ds64_MARKER :
- psf_log_printf (psf, "%M : %u\n", marker, size32) ;
+ { unsigned int table_len, bytesread ;
+
+ /* Read ds64 sizes (3 8-byte words). */
+ bytesread = psf_binheader_readf (psf, "888", &riff_size, &ds64_datalength, &frame_count) ;
+
+ /* Read table length. */
+ bytesread += psf_binheader_readf (psf, "4", &table_len) ;
+ /* Skip table for now. (this was "table_len + 4", why?) */
+ bytesread += psf_binheader_readf (psf, "j", table_len) ;
+
+ if (size32 == bytesread)
+ psf_log_printf (psf, "%M : %u\n", marker, size32) ;
+ else if (size32 >= bytesread + 4)
+ { unsigned int next ;
+ psf_binheader_readf (psf, "m", &next) ;
+ if (next == fmt_MARKER)
+ { psf_log_printf (psf, "%M : %u (should be %u)\n", marker, size32, bytesread) ;
+ psf_binheader_readf (psf, "j", -4) ;
+ }
+ else
+ { psf_log_printf (psf, "%M : %u\n", marker, size32) ;
+ psf_binheader_readf (psf, "j", size32 - bytesread - 4) ;
+ } ;
+ } ;
- psf_binheader_readf (psf, "888", &riff_size, &data_size, &psf->sf.frames) ;
- psf_log_printf (psf, " Riff size : %D\n Data size : %D\n Frames : %D\n",
- riff_size, data_size, psf->sf.frames) ;
+ if (psf->filelength != riff_size + 8)
+ psf_log_printf (psf, " Riff size : %D (should be %D)\n", riff_size, psf->filelength - 8) ;
+ else
+ psf_log_printf (psf, " Riff size : %D\n", riff_size) ;
- psf_binheader_readf (psf, "4", &size32) ;
- psf_log_printf (psf, " Table len : %u\n", size32) ;
+ psf_log_printf (psf, " Data size : %D\n", ds64_datalength) ;
- psf_binheader_readf (psf, "jm4", size32 + 4, &marker, &size32) ;
- psf_log_printf (psf, "%M : %u\n", marker, size32) ;
+ psf_log_printf (psf, " Frames : %D\n", frame_count) ;
+ psf_log_printf (psf, " Table length : %u\n", table_len) ;
+
+ } ;
+ parsestage |= HAVE_ds64 ;
+ break ;
+ case fmt_MARKER:
+ psf_log_printf (psf, "%M : %u\n", marker, size32) ;
if ((error = wav_w64_read_fmt_chunk (psf, size32)) != 0)
return error ;
- psf->sf.format = SF_FORMAT_RF64 | (psf->sf.format & SF_FORMAT_SUBMASK) ;
+ format = wav_fmt->format ;
+ parsestage |= HAVE_fmt ;
break ;
- case data_MARKER :
- psf_log_printf (psf, "%M : %x\n", marker, size32) ;
- psf->dataoffset = psf->headindex ;
- done = SF_TRUE ;
+ case bext_MARKER :
+ if ((error = wav_read_bext_chunk (psf, size32)) != 0)
+ return error ;
+ parsestage |= HAVE_bext ;
break ;
+ case data_MARKER :
+ /* see wav for more sophisticated parsing -> implement state machine with parsestage */
+
+ if (HAVE_CHUNK (HAVE_ds64))
+ { if (size32 == 0xffffffff)
+ psf_log_printf (psf, "%M : 0x%x\n", marker, size32) ;
+ else
+ psf_log_printf (psf, "%M : 0x%x (should be 0xffffffff\n", marker, size32) ;
+ psf->datalength = ds64_datalength ;
+ }
+ else
+ { if (size32 == 0xffffffff)
+ { psf_log_printf (psf, "%M : 0x%x\n", marker, size32) ;
+ psf_log_printf (psf, " *** Data length not specified no 'ds64' chunk.\n") ;
+ }
+ else
+ { psf_log_printf (psf, "%M : 0x%x\n**** Weird, RF64 file without a 'ds64' chunk and no valid 'data' size.\n", marker, size32) ;
+ psf->datalength = size32 ;
+ } ;
+ } ;
+
+ psf->dataoffset = psf_ftell (psf) ;
+
+ if (psf->dataoffset > 0)
+ { if (size32 == 0 && riff_size == 8 && psf->filelength > 44)
+ { psf_log_printf (psf, " *** Looks like a WAV file which wasn't closed properly. Fixing it.\n") ;
+ psf->datalength = psf->filelength - psf->dataoffset ;
+ } ;
+
+ /* Only set dataend if there really is data at the end. */
+ if (psf->datalength + psf->dataoffset < psf->filelength)
+ psf->dataend = psf->datalength + psf->dataoffset ;
+
+ if (NOT (psf->sf.seekable) || psf->dataoffset < 0)
+ break ;
+
+ /* Seek past data and continue reading header. */
+ psf_fseek (psf, psf->datalength, SEEK_CUR) ;
+
+ if (psf_ftell (psf) != psf->datalength + psf->dataoffset)
+ psf_log_printf (psf, " *** psf_fseek past end error ***\n") ;
+ break ;
+ } ;
+ break ;
+
default :
if (isprint ((marker >> 24) & 0xFF) && isprint ((marker >> 16) & 0xFF)
&& isprint ((marker >> 8) & 0xFF) && isprint (marker & 0xFF))
- { psf_binheader_readf (psf, "4", &size32) ;
- psf_log_printf (psf, "*** %M : %d (unknown marker)\n", marker, size32) ;
+ { psf_log_printf (psf, "*** %M : %d (unknown marker)\n", marker, size32) ;
if (size32 < 8)
done = SF_TRUE ;
psf_binheader_readf (psf, "j", size32) ;
break ;
} ;
if (psf_ftell (psf) & 0x03)
- { psf_log_printf (psf, " Unknown chunk marker at position %d. Resynching.\n", size32 - 4) ;
+ { psf_log_printf (psf, " Unknown chunk marker at position 0x%x. Resynching.\n", size32 - 4) ;
psf_binheader_readf (psf, "j", -3) ;
break ;
} ;
- psf_log_printf (psf, "*** Unknown chunk marker (%X) at position %D. Exiting parser.\n", marker, psf_ftell (psf) - 4) ;
+ psf_log_printf (psf, "*** Unknown chunk marker (0x%X) at position 0x%X. Exiting parser.\n", marker, psf_ftell (psf) - 4) ;
done = SF_TRUE ;
break ;
} ; /* switch (marker) */
} ;
} ;
+ if (psf->dataoffset <= 0)
+ return SFE_WAV_NO_DATA ;
+
+ /* WAVs can be little or big endian */
+ psf->endian = psf->rwf_endian ;
+
+ psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+
+ if (psf->is_pipe == 0)
+ { /*
+ ** Check for 'wvpk' at the start of the DATA section. Not able to
+ ** handle this.
+ */
+ psf_binheader_readf (psf, "4", &marker) ;
+ if (marker == wvpk_MARKER || marker == OggS_MARKER)
+ return SFE_WAV_WVPK_DATA ;
+ } ;
+
+ /* Seek to start of DATA section. */
+ psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+
+ if (psf->blockwidth)
+ { if (psf->filelength - psf->dataoffset < psf->datalength)
+ psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
+ else
+ psf->sf.frames = psf->datalength / psf->blockwidth ;
+ } ;
+
+ if (frame_count != psf->sf.frames)
+ psf_log_printf (psf, "*** Calculated frame count %d does not match value from 'ds64' chunk of %d.\n", psf->sf.frames, frame_count) ;
+
+ switch (format)
+ {
+ case WAVE_FORMAT_EXTENSIBLE :
+
+ /* with WAVE_FORMAT_EXTENSIBLE the psf->sf.format field is already set. We just have to set the major to rf64 */
+ psf->sf.format = (psf->sf.format & ~SF_FORMAT_TYPEMASK ) | SF_FORMAT_RF64 ;
+
+ if (psf->sf.format == (SF_FORMAT_WAVEX | SF_FORMAT_MS_ADPCM))
+ { *blockalign = wav_fmt->msadpcm.blockalign ;
+ *framesperblock = wav_fmt->msadpcm.samplesperblock ;
+ } ;
+ break ;
+
+ case WAVE_FORMAT_PCM :
+ psf->sf.format = SF_FORMAT_RF64 | u_bitwidth_to_subformat (psf->bytewidth * 8) ;
+ break ;
+
+ case WAVE_FORMAT_MULAW :
+ case IBM_FORMAT_MULAW :
+ psf->sf.format = (SF_FORMAT_RF64 | SF_FORMAT_ULAW) ;
+ break ;
+
+ case WAVE_FORMAT_ALAW :
+ case IBM_FORMAT_ALAW :
+ psf->sf.format = (SF_FORMAT_RF64 | SF_FORMAT_ALAW) ;
+ break ;
+
+ case WAVE_FORMAT_MS_ADPCM :
+ psf->sf.format = (SF_FORMAT_RF64 | SF_FORMAT_MS_ADPCM) ;
+ *blockalign = wav_fmt->msadpcm.blockalign ;
+ *framesperblock = wav_fmt->msadpcm.samplesperblock ;
+ break ;
+
+ case WAVE_FORMAT_IMA_ADPCM :
+ psf->sf.format = (SF_FORMAT_RF64 | SF_FORMAT_IMA_ADPCM) ;
+ *blockalign = wav_fmt->ima.blockalign ;
+ *framesperblock = wav_fmt->ima.samplesperblock ;
+ break ;
+
+ case WAVE_FORMAT_GSM610 :
+ psf->sf.format = (SF_FORMAT_RF64 | SF_FORMAT_GSM610) ;
+ break ;
+
+ case WAVE_FORMAT_IEEE_FLOAT :
+ psf->sf.format = SF_FORMAT_RF64 ;
+ psf->sf.format |= (psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT ;
+ break ;
+
+ case WAVE_FORMAT_G721_ADPCM :
+ psf->sf.format = SF_FORMAT_RF64 | SF_FORMAT_G721_32 ;
+ break ;
+
+ default : return SFE_UNIMPLEMENTED ;
+ } ;
+
+ if (wpriv->fmt_is_broken)
+ wav_w64_analyze (psf) ;
+
+ /* Only set the format endian-ness if its non-standard big-endian. */
+ if (psf->endian == SF_ENDIAN_BIG)
+ psf->sf.format |= SF_ENDIAN_BIG ;
+
return 0 ;
} /* rf64_read_header */
static int
-wavex_write_fmt_chunk (SF_PRIVATE *psf)
+rf64_write_fmt_chunk (SF_PRIVATE *psf)
{ WAV_PRIVATE *wpriv ;
- int subformat, fmt_size, add_fact_chunk = 0 ;
+ int subformat, fmt_size ;
if ((wpriv = psf->container_data) == NULL)
return SFE_INTERNAL ;
*/
if (wpriv->wavex_ambisonic != SF_AMBISONIC_NONE)
psf_binheader_writef (psf, "4", 0) ;
+ else if (wpriv->wavex_channelmask != 0)
+ psf_binheader_writef (psf, "4", wpriv->wavex_channelmask) ;
else
{ /*
** Ok some liberty is taken here to use the most commonly used channel masks
wavex_write_guid (psf, &MSGUID_SUBTYPE_ALAW) ;
break ;
-#if 0
- /* This is dead code due to return in previous switch statement. */
- case SF_FORMAT_MS_ADPCM : /* todo, GUID exists */
- wavex_write_guid (psf, &MSGUID_SUBTYPE_MS_ADPCM) ;
- break ;
- return SFE_UNIMPLEMENTED ;
-#endif
-
default : return SFE_UNIMPLEMENTED ;
} ;
- if (add_fact_chunk)
- psf_binheader_writef (psf, "tm48", fact_MARKER, 4, psf->sf.frames) ;
-
return 0 ;
-} /* wavex_write_fmt_chunk */
+} /* rf64_write_fmt_chunk */
static int
if (calc_length)
{ psf->filelength = psf_get_filelen (psf) ;
-
psf->datalength = psf->filelength - psf->dataoffset ;
if (psf->dataend)
psf_binheader_writef (psf, "em4m", RF64_MARKER, 0xffffffff, WAVE_MARKER) ;
- psf_binheader_writef (psf, "m488844", ds64_MARKER, 32, psf->filelength, psf->datalength, psf->sf.frames, 0, 0x005c0064) ;
+ /* Currently no table. */
+ psf_binheader_writef (psf, "m48884", ds64_MARKER, 28, psf->filelength - 8, psf->datalength, psf->sf.frames, 0) ;
/* WAVE and 'fmt ' markers. */
psf_binheader_writef (psf, "m", fmt_MARKER) ;
case SF_FORMAT_WAVEX :
case SF_FORMAT_RF64 :
- if ((error = wavex_write_fmt_chunk (psf)) != 0)
+ if ((error = rf64_write_fmt_chunk (psf)) != 0)
return error ;
break ;
return SFE_UNIMPLEMENTED ;
} ;
+ if (psf->broadcast_16k != NULL)
+ wav_write_bext_chunk (psf) ;
+
#if 0
/* The LIST/INFO chunk. */
if (psf->str_flags & SF_STR_LOCATE_START)
psf_binheader_writef (psf, "ft8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
} ;
- if (psf->broadcast_info != NULL)
- wav_write_bext_chunk (psf) ;
+// if (psf->broadcast_info != NULL)
+// wav_write_bext_chunk (psf) ;
if (psf->instrument != NULL)
{ int tmp ;
psf->dataoffset = psf->headindex ;
- if (! has_data)
+ if (NOT (has_data))
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
else if (current > 0)
psf_fseek (psf, current, SEEK_SET) ;
static int
rf64_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ // rf64_write_tailer (psf) ;
psf->write_header (psf, SF_TRUE) ;
return 0 ;
} /* rf64_close */
+
+static int
+rf64_command (SF_PRIVATE *psf, int command, void * UNUSED (data), int datasize)
+{ WAV_PRIVATE *wpriv ;
+
+ if ((wpriv = psf->container_data) == NULL)
+ return SFE_INTERNAL ;
+
+ switch (command)
+ { case SFC_WAVEX_SET_AMBISONIC :
+ if ((SF_CONTAINER (psf->sf.format)) == SF_FORMAT_WAVEX)
+ { if (datasize == SF_AMBISONIC_NONE)
+ wpriv->wavex_ambisonic = SF_AMBISONIC_NONE ;
+ else if (datasize == SF_AMBISONIC_B_FORMAT)
+ wpriv->wavex_ambisonic = SF_AMBISONIC_B_FORMAT ;
+ else
+ return 0 ;
+ } ;
+ return wpriv->wavex_ambisonic ;
+
+ case SFC_WAVEX_GET_AMBISONIC :
+ return wpriv->wavex_ambisonic ;
+
+ case SFC_SET_CHANNEL_MAP_INFO :
+ wpriv->wavex_channelmask = wavex_gen_channel_mask (psf->channel_map, psf->sf.channels) ;
+ return (wpriv->wavex_channelmask != 0) ;
+
+ default :
+ break ;
+ } ;
+
+ return 0 ;
+} /* rf64_command */
+
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
static int
rx2_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ /* Now we know for certain the length of the file we can re-write
** correct values for the FORM, 8SVX and BODY chunks.
*/
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2004 Paavo Jumppanen
**
** This program is free software; you can redistribute it and/or modify
/* SD2 is always big endian. */
psf->endian = SF_ENDIAN_BIG ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->rsrclength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->rsrclength > 0))
{ psf_use_rsrc (psf, SF_TRUE) ;
valid = psf_file_valid (psf) ;
psf_use_rsrc (psf, SF_FALSE) ;
if (! valid)
- { psf_log_printf (psf, "sd2_open : psf->rsrcdes < 0\n") ;
+ { psf_log_printf (psf, "sd2_open : psf->rsrc.filedes < 0\n") ;
return SFE_SD2_BAD_RSRC ;
} ;
psf->dataoffset = 0 ;
/* Only open and write the resource in RDWR mode is its current length is zero. */
- if (psf->mode == SFM_WRITE || (psf->mode == SFM_RDWR && psf->rsrclength == 0))
- { psf_open_rsrc (psf, psf->mode) ;
+ if (psf->file.mode == SFM_WRITE || (psf->file.mode == SFM_RDWR && psf->rsrclength == 0))
+ { psf->rsrc.mode = psf->file.mode ;
+ psf_open_rsrc (psf) ;
error = sd2_write_rsrc_fork (psf, SF_FALSE) ;
static int
sd2_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ /* Now we know for certain the audio_length of the file we can re-write
** correct values for the FORM, 8SVX and BODY chunks.
*/
} /* write_marker */
static void
-write_str (unsigned char * data, int offset, char * buffer, int buffer_len)
+write_str (unsigned char * data, int offset, const char * buffer, int buffer_len)
{ memcpy (data + offset, buffer, buffer_len) ;
} /* write_str */
write_int (rsrc.rsrc_data, 4, rsrc.map_offset) ;
write_int (rsrc.rsrc_data, 8, rsrc.data_length) ;
- write_char (rsrc.rsrc_data, 0x30, strlen (psf->filename)) ;
- write_str (rsrc.rsrc_data, 0x31, psf->filename, strlen (psf->filename)) ;
+ write_char (rsrc.rsrc_data, 0x30, strlen (psf->file.name.c)) ;
+ write_str (rsrc.rsrc_data, 0x31, psf->file.name.c, strlen (psf->file.name.c)) ;
write_short (rsrc.rsrc_data, 0x50, 0) ;
write_marker (rsrc.rsrc_data, 0x52, Sd2f_MARKER) ;
memset (buffer, 0, buffer_len) ;
for (k = 0 ; k < buffer_len - 1 ; k++)
- { if (isprint (data [offset + k]) == 0)
+ { if (psf_isprint (data [offset + k]) == 0)
return ;
buffer [k] = data [offset + k] ;
} ;
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
int read_samples [SDS_BLOCK_SIZE / 2] ; /* Maximum samples per block */
int write_block, write_count ;
+ int total_written ;
unsigned char write_data [SDS_BLOCK_SIZE] ;
int write_samples [SDS_BLOCK_SIZE / 2] ; /* Maximum samples per block */
} SDS_PRIVATE ;
return SFE_MALLOC_FAILED ;
psf->codec_data = psds ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = sds_read_header (psf, psds)))
return error ;
} ;
if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_SDS)
return SFE_BAD_OPEN_FORMAT ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (sds_write_header (psf, SF_FALSE))
return psf->error ;
static int
sds_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ SDS_PRIVATE *psds ;
if ((psds = (SDS_PRIVATE *) psf->codec_data) == NULL)
psds->samplesperblock = SDS_AUDIO_BYTES_PER_BLOCK / 4 ;
} ;
- if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
{ psf->read_short = sds_read_s ;
psf->read_int = sds_read_i ;
psf->read_float = sds_read_f ;
psds->reader (psf, psds) ;
} ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ psf->write_short = sds_write_s ;
psf->write_int = sds_write_i ;
psf->write_float = sds_write_f ;
if (marker != 0xF07E || byte != 0x01)
return SFE_SDS_NOT_SDS ;
- psf_log_printf (psf, "Midi Sample Dump Standard (.sds)\nF07E\n Midi Channel : %d\n", channel) ;
+ bytesread += psf_binheader_readf (psf, "e2", &sample_no) ;
+ sample_no = SDS_3BYTE_TO_INT_DECODE (sample_no) ;
- bytesread += psf_binheader_readf (psf, "e213", &sample_no, &bitwidth, &samp_period) ;
+ psf_log_printf (psf, "Midi Sample Dump Standard (.sds)\nF07E\n"
+ " Midi Channel : %d\n Sample Number : %d\n",
+ channel, sample_no) ;
+
+ bytesread += psf_binheader_readf (psf, "e13", &bitwidth, &samp_period) ;
- sample_no = SDS_3BYTE_TO_INT_DECODE (sample_no) ;
samp_period = SDS_3BYTE_TO_INT_DECODE (samp_period) ;
psds->bitwidth = bitwidth ;
- psf->sf.samplerate = 1000000000 / samp_period ;
+ if (psds->bitwidth > 1)
+ psf_log_printf (psf, " Bit Width : %d\n", psds->bitwidth) ;
+ else
+ { psf_log_printf (psf, " Bit Width : %d (should be > 1)\n", psds->bitwidth) ;
+ return SFE_SDS_BAD_BIT_WIDTH ;
+ } ;
+
+ if (samp_period > 0)
+ { psf->sf.samplerate = 1000000000 / samp_period ;
- psf_log_printf (psf, " Sample Number : %d\n"
- " Bit Width : %d\n"
+ psf_log_printf (psf, " Sample Period : %d\n"
" Sample Rate : %d\n",
- sample_no, psds->bitwidth, psf->sf.samplerate) ;
+ samp_period, psf->sf.samplerate) ;
+ }
+ else
+ { psf->sf.samplerate = 16000 ;
+
+ psf_log_printf (psf, " Sample Period : %d (should be > 0)\n"
+ " Sample Rate : %d (guessed)\n",
+ samp_period, psf->sf.samplerate) ;
+ } ;
bytesread += psf_binheader_readf (psf, "e3331", &data_length, &sustain_loop_start, &sustain_loop_end, &loop_type) ;
data_length = SDS_3BYTE_TO_INT_DECODE (data_length) ;
+ psf->sf.frames = psds->frames = data_length ;
+
sustain_loop_start = SDS_3BYTE_TO_INT_DECODE (sustain_loop_start) ;
sustain_loop_end = SDS_3BYTE_TO_INT_DECODE (sustain_loop_end) ;
psf->dataoffset = SDS_DATA_OFFSET ;
psf->datalength = psf->filelength - psf->dataoffset ;
- if (data_length != psf->filelength - psf->dataoffset)
- { psf_log_printf (psf, " Datalength : %d (truncated data??? %d)\n", data_length, psf->filelength - psf->dataoffset) ;
- data_length = psf->filelength - psf->dataoffset ;
- }
- else
- psf_log_printf (psf, " Datalength : %d\n", data_length) ;
-
bytesread += psf_binheader_readf (psf, "1", &byte) ;
if (byte != 0xF7)
psf_log_printf (psf, "bad end : %X\n", byte & 0xFF) ;
psf_log_printf (psf, "Frames : %d\n", blockcount * psds->samplesperblock) ;
- psf->sf.frames = blockcount * psds->samplesperblock ;
- psds->frames = blockcount * psds->samplesperblock ;
-
/* Always Mono */
psf->sf.channels = 1 ;
psf->sf.sections = 1 ;
current = psf_ftell (psf) ;
if (calc_length)
- psf->sf.frames = psds->total_blocks * psds->samplesperblock + psds->write_count ;
+ psf->sf.frames = psds->total_written ;
if (psds->write_count > 0)
{ int current_count = psds->write_count ;
psf_binheader_writef (psf, "e213", 0, psds->bitwidth, samp_period) ;
- data_length = SDS_INT_TO_3BYTE_ENCODE (psds->total_blocks * SDS_BLOCK_SIZE) ;
+ data_length = SDS_INT_TO_3BYTE_ENCODE (psds->total_written) ;
sustain_loop_start = SDS_INT_TO_3BYTE_ENCODE (0) ;
- sustain_loop_end = SDS_INT_TO_3BYTE_ENCODE (psf->sf.frames) ;
+ sustain_loop_end = SDS_INT_TO_3BYTE_ENCODE (0) ;
psf_binheader_writef (psf, "e33311", data_length, sustain_loop_start, sustain_loop_end, loop_type, 0xF7) ;
{ printf ("Error 1 : %02X\n", checksum & 0xFF) ;
}
- for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
+ for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
checksum ^= psds->read_data [k] ;
checksum &= 0x7F ;
{ printf ("Error 1 : %02X\n", checksum & 0xFF) ;
}
- for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
+ for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
checksum ^= psds->read_data [k] ;
checksum &= 0x7F ;
{ printf ("Error 1 : %02X\n", checksum & 0xFF) ;
}
- for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
+ for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
checksum ^= psds->read_data [k] ;
checksum &= 0x7F ;
psds->write_data [0] = 0xF0 ;
psds->write_data [1] = 0x7E ;
psds->write_data [2] = 0 ; /* Channel number */
- psds->write_data [3] = psds->write_block & 0x7F ; /* Packet number */
+ psds->write_data [3] = 2 ;
+ psds->write_data [4] = psds->write_block & 0x7F ; /* Packet number */
ucptr = psds->write_data + 5 ;
for (k = 0 ; k < 120 ; k += 2)
} ;
checksum = psds->write_data [1] ;
- for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
+ for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
checksum ^= psds->write_data [k] ;
checksum &= 0x7F ;
psds->write_data [0] = 0xF0 ;
psds->write_data [1] = 0x7E ;
psds->write_data [2] = 0 ; /* Channel number */
- psds->write_data [3] = psds->write_block & 0x7F ; /* Packet number */
+ psds->write_data [3] = 2 ;
+ psds->write_data [4] = psds->write_block & 0x7F ; /* Packet number */
ucptr = psds->write_data + 5 ;
for (k = 0 ; k < 120 ; k += 3)
} ;
checksum = psds->write_data [1] ;
- for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
+ for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
checksum ^= psds->write_data [k] ;
checksum &= 0x7F ;
psds->write_data [0] = 0xF0 ;
psds->write_data [1] = 0x7E ;
psds->write_data [2] = 0 ; /* Channel number */
- psds->write_data [3] = psds->write_block & 0x7F ; /* Packet number */
+ psds->write_data [3] = 2 ;
+ psds->write_data [4] = psds->write_block & 0x7F ; /* Packet number */
ucptr = psds->write_data + 5 ;
for (k = 0 ; k < 120 ; k += 4)
} ;
checksum = psds->write_data [1] ;
- for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
+ for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
checksum ^= psds->write_data [k] ;
checksum &= 0x7F ;
if (psf->codec_data == NULL)
return 0 ;
psds = (SDS_PRIVATE*) psf->codec_data ;
+ psds->total_written += len ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
if (psf->codec_data == NULL)
return 0 ;
psds = (SDS_PRIVATE*) psf->codec_data ;
+ psds->total_written += len ;
total = sds_write (psf, psds, ptr, len) ;
if (psf->codec_data == NULL)
return 0 ;
psds = (SDS_PRIVATE*) psf->codec_data ;
+ psds->total_written += len ;
if (psf->norm_float == SF_TRUE)
normfact = 1.0 * 0x80000000 ;
if (psf->codec_data == NULL)
return 0 ;
psds = (SDS_PRIVATE*) psf->codec_data ;
+ psds->total_written += len ;
if (psf->norm_double == SF_TRUE)
normfact = 1.0 * 0x80000000 ;
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
#define S_IXUSR 0000100 /* execute/search permission, owner */
#endif
-#define S_IRWXG 0000070 /* rwx, group */
-#define S_IRGRP 0000040 /* read permission, group */
-#define S_IWGRP 0000020 /* write permission, grougroup */
-#define S_IXGRP 0000010 /* execute/search permission, group */
-
-#define S_IRWXO 0000007 /* rwx, other */
-#define S_IROTH 0000004 /* read permission, other */
-#define S_IWOTH 0000002 /* write permission, other */
-#define S_IXOTH 0000001 /* execute/search permission, other */
+/* Windows doesn't have group permissions so set all these to zero. */
+#define S_IRWXG 0 /* rwx, group */
+#define S_IRGRP 0 /* read permission, group */
+#define S_IWGRP 0 /* write permission, grougroup */
+#define S_IXGRP 0 /* execute/search permission, group */
+
+/* Windows doesn't have others permissions so set all these to zero. */
+#define S_IRWXO 0 /* rwx, other */
+#define S_IROTH 0 /* read permission, other */
+#define S_IWOTH 0 /* write permission, other */
+#define S_IXOTH 0 /* execute/search permission, other */
#ifndef S_ISFIFO
#define S_ISFIFO(mode) (((mode) & _S_IFMT) == _S_IFIFO)
/*
-** Copyright (C) 2005-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2005-2011 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
#define HAVE_STDINT_H 0
#endif
+#ifndef HAVE_SYS_WAIT_H
+#define HAVE_SYS_WAIT_H 0
+#endif
+
#ifndef HAVE_UNISTD_H
#define HAVE_UNISTD_H 0
#endif
+#ifndef HAVE_PIPE
+#define HAVE_PIPE 0
+#endif
+
+#ifndef HAVE_WAITPID
+#define HAVE_WAITPID 0
+#endif
+
#endif
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <assert.h>
#include "sndfile.h"
#include "sfendian.h"
{
/* Public error values and their associated strings. */
{ SF_ERR_NO_ERROR , "No Error." },
- { SF_ERR_UNRECOGNISED_FORMAT , "File opened for read. Format not recognised." },
+ { SF_ERR_UNRECOGNISED_FORMAT , "Format not recognised." },
{ SF_ERR_SYSTEM , "System error." /* Often replaced. */ },
{ SF_ERR_MALFORMED_FILE , "Supported file format but file is malformed." },
{ SF_ERR_UNSUPPORTED_ENCODING , "Supported file format but unsupported encoding." },
/* Private error values and their associated strings. */
{ SFE_ZERO_MAJOR_FORMAT , "Error : major format is 0." },
- { SFE_ZERO_MINOR_FORMAT , "Error : major format is 0." },
+ { SFE_ZERO_MINOR_FORMAT , "Error : minor format is 0." },
{ SFE_BAD_FILE , "File does not exist or is not a regular file (possibly a pipe?)." },
{ SFE_BAD_FILE_READ , "File exists but no data could be read." },
{ SFE_OPEN_FAILED , "Could not open file." },
{ SFE_NO_EMBEDDED_RDWR , "Error : cannot open embedded file read/write." },
{ SFE_NO_PIPE_WRITE , "Error : this file format does not support pipe write." },
{ SFE_BAD_VIRTUAL_IO , "Error : bad pointer on SF_VIRTUAL_IO struct." },
- { SFE_BAD_BROADCAST_INFO_SIZE, "Error : badd SF_BROADCAST_INFO_SIZE." },
+ { SFE_BAD_BROADCAST_INFO_SIZE
+ , "Error : bad size in SF_BROADCAST_INFO struct." },
+ { SFE_BAD_BROADCAST_INFO_TOO_BIG
+ , "Error : SF_BROADCAST_INFO struct too large." },
{ SFE_INTERLEAVE_MODE , "Attempt to write to file with non-interleaved data." },
{ SFE_INTERLEAVE_SEEK , "Bad karma in seek during interleave read operation." },
{ SFE_SEEK_FAILED , "Error : parameters OK, but psf_seek() failed." },
{ SFE_BAD_OPEN_MODE , "Error : bad mode parameter for file open." },
- { SFE_OPEN_PIPE_RDWR , "Error : attempt toopen a pipe in read/write mode." },
+ { SFE_OPEN_PIPE_RDWR , "Error : attempt to open a pipe in read/write mode." },
{ SFE_RDWR_POSITION , "Error on RDWR position (cryptic)." },
{ SFE_RDWR_BAD_HEADER , "Error : Cannot open file in read/write mode due to string data in header." },
{ SFE_CMD_HAS_DATA , "Error : Command fails because file already has audio data." },
{ SFE_PAF_VERSION , "Error in PAF file, bad version." },
{ SFE_PAF_UNKNOWN_FORMAT , "Error in PAF file, unknown format." },
{ SFE_PAF_SHORT_HEADER , "Error in PAF file. File shorter than minimal header." },
+ { SFE_PAF_BAD_CHANNELS , "Error in PAF file. Bad channel count." },
{ SFE_SVX_NO_FORM , "Error in 8SVX / 16SV file, no 'FORM' marker." },
{ SFE_SVX_NO_BODY , "Error in 8SVX / 16SV file, no 'BODY' marker." },
{ SFE_FLAC_INIT_DECODER , "Error : problem while initialization of the flac decoder." },
{ SFE_FLAC_LOST_SYNC , "Error : flac decoder lost sync." },
{ SFE_FLAC_BAD_SAMPLE_RATE, "Error : flac does not support this sample rate." },
- { SFE_FLAC_UNKOWN_ERROR , "Error : unkown error in flac decoder." },
+ { SFE_FLAC_UNKOWN_ERROR , "Error : unknown error in flac decoder." },
{ SFE_WVE_NOT_WVE , "Error : not a WVE file." },
{ SFE_WVE_NO_PIPE , "Error : not able to operate on WVE files over a pipe." },
static void save_header_info (SF_PRIVATE *psf) ;
static void copy_filename (SF_PRIVATE *psf, const char *path) ;
static int psf_close (SF_PRIVATE *psf) ;
-static SNDFILE * psf_open_file (SF_PRIVATE *psf, int mode, SF_INFO *sfinfo) ;
-static int try_resource_fork (SF_PRIVATE * psf, int mode) ;
+static int try_resource_fork (SF_PRIVATE * psf) ;
/*------------------------------------------------------------------------------
** Private (static) variables.
*/
-static int sf_errno = 0 ;
+int sf_errno = 0 ;
static char sf_logbuffer [SF_BUFFER_LEN] = { 0 } ;
static char sf_syserr [SF_SYSERR_LEN] = { 0 } ;
sf_open (const char *path, int mode, SF_INFO *sfinfo)
{ SF_PRIVATE *psf ;
+ /* Ultimate sanity check. */
+ assert (sizeof (sf_count_t) == 8) ;
+
if ((psf = calloc (1, sizeof (SF_PRIVATE))) == NULL)
{ sf_errno = SFE_MALLOC_FAILED ;
return NULL ;
copy_filename (psf, path) ;
+ psf->file.mode = mode ;
if (strcmp (path, "-") == 0)
- psf->error = psf_set_stdio (psf, mode) ;
+ psf->error = psf_set_stdio (psf) ;
else
- psf->error = psf_fopen (psf, path, mode) ;
+ psf->error = psf_fopen (psf) ;
- return psf_open_file (psf, mode, sfinfo) ;
+ return psf_open_file (psf, sfinfo) ;
} /* sf_open */
SNDFILE*
} ;
psf_init_files (psf) ;
+ copy_filename (psf, "") ;
+ psf->file.mode = mode ;
psf_set_file (psf, fd) ;
psf->is_pipe = psf_is_pipe (psf) ;
psf->fileoffset = psf_ftell (psf) ;
if (! close_desc)
- psf->do_not_close_descriptor = SF_TRUE ;
+ psf->file.do_not_close_descriptor = SF_TRUE ;
- return psf_open_file (psf, mode, sfinfo) ;
+ return psf_open_file (psf, sfinfo) ;
} /* sf_open_fd */
SNDFILE*
psf->vio = *sfvirtual ;
psf->vio_user_data = user_data ;
- psf->mode = mode ;
+ psf->file.mode = mode ;
- return psf_open_file (psf, mode, sfinfo) ;
+ return psf_open_file (psf, sfinfo) ;
} /* sf_open_virtual */
int
** Return 0 on failure, 1 ons success.
*/
- if (info->channels < 1 || info->channels > 256)
+ if (info->channels < 1 || info->channels > SF_MAX_CHANNELS)
return 0 ;
if (info->samplerate < 0)
switch (SF_CONTAINER (info->format))
{ case SF_FORMAT_WAV :
- case SF_FORMAT_WAVEX :
/* WAV now allows both endian, RIFF or RIFX (little or big respectively) */
if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_16)
return 1 ;
return 1 ;
break ;
+ case SF_FORMAT_WAVEX :
+ if (endian == SF_ENDIAN_BIG || endian == SF_ENDIAN_CPU)
+ return 0 ;
+ if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_16)
+ return 1 ;
+ if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
+ return 1 ;
+ if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
+ return 1 ;
+ if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
+ return 1 ;
+ break ;
+
case SF_FORMAT_AIFF :
/* AIFF does allow both endian-nesses for PCM data.*/
if (subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
break ;
case SF_FORMAT_PAF :
- if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16)
- return 1 ;
- if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
+ if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_24)
return 1 ;
break ;
case SF_FORMAT_SVX :
- /* SVX currently does not support more than one channel for write.
- ** Read will allow more than one channel but only allow one here.
- */
- if (info->channels != 1)
+ /* SVX only supports writing mono SVX files. */
+ if (info->channels > 1)
return 0 ;
/* Always big endian. */
if (endian == SF_ENDIAN_LITTLE || endian == SF_ENDIAN_CPU)
return 0 ;
- if ((subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16) && info->channels == 1)
+ if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16)
return 1 ;
break ;
break ;
case SF_FORMAT_IRCAM :
- if (subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
+ if (subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_32)
return 1 ;
if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW || subformat == SF_FORMAT_FLOAT)
return 1 ;
return 0 ;
} /* sf_format_check */
+/*------------------------------------------------------------------------------
+*/
+
+const char *
+sf_version_string (void)
+{
+#if ENABLE_EXPERIMENTAL_CODE
+ return PACKAGE_NAME "-" PACKAGE_VERSION "-exp" ;
+#else
+ return PACKAGE_NAME "-" PACKAGE_VERSION ;
+#endif
+}
+
+
/*------------------------------------------------------------------------------
*/
psf->error = SFE_BAD_COMMAND_PARAM ;
return SFE_BAD_COMMAND_PARAM ;
} ;
- if (ENABLE_EXPERIMENTAL_CODE)
- snprintf (data, datasize, "%s-%s-exp", PACKAGE_NAME, PACKAGE_VERSION) ;
- else
- snprintf (data, datasize, "%s-%s", PACKAGE_NAME, PACKAGE_VERSION) ;
+ snprintf (data, datasize, "%s", sf_version_string ()) ;
return strlen (data) ;
case SFC_GET_SIMPLE_FORMAT_COUNT :
if (sndfile == NULL && command == SFC_GET_LOG_INFO)
{ if (data == NULL)
- return (psf->error = SFE_BAD_COMMAND_PARAM) ;
+ return (sf_errno = SFE_BAD_COMMAND_PARAM) ;
snprintf (data, datasize, "%s", sf_logbuffer) ;
return strlen (data) ;
} ;
{ int format = SF_CONTAINER (psf->sf.format) ;
/* Only WAV and AIFF support the PEAK chunk. */
- if (format != SF_FORMAT_WAV && format != SF_FORMAT_WAVEX && format != SF_FORMAT_AIFF)
- return SF_FALSE ;
+ switch (format)
+ { case SF_FORMAT_AIFF :
+ case SF_FORMAT_CAF :
+ case SF_FORMAT_WAV :
+ case SF_FORMAT_WAVEX :
+ break ;
+
+ default :
+ return SF_FALSE ;
+ } ;
format = SF_CODEC (psf->sf.format) ;
} ;
/* Can only do this is in SFM_WRITE mode. */
- if (psf->mode != SFM_WRITE && psf->mode != SFM_RDWR)
+ if (psf->file.mode != SFM_WRITE && psf->file.mode != SFM_RDWR)
return SF_FALSE ;
/* If data has already been written this must fail. */
if (psf->have_written)
if (data == NULL || datasize != SIGNED_SIZEOF (SF_DITHER_INFO))
return (psf->error = SFE_BAD_COMMAND_PARAM) ;
memcpy (&psf->write_dither, data, sizeof (psf->write_dither)) ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
dither_init (psf, SFM_WRITE) ;
break ;
if (data == NULL || datasize != SIGNED_SIZEOF (SF_DITHER_INFO))
return (psf->error = SFE_BAD_COMMAND_PARAM) ;
memcpy (&psf->read_dither, data, sizeof (psf->read_dither)) ;
- if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
dither_init (psf, SFM_READ) ;
break ;
case SFC_FILE_TRUNCATE :
- if (psf->mode != SFM_WRITE && psf->mode != SFM_RDWR)
+ if (psf->file.mode != SFM_WRITE && psf->file.mode != SFM_RDWR)
return SF_TRUE ;
if (datasize != sizeof (sf_count_t))
return SF_TRUE ;
+ if (data == NULL || datasize != sizeof (sf_count_t))
+ { psf->error = SFE_BAD_COMMAND_PARAM ;
+ return SF_FALSE ;
+ }
+ else
{ sf_count_t position ;
position = *((sf_count_t*) data) ;
case SFC_SET_BROADCAST_INFO :
{ int format = SF_CONTAINER (psf->sf.format) ;
- /* Only WAV supports the BEXT (Broadcast) chunk. */
- if (format != SF_FORMAT_WAV && format != SF_FORMAT_WAVEX)
+ /* Only WAV and RF64 supports the BEXT (Broadcast) chunk. */
+ if (format != SF_FORMAT_WAV && format != SF_FORMAT_WAVEX && format != SF_FORMAT_RF64)
return SF_FALSE ;
} ;
/* Only makes sense in SFM_WRITE or SFM_RDWR mode. */
- if ((psf->mode != SFM_WRITE) && (psf->mode != SFM_RDWR))
+ if ((psf->file.mode != SFM_WRITE) && (psf->file.mode != SFM_RDWR))
return SF_FALSE ;
/* If data has already been written this must fail. */
- if (psf->broadcast_var == NULL && psf->have_written)
+ if (psf->broadcast_16k == NULL && psf->have_written)
{ psf->error = SFE_CMD_HAS_DATA ;
return SF_FALSE ;
} ;
case SFC_RAW_DATA_NEEDS_ENDSWAP :
return psf->data_endswap ;
+ case SFC_GET_CHANNEL_MAP_INFO :
+ if (psf->channel_map == NULL)
+ return SF_FALSE ;
+
+ if (data == NULL || datasize != SIGNED_SIZEOF (psf->channel_map [0]) * psf->sf.channels)
+ { psf->error = SFE_BAD_COMMAND_PARAM ;
+ return SF_FALSE ;
+ } ;
+
+ memcpy (data, psf->channel_map, datasize) ;
+ return SF_TRUE ;
+
+ case SFC_SET_CHANNEL_MAP_INFO :
+ if (psf->have_written)
+ { psf->error = SFE_CMD_HAS_DATA ;
+ return SF_FALSE ;
+ } ;
+ if (data == NULL || datasize != SIGNED_SIZEOF (psf->channel_map [0]) * psf->sf.channels)
+ { psf->error = SFE_BAD_COMMAND_PARAM ;
+ return SF_FALSE ;
+ } ;
+
+ { int *iptr ;
+
+ for (iptr = data ; iptr < (int*) data + psf->sf.channels ; iptr++)
+ { if (*iptr <= SF_CHANNEL_MAP_INVALID || *iptr >= SF_CHANNEL_MAP_MAX)
+ { psf->error = SFE_BAD_COMMAND_PARAM ;
+ return SF_FALSE ;
+ } ;
+ } ;
+ } ;
+
+ free (psf->channel_map) ;
+ if ((psf->channel_map = malloc (datasize)) == NULL)
+ { psf->error = SFE_MALLOC_FAILED ;
+ return SF_FALSE ;
+ } ;
+
+ memcpy (psf->channel_map, data, datasize) ;
+
+ /*
+ ** Pass the command down to the container's command handler.
+ ** Don't pass user data, use validated psf->channel_map data instead.
+ */
+ if (psf->command)
+ return psf->command (psf, command, NULL, 0) ;
+ return SF_FALSE ;
+
default :
/* Must be a file specific command. Pass it on. */
if (psf->command)
/* If the whence parameter has a mode ORed in, check to see that
** it makes sense.
*/
- if (((whence & SFM_MASK) == SFM_WRITE && psf->mode == SFM_READ) ||
- ((whence & SFM_MASK) == SFM_READ && psf->mode == SFM_WRITE))
+ if (((whence & SFM_MASK) == SFM_WRITE && psf->file.mode == SFM_READ) ||
+ ((whence & SFM_MASK) == SFM_READ && psf->file.mode == SFM_WRITE))
{ psf->error = SFE_WRONG_SEEK ;
return PSF_SEEK_ERROR ;
} ;
/* The SEEK_CUR is a little more tricky. */
case SEEK_CUR :
if (offset == 0)
- { if (psf->mode == SFM_READ)
+ { if (psf->file.mode == SFM_READ)
return psf->read_current ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
return psf->write_current ;
} ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
seek_from_start = psf->read_current + offset ;
- else if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ else if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
seek_from_start = psf->write_current + offset ;
else
psf->error = SFE_AMBIGUOUS_SEEK ;
if (psf->error)
return PSF_SEEK_ERROR ;
- if (psf->mode == SFM_RDWR || psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_RDWR || psf->file.mode == SFM_WRITE)
{ if (seek_from_start < 0)
{ psf->error = SFE_BAD_SEEK ;
return PSF_SEEK_ERROR ;
} ;
if (psf->seek)
- { int new_mode = (whence & SFM_MASK) ? (whence & SFM_MASK) : psf->mode ;
+ { int new_mode = (whence & SFM_MASK) ? (whence & SFM_MASK) : psf->file.mode ;
retval = psf->seek (psf, new_mode, seek_from_start) ;
bytewidth = (psf->bytewidth > 0) ? psf->bytewidth : 1 ;
blockwidth = (psf->blockwidth > 0) ? psf->blockwidth : 1 ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ psf->error = SFE_NOT_READMODE ;
return 0 ;
} ;
- if (bytes < 0 || psf->read_current >= psf->datalength)
+ if (bytes < 0 || psf->read_current >= psf->sf.frames)
{ psf_memset (ptr, 0, bytes) ;
return 0 ;
} ;
return 0 ;
} ;
+ if (psf->last_op != SFM_READ)
+ if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
+ return 0 ;
+
count = psf_fread (ptr, 1, bytes, psf) ;
if (psf->read_current + count / blockwidth <= psf->sf.frames)
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ psf->error = SFE_NOT_READMODE ;
return 0 ;
} ;
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ psf->error = SFE_NOT_READMODE ;
return 0 ;
} ;
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ psf->error = SFE_NOT_READMODE ;
return 0 ;
} ;
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ psf->error = SFE_NOT_READMODE ;
return 0 ;
} ;
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ psf->error = SFE_NOT_READMODE ;
return 0 ;
} ;
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ psf->error = SFE_NOT_READMODE ;
return 0 ;
} ;
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ psf->error = SFE_NOT_READMODE ;
return 0 ;
} ;
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ psf->error = SFE_NOT_READMODE ;
return 0 ;
} ;
bytewidth = (psf->bytewidth > 0) ? psf->bytewidth : 1 ;
blockwidth = (psf->blockwidth > 0) ? psf->blockwidth : 1 ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ psf->error = SFE_NOT_WRITEMODE ;
return 0 ;
} ;
return 0 ;
} ;
+ if (psf->last_op != SFM_WRITE)
+ if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
+ return 0 ;
+
if (psf->have_written == SF_FALSE && psf->write_header != NULL)
psf->write_header (psf, SF_FALSE) ;
psf->have_written = SF_TRUE ;
psf->write_current += count / blockwidth ;
+ psf->last_op = SFM_WRITE ;
+
+ if (psf->auto_header && psf->write_header != NULL)
+ psf->write_header (psf, SF_TRUE) ;
+
if (psf->write_current > psf->sf.frames)
psf->sf.frames = psf->write_current ;
- psf->last_op = SFM_WRITE ;
-
return count ;
} /* sf_write_raw */
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ psf->error = SFE_NOT_WRITEMODE ;
return 0 ;
} ;
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ psf->error = SFE_NOT_WRITEMODE ;
return 0 ;
} ;
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ psf->error = SFE_NOT_WRITEMODE ;
return 0 ;
} ;
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ psf->error = SFE_NOT_WRITEMODE ;
return 0 ;
} ;
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ psf->error = SFE_NOT_WRITEMODE ;
return 0 ;
} ;
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ psf->error = SFE_NOT_WRITEMODE ;
return 0 ;
} ;
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ psf->error = SFE_NOT_WRITEMODE ;
return 0 ;
} ;
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ psf->error = SFE_NOT_WRITEMODE ;
return 0 ;
} ;
*/
static int
-try_resource_fork (SF_PRIVATE * psf, int mode)
-{
- if (psf_open_rsrc (psf, mode) != 0)
+try_resource_fork (SF_PRIVATE * psf)
+{ int old_error = psf->error ;
+
+ /* Set READ mode now, to see if resource fork exists. */
+ psf->rsrc.mode = SFM_READ ;
+ if (psf_open_rsrc (psf) != 0)
+ { psf->error = old_error ;
return 0 ;
+ } ;
/* More checking here. */
- psf_log_printf (psf, "Resource fork : %s\n", psf->rsrcpath) ;
+ psf_log_printf (psf, "Resource fork : %s\n", psf->rsrc.path.c) ;
return SF_FORMAT_SD2 ;
} /* try_resource_fork */
char buffer [16] ;
int format = 0 ;
- if ((cptr = strrchr (psf->filename, '.')) == NULL)
+ if ((cptr = strrchr (psf->file.name.c, '.')) == NULL)
return 0 ;
cptr ++ ;
if (strlen (cptr) > sizeof (buffer) - 1)
return 0 ;
- strncpy (buffer, cptr, sizeof (buffer)) ;
+ psf_strlcpy (buffer, sizeof (buffer), cptr) ;
buffer [sizeof (buffer) - 1] = 0 ;
/* Convert everything in the buffer to lower case. */
if (buffer [0] == MAKE_MARKER ('f', 'L', 'a', 'C'))
return SF_FORMAT_FLAC ;
+ if (buffer [0] == MAKE_MARKER ('2', 'B', 'I', 'T'))
+ return SF_FORMAT_AVR ;
+
+ if (buffer [0] == MAKE_MARKER ('R', 'F', '6', '4') && buffer [2] == MAKE_MARKER ('W', 'A', 'V', 'E'))
+ return SF_FORMAT_RF64 ;
+
+ if (buffer [0] == MAKE_MARKER ('I', 'D', '3', 3))
+ { psf_log_printf (psf, "Found 'ID3' marker.\n") ;
+ if (id3_skip (psf))
+ return guess_file_type (psf) ;
+ return 0 ;
+ } ;
+
/* Turtle Beach SMP 16-bit */
if (buffer [0] == MAKE_MARKER ('S', 'O', 'U', 'N') && buffer [1] == MAKE_MARKER ('D', ' ', 'S', 'A'))
return 0 ;
+ /* Yamaha sampler format. */
if (buffer [0] == MAKE_MARKER ('S', 'Y', '8', '0') || buffer [0] == MAKE_MARKER ('S', 'Y', '8', '5'))
return 0 ;
if (buffer [0] == MAKE_MARKER ('a', 'j', 'k', 'g'))
return 0 /*-SF_FORMAT_SHN-*/ ;
- if (buffer [0] == MAKE_MARKER ('2', 'B', 'I', 'T'))
- return SF_FORMAT_AVR ;
-
- if (buffer [0] == MAKE_MARKER ('R', 'F', '6', '4') && buffer [2] == MAKE_MARKER ('W', 'A', 'V', 'E'))
- return SF_FORMAT_RF64 ;
-
- /* This must be the second last one. */
- if (psf->filelength > 0 && (format = try_resource_fork (psf, SFM_READ)) != 0)
+ /* This must be the last one. */
+ if (psf->filelength > 0 && (format = try_resource_fork (psf)) != 0)
return format ;
return 0 ;
{ const char *ccptr ;
char *cptr ;
- snprintf (psf->filepath, sizeof (psf->filepath), "%s", path) ;
+ snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", path) ;
if ((ccptr = strrchr (path, '/')) || (ccptr = strrchr (path, '\\')))
ccptr ++ ;
else
ccptr = path ;
- snprintf (psf->filename, sizeof (psf->filename), "%s", ccptr) ;
+ snprintf (psf->file.name.c, sizeof (psf->file.name.c), "%s", ccptr) ;
/* Now grab the directory. */
- snprintf (psf->directory, sizeof (psf->directory), "%s", path) ;
- if ((cptr = strrchr (psf->directory, '/')) || (cptr = strrchr (psf->directory, '\\')))
+ snprintf (psf->file.dir.c, sizeof (psf->file.dir.c), "%s", path) ;
+ if ((cptr = strrchr (psf->file.dir.c, '/')) || (cptr = strrchr (psf->file.dir.c, '\\')))
cptr [1] = 0 ;
else
- psf->directory [0] = 0 ;
+ psf->file.dir.c [0] = 0 ;
return ;
} /* copy_filename */
if (psf->peak_info)
free (psf->peak_info) ;
- if (psf->broadcast_var)
- free (psf->broadcast_var) ;
+ if (psf->broadcast_16k)
+ free (psf->broadcast_16k) ;
if (psf->loop_info)
free (psf->loop_info) ;
return error ;
} /* psf_close */
-static SNDFILE *
-psf_open_file (SF_PRIVATE *psf, int mode, SF_INFO *sfinfo)
+SNDFILE *
+psf_open_file (SF_PRIVATE *psf, SF_INFO *sfinfo)
{ int error, format ;
sf_errno = error = 0 ;
goto error_exit ;
} ;
- if (mode != SFM_READ && mode != SFM_WRITE && mode != SFM_RDWR)
+ if (psf->file.mode != SFM_READ && psf->file.mode != SFM_WRITE && psf->file.mode != SFM_RDWR)
{ error = SFE_BAD_OPEN_MODE ;
goto error_exit ;
} ;
sfinfo->sections = 0 ;
sfinfo->seekable = 0 ;
- if (mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ if ((SF_CONTAINER (sfinfo->format)) == SF_FORMAT_RAW)
{ if (sf_format_check (sfinfo) == 0)
{ error = SFE_RAW_BAD_FORMAT ;
psf->Magick = SNDFILE_MAGICK ;
psf->norm_float = SF_TRUE ;
psf->norm_double = SF_TRUE ;
- psf->mode = mode ;
psf->dataoffset = -1 ;
psf->datalength = -1 ;
psf->read_current = -1 ;
} ;
if (psf->fileoffset > 0)
- { switch (psf->mode)
+ { switch (psf->file.mode)
{ case SFM_READ :
if (psf->filelength < 44)
{ psf_log_printf (psf, "Short filelength: %D (fileoffset: %D)\n", psf->filelength, psf->fileoffset) ;
else
psf_log_printf (psf, "Length : %D\n", psf->filelength) ;
- if (mode == SFM_WRITE || (mode == SFM_RDWR && psf->filelength == 0))
+ if (psf->file.mode == SFM_WRITE || (psf->file.mode == SFM_RDWR && psf->filelength == 0))
{ /* If the file is being opened for write or RDWR and the file is currently
** empty, then the SF_INFO struct must contain valid data.
*/
{ error = SFE_ZERO_MAJOR_FORMAT ;
goto error_exit ;
} ;
- if ((SF_CONTAINER (psf->sf.format)) == 0)
+ if ((SF_CODEC (psf->sf.format)) == 0)
{ error = SFE_ZERO_MINOR_FORMAT ;
goto error_exit ;
} ;
} ;
/* Prevent unnecessary seeks */
- psf->last_op = psf->mode ;
+ psf->last_op = psf->file.mode ;
/* Set bytewidth if known. */
switch (SF_CODEC (psf->sf.format))
/* For now, check whether embedding is supported. */
format = SF_CONTAINER (psf->sf.format) ;
- if (psf->fileoffset > 0 &&
- (format != SF_FORMAT_WAV) && (format != SF_FORMAT_WAVEX) &&
- (format != SF_FORMAT_AIFF) && (format != SF_FORMAT_AU)
- )
- { error = SFE_NO_EMBED_SUPPORT ;
- goto error_exit ;
+ if (psf->fileoffset > 0)
+ { switch (format)
+ { case SF_FORMAT_WAV :
+ case SF_FORMAT_WAVEX :
+ case SF_FORMAT_AIFF :
+ case SF_FORMAT_AU :
+ /* Actual embedded files. */
+ break ;
+
+ case SF_FORMAT_FLAC :
+ /* Flac with an ID3v2 header? */
+ break ;
+
+ default :
+ error = SFE_NO_EMBED_SUPPORT ;
+ goto error_exit ;
+ } ;
} ;
if (psf->fileoffset > 0)
psf_log_printf (psf, "Embedded file length : %D\n", psf->filelength) ;
- if (mode == SFM_RDWR && sf_format_check (&(psf->sf)) == 0)
+ if (psf->file.mode == SFM_RDWR && sf_format_check (&(psf->sf)) == 0)
{ error = SFE_BAD_MODE_RW ;
goto error_exit ;
} ;
psf->read_current = 0 ;
psf->write_current = 0 ;
- if (psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_RDWR)
{ psf->write_current = psf->sf.frames ;
psf->have_written = psf->sf.frames > 0 ? SF_TRUE : SF_FALSE ;
} ;
break ;
default :
- if (psf->mode == SFM_READ)
+ if (psf->file.mode == SFM_READ)
{ psf_log_printf (psf, "Parse error : %s\n", sf_error_number (error)) ;
error = SF_ERR_MALFORMED_FILE ;
} ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011Erik 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
SF_STR_COMMENT = 0x05,
SF_STR_DATE = 0x06,
SF_STR_ALBUM = 0x07,
- SF_STR_LICENSE = 0x08
+ SF_STR_LICENSE = 0x08,
+ SF_STR_TRACKNUMBER = 0x09,
+ SF_STR_GENRE = 0x10
} ;
/*
*/
#define SF_STR_FIRST SF_STR_TITLE
-#define SF_STR_LAST SF_STR_LICENSE
+#define SF_STR_LAST SF_STR_GENRE
enum
{ /* True and false */
enum
{ SF_CHANNEL_MAP_INVALID = 0,
SF_CHANNEL_MAP_MONO = 1,
- SF_CHANNEL_MAP_LEFT,
- SF_CHANNEL_MAP_RIGHT,
- SF_CHANNEL_MAP_CENTER,
+ SF_CHANNEL_MAP_LEFT, /* Apple calls this 'Left' */
+ SF_CHANNEL_MAP_RIGHT, /* Apple calls this 'Right' */
+ SF_CHANNEL_MAP_CENTER, /* Apple calls this 'Center' */
SF_CHANNEL_MAP_FRONT_LEFT,
SF_CHANNEL_MAP_FRONT_RIGHT,
SF_CHANNEL_MAP_FRONT_CENTER,
- SF_CHANNEL_MAP_REAR_CENTER,
- SF_CHANNEL_MAP_REAR_LEFT,
- SF_CHANNEL_MAP_REAR_RIGHT,
- SF_CHANNEL_MAP_LFE,
- SF_CHANNEL_MAP_FRONT_LEFT_OF_CENTER,
- SF_CHANNEL_MAP_FRONT_RIGHT_OF_CENTER,
- SF_CHANNEL_MAP_SIDE_LEFT,
- SF_CHANNEL_MAP_SIDE_RIGHT,
- SF_CHANNEL_MAP_TOP_CENTER,
- SF_CHANNEL_MAP_TOP_FRONT_LEFT,
- SF_CHANNEL_MAP_TOP_FRONT_RIGHT,
- SF_CHANNEL_MAP_TOP_FRONT_CENTER,
- SF_CHANNEL_MAP_TOP_REAR_LEFT,
- SF_CHANNEL_MAP_TOP_REAR_RIGHT,
- SF_CHANNEL_MAP_TOP_REAR_CENTER
+ SF_CHANNEL_MAP_REAR_CENTER, /* Apple calls this 'Center Surround', Msft calls this 'Back Center' */
+ SF_CHANNEL_MAP_REAR_LEFT, /* Apple calls this 'Left Surround', Msft calls this 'Back Left' */
+ SF_CHANNEL_MAP_REAR_RIGHT, /* Apple calls this 'Right Surround', Msft calls this 'Back Right' */
+ SF_CHANNEL_MAP_LFE, /* Apple calls this 'LFEScreen', Msft calls this 'Low Frequency' */
+ SF_CHANNEL_MAP_FRONT_LEFT_OF_CENTER, /* Apple calls this 'Left Center' */
+ SF_CHANNEL_MAP_FRONT_RIGHT_OF_CENTER, /* Apple calls this 'Right Center */
+ SF_CHANNEL_MAP_SIDE_LEFT, /* Apple calls this 'Left Surround Direct' */
+ SF_CHANNEL_MAP_SIDE_RIGHT, /* Apple calls this 'Right Surround Direct' */
+ SF_CHANNEL_MAP_TOP_CENTER, /* Apple calls this 'Top Center Surround' */
+ SF_CHANNEL_MAP_TOP_FRONT_LEFT, /* Apple calls this 'Vertical Height Left' */
+ SF_CHANNEL_MAP_TOP_FRONT_RIGHT, /* Apple calls this 'Vertical Height Right' */
+ SF_CHANNEL_MAP_TOP_FRONT_CENTER, /* Apple calls this 'Vertical Height Center' */
+ SF_CHANNEL_MAP_TOP_REAR_LEFT, /* Apple and MS call this 'Top Back Left' */
+ SF_CHANNEL_MAP_TOP_REAR_RIGHT, /* Apple and MS call this 'Top Back Right' */
+ SF_CHANNEL_MAP_TOP_REAR_CENTER, /* Apple and MS call this 'Top Back Center' */
+
+ SF_CHANNEL_MAP_AMBISONIC_B_W,
+ SF_CHANNEL_MAP_AMBISONIC_B_X,
+ SF_CHANNEL_MAP_AMBISONIC_B_Y,
+ SF_CHANNEL_MAP_AMBISONIC_B_Z,
+
+ SF_CHANNEL_MAP_MAX
} ;
typedef struct SNDFILE_tag SNDFILE ;
/* The following typedef is system specific and is defined when libsndfile is
-** compiled. sf_count_t can be one of loff_t (Linux), off_t (*BSD), off64_t
-** (Solaris), __int64_t (Win32) etc. On windows, we need to allow the same
-** header file to be compiler by both GCC and the microsoft compiler.
+** compiled. sf_count_t will be a 64 bit value when the underlying OS allows
+** 64 bit file offsets.
+** 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 ;
+#if (defined (_MSCVER) || defined (_MSC_VER))
+typedef __int64 sf_count_t ;
#define SF_COUNT_MAX 0x7fffffffffffffffi64
#else
typedef @TYPEOF_SF_COUNT_T@ sf_count_t ;
#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 () and filled in.
** On write, the SF_INFO structure is filled in by the user and passed into
-** sf_open_write ().
+** sf_open ().
*/
struct SF_INFO
typedef struct SF_VIRTUAL_IO SF_VIRTUAL_IO ;
+
/* Open the specified file for read, write or both. On error, this will
** return a NULL pointer. To find the error number, pass a NULL SNDFILE
** to sf_strerror ().
SNDFILE* sf_open (const char *path, int mode, SF_INFO *sfinfo) ;
+
/* Use the existing file descriptor to create a SNDFILE object. If close_desc
** is TRUE, the file descriptor will be closed when sf_close() is called. If
** it is FALSE, the descritor will not be closed.
SNDFILE* sf_open_virtual (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data) ;
+
/* sf_error () returns a error number which can be translated to a text
** string using sf_error_number().
*/
int sf_error (SNDFILE *sndfile) ;
+
/* sf_strerror () returns to the caller a pointer to the current error message for
** the given SNDFILE.
*/
const char* sf_strerror (SNDFILE *sndfile) ;
+
/* sf_error_number () allows the retrieval of the error string for each internal
** error number.
**
const char* sf_error_number (int errnum) ;
+
/* The following two error functions are deprecated but they will remain in the
** library for the forseeable future. The function sf_strerror() should be used
** in their place.
int sf_command (SNDFILE *sndfile, int command, void *data, int datasize) ;
+
/* Return TRUE if fields of the SF_INFO struct are a valid combination of values. */
int sf_format_check (const SF_INFO *info) ;
+
/* Seek within the waveform data chunk of the SNDFILE. sf_seek () uses
** the same values for whence (SEEK_SET, SEEK_CUR and SEEK_END) as
** stdio.h function fseek ().
sf_count_t sf_seek (SNDFILE *sndfile, sf_count_t frames, int whence) ;
+
/* Functions for retrieving and setting string data within sound files.
** Not all file types support this features; AIFF and WAV do. For both
** functions, the str_type parameter must be one of the SF_STR_* values
const char* sf_get_string (SNDFILE *sndfile, int str_type) ;
+
+/* Return the library version string. */
+
+const char * sf_version_string (void) ;
+
+
/* Functions for reading/writing the waveform data of a sound file.
*/
sf_count_t sf_read_raw (SNDFILE *sndfile, void *ptr, sf_count_t bytes) ;
sf_count_t sf_write_raw (SNDFILE *sndfile, const void *ptr, sf_count_t bytes) ;
+
/* Functions for reading and writing the data chunk in terms of frames.
** The number of items actually read/written = frames * number of channels.
** sf_xxxx_raw read/writes the raw data bytes from/to the file
sf_count_t sf_readf_double (SNDFILE *sndfile, double *ptr, sf_count_t frames) ;
sf_count_t sf_writef_double (SNDFILE *sndfile, const double *ptr, sf_count_t frames) ;
+
/* Functions for reading and writing the data chunk in terms of items.
** Otherwise similar to above.
** All of these read/write function return number of items read/written.
sf_count_t sf_read_double (SNDFILE *sndfile, double *ptr, sf_count_t items) ;
sf_count_t sf_write_double (SNDFILE *sndfile, const double *ptr, sf_count_t items) ;
+
/* Close the SNDFILE and clean up all memory allocations associated with this
** file.
** Returns 0 on success, or an error number.
int sf_close (SNDFILE *sndfile) ;
+
/* If the file is opened SFM_WRITE or SFM_RDWR, call fsync() on the file
** to force the writing of data to disk. If the file is opened SFM_READ
** no action is taken.
void sf_write_sync (SNDFILE *sndfile) ;
+
+
+/* The function sf_wchar_open() is Windows Only!
+** Open a file passing in a Windows Unicode filename. Otherwise, this is
+** the same as sf_open().
+**
+** In order for this to work, you need to do the following:
+**
+** #include <windows.h>
+** #define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
+** #including <sndfile.h>
+*/
+
+#if (defined (ENABLE_SNDFILE_WINDOWS_PROTOTYPES) && ENABLE_SNDFILE_WINDOWS_PROTOTYPES)
+SNDFILE* sf_wchar_open (LPCWSTR wpath, int mode, SF_INFO *sfinfo) ;
+#endif
+
+
+
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* SNDFILE_H */
+
/*
-** Copyright (C) 2005-2007 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2005-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** All rights reserved.
**
int format = 0, int channels = 0, int samplerate = 0) ;
SndfileHandle (std::string const & path, int mode = SFM_READ,
int format = 0, int channels = 0, int samplerate = 0) ;
+ SndfileHandle (int fd, bool close_desc, int mode = SFM_READ,
+ int format = 0, int channels = 0, int samplerate = 0) ;
+
+#ifdef ENABLE_SNDFILE_WINDOWS_PROTOTYPES
+ SndfileHandle (LPCWSTR wpath, int mode = SFM_READ,
+ int format = 0, int channels = 0, int samplerate = 0) ;
+#endif
+
~SndfileHandle (void) ;
SndfileHandle (const SndfileHandle &orig) ;
sf_count_t readRaw (void *ptr, sf_count_t bytes) ;
sf_count_t writeRaw (const void *ptr, sf_count_t bytes) ;
+ /**< Raw access to the handle. SndfileHandle keeps ownership. */
+ SNDFILE * rawHandle (void) ;
+
+ /**< Take ownership of handle, iff reference count is 1. */
+ SNDFILE * takeOwnership (void) ;
} ;
/*==============================================================================
return ;
} /* SndfileHandle std::string constructor */
+inline
+SndfileHandle::SndfileHandle (int fd, bool close_desc, int mode, int fmt, int chans, int srate)
+: p (NULL)
+{
+ if (fd < 0)
+ return ;
+
+ p = new (std::nothrow) SNDFILE_ref () ;
+
+ if (p != NULL)
+ { p->ref = 1 ;
+
+ p->sfinfo.frames = 0 ;
+ p->sfinfo.channels = chans ;
+ p->sfinfo.format = fmt ;
+ p->sfinfo.samplerate = srate ;
+ p->sfinfo.sections = 0 ;
+ p->sfinfo.seekable = 0 ;
+
+ p->sf = sf_open_fd (fd, mode, &p->sfinfo, close_desc) ;
+ } ;
+
+ return ;
+} /* SndfileHandle fd constructor */
+
inline
SndfileHandle::~SndfileHandle (void)
{ if (p != NULL && --p->ref == 0)
{ return sf_get_string (p->sf, str_type) ; }
inline int
-SndfileHandle::formatCheck(int fmt, int chans, int srate)
+SndfileHandle::formatCheck (int fmt, int chans, int srate)
{
SF_INFO sfinfo ;
SndfileHandle::writeRaw (const void *ptr, sf_count_t bytes)
{ return sf_write_raw (p->sf, ptr, bytes) ; }
+inline SNDFILE *
+SndfileHandle::rawHandle (void)
+{ return (p ? p->sf : NULL) ; }
+
+inline SNDFILE *
+SndfileHandle::takeOwnership (void)
+{
+ if (p == NULL || (p->ref != 1))
+ return NULL ;
+
+ SNDFILE * sf = p->sf ;
+ p->sf = NULL ;
+ delete p ;
+ p = NULL ;
+ return sf ;
+}
+
+#ifdef ENABLE_SNDFILE_WINDOWS_PROTOTYPES
+
+inline
+SndfileHandle::SndfileHandle (LPCWSTR wpath, int mode, int fmt, int chans, int srate)
+: p (NULL)
+{
+ p = new (std::nothrow) SNDFILE_ref () ;
+
+ if (p != NULL)
+ { p->ref = 1 ;
+
+ p->sfinfo.frames = 0 ;
+ p->sfinfo.channels = chans ;
+ p->sfinfo.format = fmt ;
+ p->sfinfo.samplerate = srate ;
+ p->sfinfo.sections = 0 ;
+ p->sfinfo.seekable = 0 ;
+
+ p->sf = sf_wchar_open (wpath, mode, &p->sfinfo) ;
+ } ;
+
+ return ;
+} /* SndfileHandle const wchar_t * constructor */
+
+#endif
#endif /* SNDFILE_HH */
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
int
psf_store_string (SF_PRIVATE *psf, int str_type, const char *str)
-{ static char lsf_name [] = PACKAGE "-" VERSION ;
- static char bracket_name [] = " (" PACKAGE "-" VERSION ")" ;
- int k, str_len, len_remaining, str_flags, str_type_replace = 0 ;
+{ char new_str [128] ;
+ size_t len_remaining, str_len ;
+ int k, str_flags ;
if (str == NULL)
return SFE_STR_BAD_STRING ;
str_len = strlen (str) ;
/* A few extra checks for write mode. */
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if ((psf->str_flags & SF_STR_ALLOW_START) == 0)
return SFE_STR_NO_SUPPORT ;
if (psf->have_written && (psf->str_flags & SF_STR_ALLOW_END) == 0)
/* Determine flags */
str_flags = SF_STR_LOCATE_START ;
- if (psf->mode == SFM_RDWR || psf->have_written || str_type_replace)
+ if (psf->file.mode == SFM_RDWR || psf->have_written)
{ if ((psf->str_flags & SF_STR_ALLOW_END) == 0)
return SFE_STR_NO_ADD_END ;
str_flags = SF_STR_LOCATE_END ;
if (k == 0)
psf->str_end = psf->str_storage ;
- len_remaining = SIGNED_SIZEOF (psf->str_storage) - (psf->str_end - psf->str_storage) ;
-
- if (len_remaining < str_len + 2)
- return SFE_STR_MAX_DATA ;
-
switch (str_type)
{ case SF_STR_SOFTWARE :
/* In write mode, want to append libsndfile-version to string. */
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
- { psf->strings [k].type = str_type ;
- psf->strings [k].str = psf->str_end ;
- psf->strings [k].flags = str_flags ;
-
- memcpy (psf->str_end, str, str_len + 1) ;
- psf->str_end += str_len ;
-
- /*
- ** If the supplied string does not already contain a
- ** libsndfile-X.Y.Z component, then add it.
- */
- if (strstr (str, PACKAGE) == NULL && len_remaining > (int) (strlen (bracket_name) + str_len + 2))
- { if (strlen (str) == 0)
- strncat (psf->str_end, lsf_name, len_remaining) ;
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
+ { if (strstr (str, PACKAGE) == NULL)
+ { /*
+ ** If the supplied string does not already contain a
+ ** libsndfile-X.Y.Z component, then add it.
+ */
+ if (strlen (str) == 0)
+ snprintf (new_str, sizeof (new_str), "%s-%s", PACKAGE, VERSION) ;
else
- strncat (psf->str_end, bracket_name, len_remaining) ;
- psf->str_end += strlen (psf->str_end) ;
- } ;
+ snprintf (new_str, sizeof (new_str), "%s (%s-%s)", str, PACKAGE, VERSION) ;
+ }
+ else
+ snprintf (new_str, sizeof (new_str), "%s", str) ;
- /* Plus one to catch string terminator. */
- psf->str_end += 1 ;
- break ;
+ str = new_str ;
} ;
-
- /* Fall though if not write mode. */
+ break ;
case SF_STR_TITLE :
case SF_STR_COPYRIGHT :
case SF_STR_DATE :
case SF_STR_ALBUM :
case SF_STR_LICENSE :
- psf->strings [k].type = str_type ;
- psf->strings [k].str = psf->str_end ;
- psf->strings [k].flags = str_flags ;
-
- /* Plus one to catch string terminator. */
- memcpy (psf->str_end, str, str_len + 1) ;
- psf->str_end += str_len + 1 ;
+ case SF_STR_TRACKNUMBER :
+ case SF_STR_GENRE :
break ;
default :
return SFE_STR_BAD_TYPE ;
} ;
+ str_len = strlen (str) ;
+
+ len_remaining = SIGNED_SIZEOF (psf->str_storage) - (psf->str_end - psf->str_storage) ;
+
+ if (len_remaining < str_len + 2)
+ return SFE_STR_MAX_DATA ;
+
+ psf->strings [k].type = str_type ;
+ psf->strings [k].str = psf->str_end ;
+ psf->strings [k].flags = str_flags ;
+
+ memcpy (psf->str_end, str, str_len + 1) ;
+ /* Plus one to catch string terminator. */
+ psf->str_end += str_len + 1 ;
+
psf->str_flags |= str_flags ;
#if STRINGS_DEBUG
int
psf_set_string (SF_PRIVATE *psf, int str_type, const char *str)
-{ if (psf->mode == SFM_READ)
+{ if (psf->file.mode == SFM_READ)
return SFE_STR_NOT_WRITE ;
return psf_store_string (psf, str_type, str) ;
printf ("%02X ", ptr [k] & 0xFF) ;
printf (" ") ;
for (k = 0 ; k < 16 ; k++)
- printf ("%c", isprint (ptr [k]) ? ptr [k] : '.') ;
+ printf ("%c", psf_isprint (ptr [k]) ? ptr [k] : '.') ;
puts ("") ;
ptr += 16 ;
len -= 16 ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
svx_open (SF_PRIVATE *psf)
{ int error ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = svx_read_header (psf)))
return error ;
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
} ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
memset (&vhdr, 0, sizeof (vhdr)) ;
psf_binheader_readf (psf, "p", 0) ;
- /* Set default number of channels. Currently can't handle stereo SVX files. */
+ /* Set default number of channels. Modify later if necessary */
psf->sf.channels = 1 ;
psf->sf.format = SF_FORMAT_SVX ;
psf_log_printf (psf, " %M : %d\n", marker, dword) ;
- if (strlen (psf->filename) != dword)
- { if (dword > sizeof (psf->filename) - 1)
+ if (strlen (psf->file.name.c) != dword)
+ { if (dword > sizeof (psf->file.name.c) - 1)
return SFE_SVX_BAD_NAME_LENGTH ;
- psf_binheader_readf (psf, "b", psf->filename, dword) ;
- psf->filename [dword] = 0 ;
+ psf_binheader_readf (psf, "b", psf->file.name.c, dword) ;
+ psf->file.name.c [dword] = 0 ;
}
else
psf_binheader_readf (psf, "j", dword) ;
psf_log_printf (psf, " %M : %d\n", marker, dword) ;
bytecount += psf_binheader_readf (psf, "E4", &channels) ;
- psf->sf.channels = channels ;
- psf_log_printf (psf, " Channels : %d\n", channels) ;
+ if (channels == 2 || channels == 4)
+ psf_log_printf (psf, " Channels : %d => mono\n", channels) ;
+ else if (channels == 6)
+ { psf->sf.channels = 2 ;
+ psf_log_printf (psf, " Channels : %d => stereo\n", channels) ;
+ }
+ else
+ psf_log_printf (psf, " Channels : %d *** assuming mono\n", channels) ;
psf_binheader_readf (psf, "j", dword - bytecount) ;
break ;
break ;
default :
- if (isprint ((marker >> 24) & 0xFF) && isprint ((marker >> 16) & 0xFF)
- && isprint ((marker >> 8) & 0xFF) && isprint (marker & 0xFF))
+ if (psf_isprint ((marker >> 24) & 0xFF) && psf_isprint ((marker >> 16) & 0xFF)
+ && psf_isprint ((marker >> 8) & 0xFF) && psf_isprint (marker & 0xFF))
{ psf_binheader_readf (psf, "E4", &dword) ;
psf_log_printf (psf, "%M : %d (unknown marker)\n", marker, dword) ;
static int
svx_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
svx_write_header (psf, SF_TRUE) ;
return 0 ;
/* VHDR : volume */
psf_binheader_writef (psf, "E4", (psf->bytewidth == 1) ? 0xFF : 0xFFFF) ;
+ if (psf->sf.channels == 2)
+ psf_binheader_writef (psf, "Em44", CHAN_MARKER, 4, 6) ;
+
/* Filename and annotation strings. */
- psf_binheader_writef (psf, "Emsms", NAME_MARKER, psf->filename, ANNO_MARKER, annotation) ;
+ psf_binheader_writef (psf, "Emsms", NAME_MARKER, psf->file.name.c, ANNO_MARKER, annotation) ;
/* BODY marker and size. */
psf_binheader_writef (psf, "Etm8", BODY_MARKER, (psf->datalength < 0) ?
/*
-** Copyright (C) 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2007-2011 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
ad.endianness = SF_ENDIAN_LITTLE ;
ad.channels = 1 ;
if (audio_detect (&psf, &ad, float_le_mono, sizeof (float_le_mono)) != SF_FORMAT_FLOAT)
- { if (errors == 0) puts ("\nFailed tests :\n") ;
- puts (" float_le_mono") ;
+ { puts (" float_le_mono") ;
errors ++ ;
} ;
/*
-** Copyright (C) 2006-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2006-2011 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
#include <stdio.h>
#include <stdlib.h>
-#include <stdint.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
psf = &sf_private ;
memset (psf, 0, sizeof (sf_private)) ;
- if (psf_fopen (psf, filename, SFM_WRITE) != 0)
+ psf->file.mode = SFM_WRITE ;
+ snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
+
+ if (psf_fopen (psf) != 0)
{ printf ("\n\nError : failed to open file '%s' for write.\n\n", filename) ;
exit (1) ;
} ;
psf_fclose (psf) ;
memset (psf, 0, sizeof (sf_private)) ;
- if (psf_fopen (psf, filename, SFM_READ) != 0)
+
+ psf->file.mode = SFM_READ ;
+ snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
+
+ if (psf_fopen (psf) != 0)
{ printf ("\n\nError : failed to open file '%s' for read.\n\n", filename) ;
exit (1) ;
} ;
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
[+ AutoGen5 template c +]
/*
-** Copyright (C) 2002-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
#include <string.h>
#include <errno.h>
+#include <inttypes.h>
#include "common.h"
exit (1) ;
} ;
- snprintf (psf->filename, sizeof (psf->filename), "%s", filename) ;
+ psf->file.mode = SFM_READ ;
+ snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
/* Test that open for read fails if the file doesn't exist. */
- error = psf_fopen (psf, psf->filename, SFM_READ) ;
+ error = psf_fopen (psf) ;
if (error == 0)
{ printf ("\n\nLine %d: psf_fopen() should have failed.\n\n", __LINE__) ;
exit (1) ;
psf->error = SFE_NO_ERROR ;
/* Test file open in write mode. */
- psf->mode = SFM_WRITE ;
+ psf->file.mode = SFM_WRITE ;
test_open_or_die (psf, __LINE__) ;
test_close_or_die (psf, __LINE__) ;
- unlink (psf->filename) ;
+ unlink (psf->file.path.c) ;
/* Test file open in read/write mode for a non-existant file. */
- psf->mode = SFM_RDWR ;
+ psf->file.mode = SFM_RDWR ;
test_open_or_die (psf, __LINE__) ;
test_close_or_die (psf, __LINE__) ;
/* Test file open in read/write mode for an existing file. */
- psf->mode = SFM_RDWR ;
+ psf->file.mode = SFM_RDWR ;
test_open_or_die (psf, __LINE__) ;
test_close_or_die (psf, __LINE__) ;
- unlink (psf->filename) ;
+ unlink (psf->file.path.c) ;
puts ("ok") ;
} /* file_open_test */
memset (&sf_data, 0, sizeof (sf_data)) ;
psf = &sf_data ;
- snprintf (psf->filename, sizeof (psf->filename), "%s", filename) ;
+ snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
/* Test file open in write mode. */
- psf->mode = SFM_WRITE ;
+ psf->file.mode = SFM_WRITE ;
test_open_or_die (psf, __LINE__) ;
make_data (data_out, ARRAY_LEN (data_out), 1) ;
test_write_or_die (psf, data_out, sizeof (data_out [0]), ARRAY_LEN (data_out), sizeof (data_out), __LINE__) ;
if ((retval = psf_get_filelen (psf)) != sizeof (data_out))
- { printf ("\n\nLine %d: file length after write is not correct (%ld should be %d).\n\n", __LINE__, (long) retval, (int) sizeof (data_out)) ;
+ { printf ("\n\nLine %d: file length after write is not correct (%" PRId64 " should be %zd).\n\n", __LINE__, retval, sizeof (data_out)) ;
if (retval == 0)
printf ("An fsync() may be necessary before fstat() in psf_get_filelen().\n\n") ;
exit (1) ;
test_write_or_die (psf, data_out, ARRAY_LEN (data_out), sizeof (data_out [0]), 2 * sizeof (data_out), __LINE__) ;
if ((retval = psf_get_filelen (psf)) != 2 * sizeof (data_out))
- { printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 2 * ((int) sizeof (data_out))) ;
+ { printf ("\n\nLine %d: file length after write is not correct. (%" PRId64 " should be %zd)\n\n", __LINE__, retval, 2 * sizeof (data_out)) ;
exit (1) ;
} ;
print_test_name ("Testing file read") ;
/* Test file open in write mode. */
- psf->mode = SFM_READ ;
+ psf->file.mode = SFM_READ ;
test_open_or_die (psf, __LINE__) ;
make_data (data_out, ARRAY_LEN (data_out), 1) ;
print_test_name ("Testing file seek") ;
/* Test file open in read/write mode. */
- psf->mode = SFM_RDWR ;
+ psf->file.mode = SFM_RDWR ;
test_open_or_die (psf, __LINE__) ;
test_seek_or_die (psf, 0, SEEK_SET, 0, __LINE__) ;
print_test_name ("Testing file offset") ;
/* Test file open in read/write mode. */
- psf->mode = SFM_RDWR ;
+ psf->file.mode = SFM_RDWR ;
psf->fileoffset = sizeof (data_out [0]) * ARRAY_LEN (data_out) ;
test_open_or_die (psf, __LINE__) ;
if ((retval = psf_get_filelen (psf)) != 3 * sizeof (data_out))
- { printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 3 * ((int) sizeof (data_out))) ;
+ { printf ("\n\nLine %d: file length after write is not correct. (%" PRId64 " should be %zd)\n\n", __LINE__, retval, 3 * sizeof (data_out)) ;
exit (1) ;
} ;
/* final test with psf->fileoffset == 0. */
- psf->mode = SFM_RDWR ;
+ psf->file.mode = SFM_RDWR ;
psf->fileoffset = 0 ;
test_open_or_die (psf, __LINE__) ;
if ((retval = psf_get_filelen (psf)) != 3 * sizeof (data_out))
- { printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 3 * ((int) sizeof (data_out))) ;
+ { printf ("\n\nLine %d: file length after write is not correct. (%" PRId64 " should be %zd)\n\n", __LINE__, retval, 3 * sizeof (data_out)) ;
exit (1) ;
} ;
memset (buffer, 0xEE, sizeof (buffer)) ;
psf = &sf_data ;
- snprintf (psf->filename, sizeof (psf->filename), "%s", filename) ;
+ snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
/*
** Open the file write mode, write 0xEE data and then extend the file
** using truncate (the extended data should be 0x00).
*/
- psf->mode = SFM_WRITE ;
+ psf->file.mode = SFM_WRITE ;
test_open_or_die (psf, __LINE__) ;
test_write_or_die (psf, buffer, sizeof (buffer) / 2, 1, sizeof (buffer) / 2, __LINE__) ;
psf_ftruncate (psf, sizeof (buffer)) ;
test_close_or_die (psf, __LINE__) ;
/* Open the file in read mode and check the data. */
- psf->mode = SFM_READ ;
+ psf->file.mode = SFM_READ ;
test_open_or_die (psf, __LINE__) ;
test_read_or_die (psf, buffer, sizeof (buffer), 1, sizeof (buffer), __LINE__) ;
test_close_or_die (psf, __LINE__) ;
} ;
/* Open the file in read/write and shorten the file using truncate. */
- psf->mode = SFM_RDWR ;
+ psf->file.mode = SFM_RDWR ;
test_open_or_die (psf, __LINE__) ;
psf_ftruncate (psf, sizeof (buffer) / 4) ;
test_close_or_die (psf, __LINE__) ;
/* Check the file length. */
- psf->mode = SFM_READ ;
+ psf->file.mode = SFM_READ ;
test_open_or_die (psf, __LINE__) ;
test_seek_or_die (psf, 0, SEEK_END, SIGNED_SIZEOF (buffer) / 4, __LINE__) ;
test_close_or_die (psf, __LINE__) ;
{ int error ;
/* Test that open for read fails if the file doesn't exist. */
- error = psf_fopen (psf, psf->filename, psf->mode) ;
+ error = psf_fopen (psf) ;
if (error)
{ printf ("\n\nLine %d: psf_fopen() failed : %s\n\n", linenum, strerror (errno)) ;
exit (1) ;
{
psf_fclose (psf) ;
if (psf_file_valid (psf))
- { printf ("\n\nLine %d: psf->filedes should not be valid.\n\n", linenum) ;
+ { printf ("\n\nLine %d: psf->file.filedes should not be valid.\n\n", linenum) ;
exit (1) ;
} ;
retval = psf_fwrite (data, bytes, items, psf) ;
if (retval != items)
- { printf ("\n\nLine %d: psf_write() returned %ld (should be %ld)\n\n", linenum, (long) retval, (long) items) ;
+ { printf ("\n\nLine %d: psf_write() returned %" PRId64 " (should be %" PRId64 ")\n\n", linenum, retval, items) ;
exit (1) ;
} ;
if ((retval = psf_ftell (psf)) != new_position)
- { printf ("\n\nLine %d: file length after write is not correct. (%ld should be %ld)\n\n", linenum, (long) retval, (long) new_position) ;
+ { printf ("\n\nLine %d: file length after write is not correct. (%" PRId64 " should be %" PRId64 ")\n\n", linenum, retval, new_position) ;
exit (1) ;
} ;
retval = psf_fread (data, bytes, items, psf) ;
if (retval != items)
- { printf ("\n\nLine %d: psf_write() returned %ld (should be %ld)\n\n", linenum, (long) retval, (long) items) ;
+ { printf ("\n\nLine %d: psf_write() returned %" PRId64 " (should be %" PRId64 ")\n\n", linenum, retval, items) ;
exit (1) ;
} ;
if ((retval = psf_ftell (psf)) != new_position)
- { printf ("\n\nLine %d: file length after write is not correct. (%ld should be %ld)\n\n", linenum, (long) retval, (long) new_position) ;
+ { printf ("\n\nLine %d: file length after write is not correct. (%" PRId64 " should be %" PRId64 ")\n\n", linenum, retval, new_position) ;
exit (1) ;
} ;
retval = psf_fseek (psf, offset, whence) ;
if (retval != new_position)
- { printf ("\n\nLine %d: psf_fseek() failed. New position is %ld (should be %ld).\n\n",
- linenum, (long) retval, (long) new_position) ;
+ { printf ("\n\nLine %d: psf_fseek() failed. New position is %" PRId64 " (should be %" PRId64 ").\n\n",
+ linenum, retval, new_position) ;
exit (1) ;
} ;
/*
-** Copyright (C) 2006-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2006-2011 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
/*
+** Copyright (C) 2007-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (c) 2007 <robs@users.sourceforge.net>
-** Copyright (C) 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** 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
** Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
+#include "sfconfig.h"
+
#include <stdio.h>
#include "test_main.h"
print_test_name ("Testing ima/oki decoder") ;
ima_oki_adpcm_init (&adpcm, IMA_OKI_ADPCM_TYPE_OKI) ;
- for (i = 0 ; i < ARRAY_LEN (test_pcm) - 1 ; i += j)
+ for (i = 0 ; i < ARRAY_LEN (test_pcm) - 1 ; i += 2)
{ code = adpcm_encode (&adpcm, test_pcm [i]) ;
code = (code << 4) | adpcm_encode (&adpcm, test_pcm [i + 1]) ;
if (code != test_codes [i / 2])
/*
-** Copyright (C) 2003-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2003-2011 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
/*
-** Copyright (C) 2008-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2008-2011 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
test_audio_detect () ;
test_ima_oki_adpcm () ;
+ test_psf_strlcpy_crlf () ;
+ test_broadcast_var () ;
+
return 0 ;
} /* main */
/*
-** Copyright (C) 2008-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2008-2011 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
void test_audio_detect (void) ;
void test_ima_oki_adpcm (void) ;
+
+void test_psf_strlcpy_crlf (void) ;
+void test_broadcast_var (void) ;
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
txw_open (SF_PRIVATE *psf)
{ int error ;
- if (psf->mode != SFM_READ)
+ if (psf->file.mode != SFM_READ)
return SFE_UNIMPLEMENTED ;
if ((error = txw_read_header (psf)))
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
int
ulaw_init (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
{ psf->read_short = ulaw_read_ulaw2s ;
psf->read_int = ulaw_read_ulaw2i ;
psf->read_float = ulaw_read_ulaw2f ;
psf->read_double = ulaw_read_ulaw2d ;
} ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ psf->write_short = ulaw_write_s2ulaw ;
psf->write_int = ulaw_write_i2ulaw ;
psf->write_float = ulaw_write_f2ulaw ;
else
psf->datalength = 0 ;
- psf->sf.frames = psf->datalength / psf->blockwidth ;
+ psf->sf.frames = psf->blockwidth > 0 ? psf->datalength / psf->blockwidth : 0 ;
return 0 ;
} /* ulaw_init */
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
if (psf->is_pipe)
return SFE_VOC_NO_PIPE ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = voc_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_VOC)
return SFE_BAD_OPEN_FORMAT ;
psf->endian = SF_ENDIAN_LITTLE ;
while (1)
- { int size ;
+ { unsigned size ;
short count ;
block_type = 0 ;
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) ;
+ if (size < sizeof (psf->header) - 1)
+ { 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, "j", size) ;
continue ;
case VOC_REPEAT :
static int
voc_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ /* Now we know for certain the length of the file we can re-write
** correct values for the FORM, 8SVX and BODY chunks.
*/
- unsigned byte = VOC_TERMINATOR ;
+ unsigned char byte = VOC_TERMINATOR ;
psf_fseek (psf, 0, SEEK_END) ;
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
vox_adpcm_init (SF_PRIVATE *psf)
{ IMA_OKI_ADPCM *pvox = NULL ;
- if (psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
- if (psf->mode == SFM_WRITE && psf->sf.channels != 1)
+ if (psf->file.mode == SFM_WRITE && psf->sf.channels != 1)
return SFE_CHANNEL_COUNT ;
if ((pvox = malloc (sizeof (IMA_OKI_ADPCM))) == NULL)
psf->codec_data = (void*) pvox ;
memset (pvox, 0, sizeof (IMA_OKI_ADPCM)) ;
- if (psf->mode == SFM_WRITE)
+ if (psf->file.mode == SFM_WRITE)
{ psf->write_short = vox_write_s ;
psf->write_int = vox_write_i ;
psf->write_float = vox_write_f ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
return SFE_MALLOC_FAILED ;
psf->container_data = wpriv ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR &&psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR &&psf->filelength > 0))
{ if ((error = w64_read_header (psf, &blockalign, &framesperblock)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
static int
w64_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
w64_write_header (psf, SF_TRUE) ;
return 0 ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2004-2005 David Viens <davidv@plogue.com>
**
** This program is free software; you can redistribute it and/or modify
#include <string.h>
#include <ctype.h>
#include <time.h>
+#include <inttypes.h>
#include "sndfile.h"
#include "sfendian.h"
#define clm_MARKER (MAKE_MARKER ('c', 'l', 'm', ' '))
#define elmo_MARKER (MAKE_MARKER ('e', 'l', 'm', 'o'))
#define cart_MARKER (MAKE_MARKER ('c', 'a', 'r', 't'))
+#define FLLR_MARKER (MAKE_MARKER ('F', 'L', 'L', 'R'))
#define exif_MARKER (MAKE_MARKER ('e', 'x', 'i', 'f'))
#define ever_MARKER (MAKE_MARKER ('e', 'v', 'e', 'r'))
#define IART_MARKER (MAKE_MARKER ('I', 'A', 'R', 'T'))
#define INAM_MARKER (MAKE_MARKER ('I', 'N', 'A', 'M'))
#define IENG_MARKER (MAKE_MARKER ('I', 'E', 'N', 'G'))
-#define IART_MARKER (MAKE_MARKER ('I', 'A', 'R', 'T'))
+#define IGNR_MARKER (MAKE_MARKER ('I', 'G', 'N', 'R'))
#define ICOP_MARKER (MAKE_MARKER ('I', 'C', 'O', 'P'))
#define IPRD_MARKER (MAKE_MARKER ('I', 'P', 'R', 'D'))
#define ISRC_MARKER (MAKE_MARKER ('I', 'S', 'R', 'C'))
static int exif_subchunk_parse (SF_PRIVATE *psf, unsigned int length) ;
static int wav_read_smpl_chunk (SF_PRIVATE *psf, unsigned int chunklen) ;
static int wav_read_acid_chunk (SF_PRIVATE *psf, unsigned int chunklen) ;
-static int wav_read_bext_chunk (SF_PRIVATE *psf, unsigned int chunklen) ;
-static int wav_write_bext_chunk (SF_PRIVATE *psf) ;
/*------------------------------------------------------------------------------
** Public function.
wpriv->wavex_ambisonic = SF_AMBISONIC_NONE ;
psf->str_flags = SF_STR_ALLOW_START | SF_STR_ALLOW_END ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = wav_read_header (psf, &blockalign, &framesperblock)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
else if (psf->endian != SF_ENDIAN_BIG)
psf->endian = SF_ENDIAN_LITTLE ;
- if (psf->mode != SFM_RDWR || psf->filelength < 44)
+ if (psf->file.mode != SFM_RDWR || psf->filelength < 44)
{ psf->filelength = 0 ;
psf->datalength = 0 ;
psf->dataoffset = 0 ;
/* By default, add the peak chunk to floating point files. Default behaviour
** can be switched off using sf_command (SFC_SET_PEAK_CHUNK, SF_FALSE).
*/
- if (psf->mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
+ if (psf->file.mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
{ if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
return SFE_MALLOC_FAILED ;
psf->peak_info->peak_loc = SF_PEAK_START ;
default : return SFE_UNIMPLEMENTED ;
} ;
- if (psf->mode == SFM_WRITE || (psf->mode == SFM_RDWR && psf->filelength == 0))
+ if (psf->file.mode == SFM_WRITE || (psf->file.mode == SFM_RDWR && psf->filelength == 0))
return psf->write_header (psf, SF_FALSE) ;
return error ;
{ WAV_PRIVATE *wpriv ;
WAV_FMT *wav_fmt ;
FACT_CHUNK fact_chunk ;
- unsigned dword = 0, marker, RIFFsize, done = 0 ;
+ unsigned dword = 0, marker, RIFFsize = 0, done = 0 ;
int parsestage = 0, error, format = 0 ;
char *cptr ;
if ((parsestage & (HAVE_RIFF | HAVE_WAVE | HAVE_fmt)) != (HAVE_RIFF | HAVE_WAVE | HAVE_fmt))
return SFE_WAV_NO_DATA ;
- if (psf->mode == SFM_RDWR && (parsestage & HAVE_other) != 0)
+ if (psf->file.mode == SFM_RDWR && (parsestage & HAVE_other) != 0)
return SFE_RDWR_BAD_HEADER ;
parsestage |= HAVE_data ;
psf_fseek (psf, psf->datalength, SEEK_CUR) ;
if (psf_ftell (psf) != psf->datalength + psf->dataoffset)
- psf_log_printf (psf, "*** psf_fseek past end error ***\n", dword, psf->dataoffset + psf->datalength) ;
+ psf_log_printf (psf, "*** psf_fseek past end error ***\n") ;
break ;
case fact_MARKER :
for (dword = 0 ; dword < (unsigned) psf->sf.channels ; dword++)
{ float value ;
unsigned int position ;
+
psf_binheader_readf (psf, "f4", &value, &position) ;
psf->peak_info->peaks [dword].value = value ;
psf->peak_info->peaks [dword].position = position ;
- snprintf (cptr, sizeof (psf->u.cbuf), " %2d %-12ld %g\n",
- dword, (long) psf->peak_info->peaks [dword].position, psf->peak_info->peaks [dword].value) ;
+ snprintf (cptr, sizeof (psf->u.cbuf), " %2d %-12" PRId64 " %g\n",
+ dword, psf->peak_info->peaks [dword].position, psf->peak_info->peaks [dword].value) ;
cptr [sizeof (psf->u.cbuf) - 1] = 0 ;
- psf_log_printf (psf, cptr) ;
+ psf_log_printf (psf, "%s", cptr) ;
} ;
psf->peak_info->peak_loc = ((parsestage & HAVE_data) == 0) ? SF_PEAK_START : SF_PEAK_END ;
case plst_MARKER :
case DISP_MARKER :
case MEXT_MARKER :
- parsestage |= HAVE_other ;
-
+ case FLLR_MARKER :
psf_binheader_readf (psf, "4", &dword) ;
psf_log_printf (psf, "%M : %u\n", marker, dword) ;
dword += (dword & 1) ;
break ;
default :
- parsestage |= HAVE_other ;
- if (isprint ((marker >> 24) & 0xFF) && isprint ((marker >> 16) & 0xFF)
- && isprint ((marker >> 8) & 0xFF) && isprint (marker & 0xFF))
+ if (psf_isprint ((marker >> 24) & 0xFF) && psf_isprint ((marker >> 16) & 0xFF)
+ && psf_isprint ((marker >> 8) & 0xFF) && psf_isprint (marker & 0xFF))
{ psf_binheader_readf (psf, "4", &dword) ;
psf_log_printf (psf, "*** %M : %d (unknown marker)\n", marker, dword) ;
psf_binheader_readf (psf, "j", dword) ;
if (psf_ftell (psf) & 0x03)
{ psf_log_printf (psf, " Unknown chunk marker at position %d. Resynching.\n", dword - 4) ;
psf_binheader_readf (psf, "j", -3) ;
+ /* File is too messed up so we prevent editing in RDWR mode here. */
+ parsestage |= HAVE_other ;
break ;
} ;
psf_log_printf (psf, "*** Unknown chunk marker (%X) at position %D. Exiting parser.\n", marker, psf_ftell (psf) - 4) ;
break ;
case SF_FORMAT_ULAW :
- fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ;
+ fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 ;
/* fmt : format, channels, samplerate */
psf_binheader_writef (psf, "4224", fmt_size, WAVE_FORMAT_MULAW, psf->sf.channels, psf->sf.samplerate) ;
/* fmt : bytespersec */
psf_binheader_writef (psf, "4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
- /* fmt : blockalign, bitwidth */
- psf_binheader_writef (psf, "22", psf->bytewidth * psf->sf.channels, 8) ;
+ /* fmt : blockalign, bitwidth, extrabytes */
+ psf_binheader_writef (psf, "222", psf->bytewidth * psf->sf.channels, 8, 0) ;
add_fact_chunk = SF_TRUE ;
break ;
case SF_FORMAT_ALAW :
- fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ;
+ fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 ;
/* fmt : format, channels, samplerate */
psf_binheader_writef (psf, "4224", fmt_size, WAVE_FORMAT_ALAW, psf->sf.channels, psf->sf.samplerate) ;
/* fmt : bytespersec */
psf_binheader_writef (psf, "4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
- /* fmt : blockalign, bitwidth */
- psf_binheader_writef (psf, "22", psf->bytewidth * psf->sf.channels, 8) ;
+ /* fmt : blockalign, bitwidth, extrabytes */
+ psf_binheader_writef (psf, "222", psf->bytewidth * psf->sf.channels, 8, 0) ;
add_fact_chunk = SF_TRUE ;
break ;
*/
if (wpriv->wavex_ambisonic != SF_AMBISONIC_NONE)
psf_binheader_writef (psf, "4", 0) ;
+ else if (wpriv->wavex_channelmask != 0)
+ psf_binheader_writef (psf, "4", wpriv->wavex_channelmask) ;
else
{ /*
** Ok some liberty is taken here to use the most commonly used channel masks
psf_binheader_writef (psf, "ft8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
} ;
- if (psf->broadcast_var != NULL)
+ if (psf->broadcast_16k != NULL)
wav_write_bext_chunk (psf) ;
if (psf->instrument != NULL)
type = (type == SF_LOOP_FORWARD ? 0 : type==SF_LOOP_BACKWARD ? 2 : type == SF_LOOP_ALTERNATING ? 1 : 32) ;
psf_binheader_writef (psf, "44", tmp, type) ;
- psf_binheader_writef (psf, "44", psf->instrument->loops [tmp].start, psf->instrument->loops [tmp].end) ;
+ psf_binheader_writef (psf, "44", psf->instrument->loops [tmp].start, psf->instrument->loops [tmp].end - 1) ;
psf_binheader_writef (psf, "44", 0, psf->instrument->loops [tmp].count) ;
} ;
} ;
psf_binheader_writef (psf, "ms", ICRD_MARKER, psf->strings [k].str) ;
break ;
+ case SF_STR_GENRE :
+ psf_binheader_writef (psf, "ms", IGNR_MARKER, psf->strings [k].str) ;
+ break ;
+
default :
break ;
} ;
static int
wav_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ wav_write_tailer (psf) ;
- if (psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_RDWR)
{ sf_count_t current = psf_ftell (psf) ;
/*
case SFC_WAVEX_GET_AMBISONIC :
return wpriv->wavex_ambisonic ;
+ case SFC_SET_CHANNEL_MAP_INFO :
+ wpriv->wavex_channelmask = wavex_gen_channel_mask (psf->channel_map, psf->sf.channels) ;
+ return (wpriv->wavex_channelmask != 0) ;
+
default :
break ;
} ;
case ICMT_MARKER :
case ICRD_MARKER :
case IENG_MARKER :
-
+ case IGNR_MARKER :
case INAM_MARKER :
case IPRD_MARKER :
case ISBJ_MARKER :
case ICRD_MARKER :
psf_store_string (psf, SF_STR_DATE, psf->u.cbuf) ;
break ;
+ case IGNR_MARKER :
+ psf_store_string (psf, SF_STR_GENRE, psf->u.cbuf) ;
+ break ;
} ;
} ;
if (j < ARRAY_LEN (psf->instrument->loops))
{ psf->instrument->loops [j].start = start ;
- psf->instrument->loops [j].end = end ;
+ psf->instrument->loops [j].end = end + 1 ;
psf->instrument->loops [j].count = count ;
switch (type)
return 0 ;
} /* wav_read_acid_chunk */
-static int
+int
wav_read_bext_chunk (SF_PRIVATE *psf, unsigned int chunksize)
{
- SF_BROADCAST_INFO* b ;
+ SF_BROADCAST_INFO_16K * b ;
unsigned int bytes = 0 ;
if (chunksize < WAV_BEXT_MIN_CHUNK_SIZE)
return 0 ;
} ;
+ if (chunksize >= sizeof (SF_BROADCAST_INFO_16K))
+ { psf_log_printf (psf, "bext : %u too big to be handled\n", chunksize) ;
+ psf_binheader_readf (psf, "j", chunksize) ;
+ return 0 ;
+ } ;
+
psf_log_printf (psf, "bext : %u\n", chunksize) ;
- if ((psf->broadcast_var = broadcast_var_alloc (chunksize + 128)) == NULL)
+ if ((psf->broadcast_16k = broadcast_var_alloc ()) == NULL)
{ psf->error = SFE_MALLOC_FAILED ;
return psf->error ;
} ;
- b = & psf->broadcast_var->binfo ;
+ b = psf->broadcast_16k ;
bytes += psf_binheader_readf (psf, "b", b->description, sizeof (b->description)) ;
bytes += psf_binheader_readf (psf, "b", b->originator, sizeof (b->originator)) ;
return 0 ;
} /* wav_read_bext_chunk */
-static int
+int
wav_write_bext_chunk (SF_PRIVATE *psf)
-{ SF_BROADCAST_INFO *b ;
+{ SF_BROADCAST_INFO_16K *b ;
- if (psf->broadcast_var == NULL)
+ if (psf->broadcast_16k == NULL)
return -1 ;
- b = & psf->broadcast_var->binfo ;
+ b = psf->broadcast_16k ;
psf_binheader_writef (psf, "m4", bext_MARKER, WAV_BEXT_MIN_CHUNK_SIZE + b->coding_history_size) ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2004-2005 David Viens <davidv@plogue.com>
**
** This program is free software; you can redistribute it and/or modify
} ;
#endif
+/* This stores which bit in dwChannelMask maps to which channel */
+static const struct chanmap_s
+{ int id ;
+ const char * name ;
+} channel_mask_bits [] =
+{ /* WAVEFORMATEXTENSIBLE doesn't distuingish FRONT_LEFT from LEFT */
+ { SF_CHANNEL_MAP_LEFT, "L" },
+ { SF_CHANNEL_MAP_RIGHT, "R" },
+ { SF_CHANNEL_MAP_CENTER, "C" },
+ { SF_CHANNEL_MAP_LFE, "LFE" },
+ { SF_CHANNEL_MAP_REAR_LEFT, "Ls" },
+ { SF_CHANNEL_MAP_REAR_RIGHT, "Rs" },
+ { SF_CHANNEL_MAP_FRONT_LEFT_OF_CENTER, "Lc" },
+ { SF_CHANNEL_MAP_FRONT_RIGHT_OF_CENTER, "Rc" },
+ { SF_CHANNEL_MAP_REAR_CENTER, "Cs" },
+ { SF_CHANNEL_MAP_SIDE_LEFT, "Sl" },
+ { SF_CHANNEL_MAP_SIDE_RIGHT, "Sr" },
+ { SF_CHANNEL_MAP_TOP_CENTER, "Tc" },
+ { SF_CHANNEL_MAP_TOP_FRONT_LEFT, "Tfl" },
+ { SF_CHANNEL_MAP_TOP_FRONT_CENTER, "Tfc" },
+ { SF_CHANNEL_MAP_TOP_FRONT_RIGHT, "Tfr" },
+ { SF_CHANNEL_MAP_TOP_REAR_LEFT, "Trl" },
+ { SF_CHANNEL_MAP_TOP_REAR_CENTER, "Trc" },
+ { SF_CHANNEL_MAP_TOP_REAR_RIGHT, "Trr" },
+} ;
+
/*------------------------------------------------------------------------------
* Private static functions.
*/
psf_log_printf (psf, " Format : 0x%X => %s\n", wav_fmt->format, wav_w64_format_str (wav_fmt->format)) ;
psf_log_printf (psf, " Channels : %d\n", wav_fmt->min.channels) ;
psf_log_printf (psf, " Sample Rate : %d\n", wav_fmt->min.samplerate) ;
- psf_log_printf (psf, " Block Align : %d\n", wav_fmt->min.blockalign) ;
- if (wav_fmt->min.blockalign == 0)
- { psf_log_printf (psf, "*** Error : wav_fmt->min.blockalign should not be zero.\n") ;
- return SFE_INTERNAL ;
- } ;
+ if (wav_fmt->format == WAVE_FORMAT_PCM && wav_fmt->min.blockalign == 0
+ && wav_fmt->min.bitwidth > 0 && wav_fmt->min.channels > 0)
+ { wav_fmt->min.blockalign = wav_fmt->min.bitwidth / 8 + (wav_fmt->min.bitwidth % 8 > 0 ? 1 : 0) ;
+ wav_fmt->min.blockalign *= wav_fmt->min.channels ;
+ psf_log_printf (psf, " Block Align : 0 (should be %d)\n", wav_fmt->min.blockalign) ;
+ }
+ else
+ psf_log_printf (psf, " Block Align : %d\n", wav_fmt->min.blockalign) ;
if (wav_fmt->format == WAVE_FORMAT_PCM && wav_fmt->min.bitwidth == 24 &&
wav_fmt->min.blockalign == 4 * wav_fmt->min.channels)
else
psf_log_printf (psf, " Bytes/sec : %d (should be %d)\n", wav_fmt->min.bytespersec, bytespersec) ;
-
psf->bytewidth = 2 ;
psf_log_printf (psf, " Extra Bytes : %d\n", wav_fmt->msadpcm.extrabytes) ;
psf_log_printf (psf, " Samples/Block : %d\n", wav_fmt->msadpcm.samplesperblock) ;
&(wav_fmt->ext.channelmask)) ;
psf_log_printf (psf, " Valid Bits : %d\n", wav_fmt->ext.validbits) ;
- psf_log_printf (psf, " Channel Mask : 0x%X\n", wav_fmt->ext.channelmask) ;
- bytesread +=
- psf_binheader_readf (psf, "422", &(wav_fmt->ext.esf.esf_field1), &(wav_fmt->ext.esf.esf_field2),
- &(wav_fmt->ext.esf.esf_field3)) ;
+ if (wav_fmt->ext.channelmask == 0)
+ psf_log_printf (psf, " Channel Mask : 0x0 (should not be zero)\n") ;
+ else
+ { unsigned bit ;
+
+ wpriv->wavex_channelmask = wav_fmt->ext.channelmask ;
+
+ /* It's probably wise to ignore the channel mask if it is all zero */
+ free (psf->channel_map) ;
+
+ if ((psf->channel_map = calloc (psf->sf.channels, sizeof (psf->channel_map [0]))) == NULL)
+ return SFE_MALLOC_FAILED ;
+
+ /* Terminate the buffer we're going to append_snprintf into. */
+ psf->u.cbuf [0] = 0 ;
+
+ for (bit = k = 0 ; bit < ARRAY_LEN (channel_mask_bits) ; bit++)
+ {
+ if (wav_fmt->ext.channelmask & (1 << bit))
+ { if (k > psf->sf.channels)
+ { psf_log_printf (psf, "*** More channel map bits than there are channels.\n") ;
+ break ;
+ } ;
+
+ psf->channel_map [k++] = channel_mask_bits [bit].id ;
+ append_snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), "%s, ", channel_mask_bits [bit].name) ;
+ } ;
+ } ;
+
+ /* Remove trailing ", ". */
+ bit = strlen (psf->u.cbuf) ;
+ psf->u.cbuf [--bit] = 0 ;
+ psf->u.cbuf [--bit] = 0 ;
+
+ if (k != psf->sf.channels)
+ { psf_log_printf (psf, " Channel Mask : 0x%X\n", wav_fmt->ext.channelmask) ;
+ psf_log_printf (psf, "*** Less channel map bits than there are channels.\n") ;
+ }
+ else
+ psf_log_printf (psf, " Channel Mask : 0x%X (%s)\n", wav_fmt->ext.channelmask, psf->u.cbuf) ;
+ } ;
+
+ bytesread += psf_binheader_readf (psf, "422", &(wav_fmt->ext.esf.esf_field1), &(wav_fmt->ext.esf.esf_field2), &(wav_fmt->ext.esf.esf_field3)) ;
/* compare the esf_fields with each known GUID? and print? */
psf_log_printf (psf, " Subformat\n") ;
subformat->esf_field4, make_size_t (8)) ;
} /* wavex_write_guid */
+
+int
+wavex_gen_channel_mask (const int *chan_map, int channels)
+{ int chan, mask = 0, bit = -1, last_bit = -1 ;
+
+ if (chan_map == NULL)
+ return 0 ;
+
+ for (chan = 0 ; chan < channels ; chan ++)
+ { int k ;
+
+ for (k = bit + 1 ; k < ARRAY_LEN (channel_mask_bits) ; k++)
+ if (chan_map [chan] == channel_mask_bits [k].id)
+ { bit = k ;
+ break ;
+ } ;
+
+ /* Check for bad sequence. */
+ if (bit <= last_bit)
+ return 0 ;
+
+ mask += 1 << bit ;
+ last_bit = bit ;
+ } ;
+
+ return mask ;
+} /* wavex_gen_channel_mask */
+
void
wav_w64_analyze (SF_PRIVATE *psf)
{ AUDIO_DETECT ad ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
typedef struct
{ /* For ambisonic commands */
int wavex_ambisonic ;
+ unsigned wavex_channelmask ;
/* Set to true when 'fmt ' chunk is ambiguous.*/
int fmt_is_broken ;
int wav_w64_read_fmt_chunk (SF_PRIVATE *psf, int fmtsize) ;
void wavex_write_guid (SF_PRIVATE *psf, const EXT_SUBFORMAT * subformat) ;
void wav_w64_analyze (SF_PRIVATE *psf) ;
+int wavex_gen_channel_mask (const int *chan_map, int channels) ;
+
+int wav_read_bext_chunk (SF_PRIVATE *psf, unsigned int chunksize) ;
+int wav_write_bext_chunk (SF_PRIVATE *psf) ;
#endif
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2007 Reuben Thomas
**
** This program is free software; you can redistribute it and/or modify
if (psf->is_pipe)
return SFE_WVE_NO_PIPE ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = wve_read_header (psf)))
return error ;
} ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_WVE)
return SFE_BAD_OPEN_FORMAT ;
static int
wve_close (SF_PRIVATE *psf)
{
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ /* Now we know for certain the length of the file we can re-write
** the header.
*/
/*
-** Copyright (C) 2003-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2003-2011 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
psf->codec_data = pxi ;
- if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+ if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = xi_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_XI)
return SFE_BAD_OPEN_FORMAT ;
psf->blockwidth = psf->bytewidth * psf->sf.channels ;
- if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
{ switch (psf->bytewidth)
{ case 1 :
psf->read_short = dpcm_read_dsc2s ;
} ;
} ;
- if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+ if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ switch (psf->bytewidth)
{ case 1 :
psf->write_short = dpcm_write_s2dsc ;
INCLUDES = -I$(top_srcdir)/src
-noinst_PROGRAMS = sfversion floating_point_test write_read_test \
+check_PROGRAMS = sfversion floating_point_test write_read_test \
lossy_comp_test error_test ulaw_test alaw_test dwvw_test \
peak_chunk_test command_test stdin_test stdout_test stdio_test \
pcm_test headerless_test pipe_test benchmark header_test misc_test \
raw_test string_test multi_file_test dither_test \
scale_clip_test win32_test fix_this aiff_rw_test virtual_io_test \
locale_test largefile_test win32_ordinal_test ogg_test vorbis_test \
- checksum_test external_libs_test $(CPP_TEST)
+ checksum_test external_libs_test rdwr_test format_check_test $(CPP_TEST)
noinst_HEADERS = dft_cmp.h utils.h generate.h
utils.tpl utils.def \
scale_clip_test.tpl scale_clip_test.def \
pipe_test.tpl pipe_test.def \
+ rdwr_test.tpl rdwr_test.def \
floating_point_test.tpl floating_point_test.def \
benchmark.tpl benchmark.def
EXTRA_DIST = $(autogen_sources)
+CLEANFILES = *~
+
+#===============================================================================
+# If we're cross compiling from Linux to Windows and running the test suite
+# under Wine, we need a symbolic link to the generated libsndfile DLL.
+
+if LINUX_MINGW_CROSS_TEST
+
+$(check_PROGRAMS) : libsndfile-1.dll
+
+libsndfile-1.dll :
+ ln -s $(top_builddir)/src/.libs/$@ $@
+
+clean-local :
+ -rm -f libsndfile-1.dll
+
+endif
+
+#===============================================================================
+
+check: test_wrapper.sh
+ sh test_wrapper.sh
+
+# Need this target to force building of test programs.
+checkprograms : $(check_PROGRAMS)
+
#===============================================================================
sfversion_SOURCES = sfversion.c
vorbis_test_SOURCES = vorbis_test.c utils.c
vorbis_test_LDADD = $(top_builddir)/src/libsndfile.la
+rdwr_test_SOURCES = rdwr_test.c utils.c
+rdwr_test_LDADD = $(top_builddir)/src/libsndfile.la
+
win32_test_SOURCES = win32_test.c
-win32_test_LDADD =
+# Link lib here so that generating the testsuite tarball works correctly.
+win32_test_LDADD = $(top_builddir)/src/libsndfile.la
win32_ordinal_test_SOURCES = win32_ordinal_test.c utils.c
win32_ordinal_test_LDADD = $(top_builddir)/src/libsndfile.la
external_libs_test_SOURCES = external_libs_test.c utils.c
external_libs_test_LDADD = $(top_builddir)/src/libsndfile.la
+format_check_test_SOURCES = format_check_test.c utils.c
+format_check_test_LDADD = $(top_builddir)/src/libsndfile.la
+
cpp_test_SOURCES = cpp_test.cc utils.c
cpp_test_LDADD = $(top_builddir)/src/libsndfile.la
pipe_test.c: pipe_test.def pipe_test.tpl
autogen --writable pipe_test.def
+rdwr_test.c: rdwr_test.def rdwr_test.tpl
+ autogen --writable rdwr_test.def
+
floating_point_test.c: floating_point_test.def floating_point_test.tpl
autogen --writable floating_point_test.def
autogen --writable benchmark.def
genfiles : write_read_test.c pcm_test.c header_test.c utils.c \
- scale_clip_test.c pipe_test.c floating_point_test.c benchmark.c
-
-#===============================================================================
-# If we're cross compiling from Linux to Windows and running the test suite
-# under Wine, we need a symbolic link to the generated libsndfile DLL.
-
-if LINUX_MINGW_CROSS_TEST
-
-$(noinst_PROGRAMS) : libsndfile-1.dll
-
-libsndfile-1.dll :
- ln -s $(top_builddir)/src/.libs/$@ $@
-
-clean-local :
- -rm -f libsndfile-1.dll
-
-endif
-
-#===============================================================================
-
-check: $(noinst_PROGRAMS) test_wrapper.sh
- sh test_wrapper.sh
+ scale_clip_test.c pipe_test.c floating_point_test.c rdwr_test.c \
+ benchmark.c
-
/*
-** Copyright (C) 2003-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2003-2011 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
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#if HAVE_UNISTD_H
#include <unistd.h>
const char *filename ;
int k ;
+ print_test_name ("alaw_test", "encoder") ;
+
filename = "test.raw" ;
- sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_ALAW ;
- sfinfo.samplerate = 44100 ;
- sfinfo.frames = 123456789 ; /* Wrong length. Library should correct this on sf_close. */
- sfinfo.channels = 1 ;
+ sf_info_setup (&sfinfo, SF_FORMAT_RAW | SF_FORMAT_ALAW, 44100, 1) ;
if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
{ printf ("sf_open_write failed with error : ") ;
sf_close (file) ;
- printf (" alaw_test : encoder ... ok\n") ;
+ puts ("ok") ;
+ print_test_name ("alaw_test", "decoder") ;
/* Now generate a file containing all possible 8 bit encoded
** sample values and write it to disk as alaw encoded.frames.
*/
sf_close (file) ;
- printf (" alaw_test : decoder ... ok\n") ;
+ puts ("ok") ;
unlink (filename) ;
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
[+ AutoGen5 template c +]
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
/*
-** Copyright (C) 2008-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2008-2011 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
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
broadcast_test ("broadcast.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ;
broadcast_rdwr_test ("broadcast.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ;
+
+ broadcast_test ("broadcast.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
+ broadcast_rdwr_test ("broadcast.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
test_count ++ ;
} ;
} ;
if (do_all || strcmp (argv [1], "chanmap") == 0)
- { channel_map_test ("chanmap.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
- channel_map_test ("chanmap.aiff" , SF_FORMAT_AIFF | SF_FORMAT_PCM_24) ;
+ { channel_map_test ("chanmap.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ;
+ channel_map_test ("chanmap.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
+ channel_map_test ("chanmap.aifc" , SF_FORMAT_AIFF | SF_FORMAT_PCM_16) ;
+ channel_map_test ("chanmap.caf" , SF_FORMAT_CAF | SF_FORMAT_PCM_16) ;
test_count ++ ;
} ;
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) ;
memset (&ininfo, 0, sizeof (ininfo)) ;
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)) ;
} ;
if (bc_read.coding_history_size < strlen (default_history) || memcmp (bc_read.coding_history, default_history, strlen (default_history)) != 0)
- { printf ("\n\nLine %d : unexpected coding history '%.*s'.\n\n", __LINE__, bc_read.coding_history_size, bc_read.coding_history) ;
+ { printf ("\n\n"
+ "Line %d : unexpected coding history '%.*s',\n"
+ " should be '%s'\n\n", __LINE__, bc_read.coding_history_size, bc_read.coding_history, default_history) ;
exit (1) ;
} ;
{ SNDFILE *file ;
SF_INFO sfinfo ;
int channel_map_read [4], channel_map_write [4] =
- { SF_CHANNEL_MAP_FRONT_LEFT, SF_CHANNEL_MAP_FRONT_CENTER,
- SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT
+ { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_LFE,
+ SF_CHANNEL_MAP_REAR_CENTER
} ;
print_test_name ("channel_map_test", filename) ;
sfinfo.format = filetype ;
sfinfo.channels = ARRAY_LEN (channel_map_read) ;
- /* Write file without channel map. */
- file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
- test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
- sf_close (file) ;
-
- /* Read file making sure no channel map exists. */
- file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
- exit_if_true (
- sf_command (file, SFC_GET_CHANNEL_MAP_INFO, channel_map_read, sizeof (channel_map_read)) != SF_FALSE,
- "\n\nLine %d : sf_command (SFC_GET_CHANNEL_MAP_INFO) should have failed.\n\n", __LINE__
- ) ;
- check_log_buffer_or_die (file, __LINE__) ;
- sf_close (file) ;
+ switch (filetype & SF_FORMAT_TYPEMASK)
+ { /* WAVEX and RF64 have a default channel map, even if you don't specify one. */
+ case SF_FORMAT_WAVEX :
+ case SF_FORMAT_RF64 :
+ /* Write file without channel map. */
+ file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
+ test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
+ sf_close (file) ;
+
+ /* Read file making default channel map exists. */
+ file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
+ exit_if_true (
+ sf_command (file, SFC_GET_CHANNEL_MAP_INFO, channel_map_read, sizeof (channel_map_read)) == SF_FALSE,
+ "\n\nLine %d : sf_command (SFC_GET_CHANNEL_MAP_INFO) should not have failed.\n\n", __LINE__
+ ) ;
+ check_log_buffer_or_die (file, __LINE__) ;
+ sf_close (file) ;
+ break ;
+
+ default :
+ break ;
+ } ;
/* Write file with a channel map. */
file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
- test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
exit_if_true (
sf_command (file, SFC_SET_CHANNEL_MAP_INFO, channel_map_write, sizeof (channel_map_write)) == SF_FALSE,
"\n\nLine %d : sf_command (SFC_SET_CHANNEL_MAP_INFO) failed.\n\n", __LINE__
) ;
+ test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ;
sf_close (file) ;
/* Read file making sure no channel map exists. */
/*
-** Copyright (C) 2006 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2006-2011 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
static float fbuffer [100] ;
static double dbuffer [100] ;
+static void
+ceeplusplus_wchar_test (void)
+{
+#if 0
+ LPCWSTR filename = L"wchar_test.wav" ;
+
+ print_test_name (__func__, "ceeplusplus_wchar_test.wav") ;
+
+ /* Use this scope to make sure the created file is closed. */
+ {
+ SndfileHandle file (filename, SFM_WRITE, SF_FORMAT_WAV | SF_FORMAT_PCM_16, 2, 44100) ;
+
+ if (file.refCount () != 1)
+ { printf ("\n\n%s %d : Error : Reference count (%d) should be 1.\n\n", __func__, __LINE__, file.refCount ()) ;
+ exit (1) ;
+ } ;
+
+ /* This should check that the file did in fact get created with a
+ ** wchar_t * filename.
+ */
+ exit_if_true (
+ GetFileAttributesW (filename) == INVALID_FILE_ATTRIBUTES,
+ "\n\nLine %d : GetFileAttributes failed.\n\n", __LINE__
+ ) ;
+ }
+
+ /* Use this because the file was created with CreateFileW. */
+ DeleteFileW (filename) ;
+
+ puts ("ok") ;
+#endif
+} /* ceeplusplus_wchar_test */
+
+
+
static void
create_file (const char * filename, int format)
{ SndfileHandle file ;
puts ("ok") ;
} /* ceeplusplus_extra_test */
+
+static void
+ceeplusplus_rawhandle_test (const char *filename)
+{
+ SNDFILE* handle ;
+ {
+ SndfileHandle file (filename) ;
+ handle = file.rawHandle () ;
+ sf_read_float (handle, fbuffer, ARRAY_LEN (fbuffer)) ;
+ }
+} /* ceeplusplus_rawhandle_test */
+
+static void
+ceeplusplus_takeOwnership_test (const char *filename)
+{
+ SNDFILE* handle ;
+ {
+ SndfileHandle file (filename) ;
+ handle = file.takeOwnership () ;
+ }
+
+ if (sf_read_float (handle, fbuffer, ARRAY_LEN (fbuffer)) <= 0)
+ { printf ("\n\n%s %d : error when taking ownership of handle.\n\n", __func__, __LINE__) ;
+ exit (1) ;
+ }
+
+ if (sf_close (handle) != 0)
+ { printf ("\n\n%s %d : cannot close file.\n\n", __func__, __LINE__) ;
+ exit (1) ;
+ }
+
+ SndfileHandle file (filename) ;
+ SndfileHandle file2 (file) ;
+
+ if (file2.takeOwnership ())
+ { printf ("\n\n%s %d : taking ownership of shared handle is not allowed.\n\n", __func__, __LINE__) ;
+ exit (1) ;
+ }
+} /* ceeplusplus_takeOwnership_test */
+
+static void
+ceeplusplus_handle_test (const char *filename, int format)
+{
+ print_test_name ("ceeplusplus_handle_test", filename) ;
+
+ create_file (filename, format) ;
+
+ if (0) ceeplusplus_rawhandle_test (filename) ;
+ ceeplusplus_takeOwnership_test (filename) ;
+
+ remove (filename) ;
+ puts ("ok") ;
+} /* ceeplusplus_test */
+
int
main (void)
{
ceeplusplus_test ("cpp_test.au", SF_FORMAT_AU | SF_FORMAT_FLOAT) ;
ceeplusplus_extra_test () ;
+ ceeplusplus_handle_test ("cpp_test.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
+
+ ceeplusplus_wchar_test () ;
return 0 ;
} /* main */
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
/*
-** Copyright (C) 2003-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2003-2011 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
{ SNDFILE *file ;
SF_INFO sfinfo ;
SF_DITHER_INFO dither ;
- int frames ;
filetype = filetype ;
sfinfo.channels = 1 ;
sfinfo.frames = 0 ;
- frames = BUFFER_LEN / sfinfo.channels ;
-
file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
/* Check for old version of the dither API. */
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <math.h>
#if HAVE_UNISTD_H
print_test_name ("dwvw_test", filename) ;
- sfinfo.format = format ;
- sfinfo.samplerate = 44100 ;
- sfinfo.frames = -1 ; /* Unknown! */
- sfinfo.channels = 1 ;
+ sf_info_setup (&sfinfo, format, 44100, 1) ;
file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
/* Generate random.frames. */
- k = 0 ;
for (k = 0 ; k < BUFFER_SIZE / 2 ; k++)
{ value = 0x7FFFFFFF * sin (123.0 / sfinfo.samplerate * 2 * k * M_PI) ;
write_buf [k] = bit_mask & lrint (value) ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
#include <unistd.h>
#endif
+#if OS_IS_WIN32
+#include <windows.h>
+#endif
+
#include <sndfile.h>
#include "utils.h"
fclose (file) ;
if (sf_close (sndfile) == 0)
- { printf ("\n\nLine %d : sf_close should not have returned zero.\n", __LINE__) ;
+ {
+#if OS_IS_WIN32
+ OSVERSIONINFOEX osvi ;
+
+ memset (&osvi, 0, sizeof (OSVERSIONINFOEX)) ;
+ osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX) ;
+
+ if (GetVersionEx ((OSVERSIONINFO *) &osvi))
+ { printf ("\n\nLine %d : sf_close should not have returned zero.\n", __LINE__) ;
+ printf ("\nHowever, this is a known bug in version %d.%d of windows so we'll ignore it.\n\n",
+ (int) osvi.dwMajorVersion, (int) osvi.dwMinorVersion) ;
+ } ;
+#else
+ printf ("\n\nLine %d : sf_close should not have returned zero.\n", __LINE__) ;
exit (1) ;
+#endif
} ;
unlink (filename) ;
/*
-** Copyright (C) 2008-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2008-2011 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
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
} ;
for (m = 0 ; m < 3 ; m++)
- { if ((k = sf_readf_int (file, data, 11)) != 11)
+ { int n ;
+
+ if ((k = sf_readf_int (file, data, 11)) != 11)
{ printf ("Line %d: Incorrect read length (11 => %d).\n", __LINE__, k) ;
exit (1) ;
} ;
for (k = 0 ; k < 11 ; k++)
if (error_function (data [k] / scale, orig [k + m * 11] / scale, margin))
{ printf ("Line %d: Incorrect sample (m = %d) (#%d : %d => %d).\n", __LINE__, m, k + m * 11, orig [k + m * 11], data [k]) ;
- for (m = 0 ; m < 1 ; m++)
- printf ("%d ", data [m]) ;
+ for (n = 0 ; n < 1 ; n++)
+ printf ("%d ", data [n]) ;
printf ("\n") ;
exit (1) ;
} ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
[+ AutoGen5 template c +]
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
/*
-** Copyright (C) 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2007-2011 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
maxabs = crappy_snare (output, len, 0, 0.95, maxabs) ;
maxabs = crappy_snare (output, len, len / 4, 0.85, maxabs) ;
maxabs = crappy_snare (output, len, 2 * len / 4, 0.85, maxabs) ;
- maxabs = crappy_snare (output, len, 3 * len / 4, 0.85, maxabs) ;
+ crappy_snare (output, len, 3 * len / 4, 0.85, maxabs) ;
write_mono_file (filename, format, 44100, output, len) ;
/*
-** Copyright (C) 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2007-2011 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
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
update_header_sub (const char *filename, int typemajor, int write_mode)
{ SNDFILE *outfile, *infile ;
SF_INFO sfinfo ;
- int k, frames ;
+ int k ;
sfinfo.samplerate = 44100 ;
sfinfo.format = (typemajor | SF_FORMAT_PCM_16) ;
sfinfo.channels = 1 ;
sfinfo.frames = 0 ;
- frames = BUFFER_LEN / sfinfo.channels ;
-
outfile = test_open_file_or_die (filename, write_mode, &sfinfo, SF_TRUE, __LINE__) ;
for (k = 0 ; k < BUFFER_LEN ; k++)
static void
extra_header_test (const char *filename, int filetype)
-{ SNDFILE *outfile ;
+{ SNDFILE *outfile, *infile ;
SF_INFO sfinfo ;
sf_count_t frames ;
short buffer [8] ;
frames = ARRAY_LEN (buffer) / sfinfo.channels ;
/* Test the file with extra header data. */
- outfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, 464) ;
+ outfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, 462) ;
sf_set_string (outfile, SF_STR_TITLE, filename) ;
- test_writef_short_or_die (outfile, k, buffer, frames, 466) ;
+ test_writef_short_or_die (outfile, k, buffer, frames, 464) ;
sf_set_string (outfile, SF_STR_COPYRIGHT, "(c) 1980 Erik") ;
sf_close (outfile) ;
** integration is done.
*/
- if (sf_open (filename, SFM_RDWR, &sfinfo) != NULL)
+ if ((infile = sf_open (filename, SFM_RDWR, &sfinfo)) != NULL)
{ printf ("\n\nError : should not be able to open this file in SFM_RDWR.\n\n") ;
exit (1) ;
} ;
hexdump_file (filename, 0, 100000) ;
/* Open again for read/write. */
- outfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, 493) ;
+ outfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, 491) ;
/*
** In auto header update mode, seeking to the end of the file with
memset (buffer, 0xA0 + k, sizeof (buffer)) ;
- test_seek_or_die (outfile, k * frames, SEEK_SET, k * frames, sfinfo.channels, 514) ;
- test_seek_or_die (outfile, 0, SEEK_END, k * frames, sfinfo.channels, 515) ;
+ test_seek_or_die (outfile, k * frames, SEEK_SET, k * frames, sfinfo.channels, 512) ;
+ test_seek_or_die (outfile, 0, SEEK_END, k * frames, sfinfo.channels, 513) ;
/* Open file again and make sure no errors in log buffer. */
if (0)
- { infile = test_open_file_or_die (filename, SFM_READ, &sfinfo, 519) ;
- check_log_buffer_or_die (infile, 520) ;
+ { infile = test_open_file_or_die (filename, SFM_READ, &sfinfo, 517) ;
+ check_log_buffer_or_die (infile, 518) ;
sf_close (infile) ;
} ;
if (sfinfo.frames != k * frames)
- { printf ("\n\nLine %d : Incorrect sample count (%ld should be %ld)\n", 525, SF_COUNT_TO_LONG (sfinfo.frames), SF_COUNT_TO_LONG (k + frames)) ;
+ { printf ("\n\nLine %d : Incorrect sample count (%ld should be %ld)\n", 523, SF_COUNT_TO_LONG (sfinfo.frames), SF_COUNT_TO_LONG (k + frames)) ;
dump_log_buffer (infile) ;
exit (1) ;
} ;
if ((k & 1) == 0)
- test_write_short_or_die (outfile, k, buffer, sfinfo.channels * frames, 531) ;
+ test_write_short_or_die (outfile, k, buffer, sfinfo.channels * frames, 529) ;
else
- test_writef_short_or_die (outfile, k, buffer, frames, 533) ;
+ test_writef_short_or_die (outfile, k, buffer, frames, 531) ;
hexdump_file (filename, 0, 100000) ;
} ;
[+ AutoGen5 template c +]
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
update_header_sub (const char *filename, int typemajor, int write_mode)
{ SNDFILE *outfile, *infile ;
SF_INFO sfinfo ;
- int k, frames ;
+ int k ;
sfinfo.samplerate = 44100 ;
sfinfo.format = (typemajor | SF_FORMAT_PCM_16) ;
sfinfo.channels = 1 ;
sfinfo.frames = 0 ;
- frames = BUFFER_LEN / sfinfo.channels ;
-
outfile = test_open_file_or_die (filename, write_mode, &sfinfo, SF_TRUE, __LINE__) ;
for (k = 0 ; k < BUFFER_LEN ; k++)
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
/*
-** Copyright (C) 2006-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2006-2011 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
/*
-** Copyright (C) 2005-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2005-2011 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
*/
#include "sfconfig.h"
-#include "sndfile.h"
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#endif
+#if OS_IS_WIN32
+#include <windows.h>
+#define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
+#endif
+
+#include "sndfile.h"
#include "utils.h"
+static void utf8_test (void) ;
+static void wchar_test (void) ;
+
+int
+main (void)
+{
+ utf8_test () ;
+ wchar_test () ;
+
+ return 0 ;
+} /* main */
+
+/*==============================================================================
+*/
+
+static void
+wchar_test (void)
+{
+#if OS_IS_WIN32
+ SNDFILE * file ;
+ SF_INFO info ;
+ LPCWSTR filename = L"test.wav" ;
+
+ print_test_name (__func__, "test.wav") ;
+
+ info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ;
+ info.channels = 1 ;
+ info.samplerate = 44100 ;
+
+ file = sf_wchar_open (filename, SFM_WRITE, &info) ;
+ exit_if_true (file == NULL, "\n\nLine %d : sf_wchar_open failed : %s\n\n", __LINE__, sf_strerror (NULL)) ;
+ sf_close (file) ;
+
+ /* This should check that the file did in fact get created with a
+ ** wchar_t * filename.
+ */
+ exit_if_true (
+ GetFileAttributesW (filename) == INVALID_FILE_ATTRIBUTES,
+ "\n\nLine %d : GetFileAttributes failed.\n\n", __LINE__
+ ) ;
+
+ /* Use this because the file was created with CreateFileW. */
+ DeleteFileW (filename) ;
+
+ puts ("ok") ;
+#endif
+} /* wchar_test */
+
+/*==============================================================================
+*/
+
typedef struct
{ const char *locale ;
+ int utf8 ;
const char *filename ;
int width ;
} LOCALE_DATA ;
-static void locale_test (const char * locname, const char * filename, int width) ;
+static void locale_test (const LOCALE_DATA * locdata) ;
-int
-main (void)
+static void
+utf8_test (void)
{ LOCALE_DATA ldata [] =
- { { "de_DE", "F\303\274\303\237e.au", 7 },
- { "en_AU", "kangaroo.au", 11 },
- { "POSIX", "posix.au", 8 },
- { "pt_PT", "concei\303\247\303\243o.au", 12 },
+ { { "de_DE", 1, "F\303\274\303\237e.au", 7 },
+ { "en_AU", 1, "kangaroo.au", 11 },
+ { "POSIX", 0, "posix.au", 8 },
+ { "pt_PT", 1, "concei\303\247\303\243o.au", 12 },
#if OS_IS_WIN32 == 0
- { "ja_JP", "\343\201\212\343\201\257\343\202\210\343\201\206\343\201\224\343\201\226\343\201\204\343\201\276\343\201\231.au", 21 },
- { "vi_VN", "qu\341\273\221c ng\341\273\257.au", 11 },
+ { "ja_JP", 1, "\343\201\212\343\201\257\343\202\210\343\201\206\343\201\224\343\201\226\343\201\204\343\201\276\343\201\231.au", 21 },
#endif
- { NULL, NULL, 0 }
+ { "vi_VN", 1, "qu\341\273\221c ng\341\273\257.au", 11 },
+ { NULL, 0, NULL, 0 }
} ;
int k ;
for (k = 0 ; ldata [k].locale != NULL ; k++)
- locale_test (ldata [k].locale, ldata [k].filename, ldata [k].width) ;
+ locale_test (ldata + k) ;
+} /* utf8_test */
- return 0 ;
-} /* main */
static void
-locale_test (const char * locname, const char * filename, int width)
+locale_test (const LOCALE_DATA * ldata)
{
#if (HAVE_LOCALE_H == 0 || HAVE_SETLOCALE == 0)
locname = filename = NULL ;
const short wdata [] = { 1, 2, 3, 4, 5, 6, 7, 8 } ;
short rdata [ARRAY_LEN (wdata)] ;
const char *old_locale ;
+ char utf8_locname [32] ;
SNDFILE *file ;
SF_INFO sfinfo ;
- /* Grab the old locale. */
- old_locale = setlocale (LC_ALL, NULL) ;
+ snprintf (utf8_locname, sizeof (utf8_locname), "%s%s", ldata->locale, ldata->utf8 ? ".UTF-8" : "") ;
- if (setlocale (LC_ALL, locname) == NULL)
+ /* Change the locale saving the old one. */
+ if ((old_locale = setlocale (LC_CTYPE, utf8_locname)) == NULL)
return ;
- printf (" locale_test : %-6s %s%*c : ", locname, filename, 28 - width, ' ') ;
+ printf (" locale_test %-8s : %s %*c ", ldata->locale, ldata->filename, 24 - ldata->width, ' ') ;
fflush (stdout) ;
sfinfo.format = SF_FORMAT_AU | SF_FORMAT_PCM_16 ;
sfinfo.channels = 1 ;
sfinfo.samplerate = 44100 ;
- file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, 0, __LINE__) ;
+ file = test_open_file_or_die (ldata->filename, SFM_WRITE, &sfinfo, 0, __LINE__) ;
test_write_short_or_die (file, 0, wdata, ARRAY_LEN (wdata), __LINE__) ;
sf_close (file) ;
- file = test_open_file_or_die (filename, SFM_READ, &sfinfo, 0, __LINE__) ;
+ file = test_open_file_or_die (ldata->filename, SFM_READ, &sfinfo, 0, __LINE__) ;
test_read_short_or_die (file, 0, rdata, ARRAY_LEN (rdata), __LINE__) ;
sf_close (file) ;
+ unlink (ldata->filename) ;
+
/* Restore old locale. */
- setlocale (LC_ALL, old_locale) ;
+ setlocale (LC_CTYPE, old_locale) ;
- unlink (filename) ;
puts ("ok") ;
#endif
} /* locale_test */
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
zero_data_test (const char *filename, int format)
{ SNDFILE *file ;
SF_INFO sfinfo ;
- int frames ;
switch (format & SF_FORMAT_TYPEMASK)
{ case SF_FORMAT_OGG :
sfinfo.channels = 1 ;
sfinfo.frames = 0 ;
- frames = BUFFER_LEN / sfinfo.channels ;
-
file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
sf_close (file) ;
struct stat buf ;
const char *filename = "/dev/full", *errorstr ;
- int frames ;
#if (defined (WIN32) || defined (_WIN32))
/* Can't run this test on Win32 so return. */
sfinfo.channels = 1 ;
sfinfo.frames = 0 ;
- frames = BUFFER_LEN / sfinfo.channels ;
-
if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) != NULL)
{ printf ("\n\nLine %d : Error, file should not have openned.\n", __LINE__ - 1) ;
exit (1) ;
SNDFILE *file ;
SF_INFO sfinfo ;
const char *errorstr ;
- int frames ;
/* Make sure errno is zero before doing anything else. */
errno = 0 ;
sfinfo.channels = 1 ;
sfinfo.frames = 0 ;
- frames = BUFFER_LEN / sfinfo.channels ;
-
if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) != NULL)
{ printf ("\n\nLine %d : Error, file should not have opened.\n", __LINE__ - 1) ;
exit (1) ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
SF_INFO sfinfo ;
SF_EMBED_FILE_INFO embed_info ;
sf_count_t filelen ;
- int fd, k, file_count = 0, open_perm ;
+ int fd, k, file_count = 0 ;
print_test_name ("multi_file_test", filename) ;
unlink (filename) ;
- open_perm = OS_IS_WIN32 ? 0 : S_IRUSR | S_IWUSR | S_IRGRP ;
-
- if ((fd = open (filename, O_RDWR | O_CREAT, open_perm)) < 0)
+ if ((fd = open (filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) < 0)
{ printf ("\n\nLine %d: open failed : %s\n", __LINE__, strerror (errno)) ;
exit (1) ;
} ;
embed_info.length = 0 ;
- for (file_count = 0 ; embed_info.offset + embed_info.length < filelen ; )
+ for (file_count = 1 ; embed_info.offset + embed_info.length < filelen ; file_count ++)
{
- file_count ++ ;
-
if (verbose)
{ puts ("\n------------------------------------") ;
printf ("This offset : %ld\n", SF_COUNT_TO_LONG (embed_info.offset + embed_info.length)) ;
printf ("\nNext offset : %ld\nNext length : %ld\n", SF_COUNT_TO_LONG (embed_info.offset), SF_COUNT_TO_LONG (embed_info.length)) ;
} ;
+ file_count -- ;
+
if (file_count != format_count)
{ printf ("\n\nLine %d: file count (%d) not equal to %d.\n\n", __LINE__, file_count, format_count) ;
printf ("Embedded file number : %d\n", file_count) ;
/*
-** Copyright (C) 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2007-2011 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
+++ /dev/null
-/*
-** Copyright (C) 2003,2004 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 "sfconfig.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <sndfile.h>
-
-#include "utils.h"
-
-int
-main (void)
-{ SNDFILE *sndfile ;
- SF_INFO sfinfo ;
-
- FILE *bad_file ;
- const char *bad_wav = "bad_wav.wav" ;
- const char bad_data [] = "RIFF WAVEfmt " ;
-
- print_test_name ("open_fail_test", bad_wav) ;
-
- memset (&sfinfo, 0, sizeof (sfinfo)) ;
-
- sndfile = sf_open ("let's hope this file doesn't exist", SFM_READ, &sfinfo) ;
-
- if (sndfile)
- { printf ("Line %d: should not have received a valid SNDFILE* pointer.\n", __LINE__) ;
- exit (1) ;
- } ;
-
- if ((bad_file = fopen (bad_wav, "w")) == NULL)
- { printf ("Line %d: fopen returned NULL.\n", __LINE__) ;
- exit (1) ;
- } ;
-
- fwrite (bad_data, sizeof (bad_data), 1, bad_file) ;
- fclose (bad_file) ;
-
- sndfile = sf_open (bad_wav, SFM_READ, &sfinfo) ;
-
- if (sndfile)
- { printf ("Line %d: should not have received a valid SNDFILE* pointer.\n", __LINE__) ;
- exit (1) ;
- } ;
-
- unlink (bad_wav) ;
- puts ("ok") ;
-
- 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: 24440323-00b1-4e4b-87c5-0e3b7e9605e9
-*/
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
pcm_test_double ("le-double.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, 0xc682726f958f669cLL, SF_FALSE) ;
pcm_test_double ("be-double.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, 0xd9a3583f8ee51164LL, SF_FALSE) ;
- puts ("Test IEEE replacement code.") ;
-
pcm_test_float ("le-float.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_FLOAT, 0x3c2ad04f7554267aLL, SF_TRUE) ;
pcm_test_float ("be-float.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_FLOAT, 0x074de3e248fa9186LL, SF_TRUE) ;
if (fabs (float_out [k] - float_in [k]) > 1e-10)
{ printf ("\n\nLine %d: float : Incorrect sample (#%d : %f => %f).\n", __LINE__, k, (double) float_out [k], (double) float_in [k]) ;
exit (1) ;
- break ;
} ;
sf_close (file) ;
if (fabs (float_out [k] - float_in [k]) > 1e-10)
{ printf ("\n\nLine %d: float : Incorrect sample (#%d : %f => %f).\n", __LINE__, k, (double) float_out [k], (double) float_in [k]) ;
exit (1) ;
- break ;
} ;
sf_close (file) ;
if (fabs (float_out [k] - float_in [k]) > 1e-10)
{ printf ("\n\nLine %d: float : Incorrect sample (#%d : %f => %f).\n", __LINE__, k, (double) float_out [k], (double) float_in [k]) ;
exit (1) ;
- break ;
} ;
sf_close (file) ;
if (fabs (float_out [k] - float_in [k]) > 1e-10)
{ printf ("\n\nLine %d: float : Incorrect sample (#%d : %f => %f).\n", __LINE__, k, (double) float_out [k], (double) float_in [k]) ;
exit (1) ;
- break ;
} ;
sf_close (file) ;
int sign ;
double *data, error ;
- print_test_name ("pcm_test_float", filename) ;
+ print_test_name (replace_float ? "pcm_test_float (replace)" : "pcm_test_float", filename) ;
items = BUFFER_SIZE ;
/* This is the best test routine. Other should be brought up to this standard. */
- print_test_name ("pcm_test_double", filename) ;
+ print_test_name (replace_float ? "pcm_test_double (replace)" : "pcm_test_double", filename) ;
items = BUFFER_SIZE ;
[+ AutoGen5 template c +]
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
pcm_test_double ("le-double.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, 0xc682726f958f669cLL, SF_FALSE) ;
pcm_test_double ("be-double.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_DOUBLE, 0xd9a3583f8ee51164LL, SF_FALSE) ;
- puts ("Test IEEE replacement code.") ;
-
pcm_test_float ("le-float.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_FLOAT, 0x3c2ad04f7554267aLL, SF_TRUE) ;
pcm_test_float ("be-float.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_FLOAT, 0x074de3e248fa9186LL, SF_TRUE) ;
if (fabs (float_out [k] - float_in [k]) > 1e-10)
{ printf ("\n\nLine %d: float : Incorrect sample (#%d : %f => %f).\n", __LINE__, k, (double) float_out [k], (double) float_in [k]) ;
exit (1) ;
- break ;
} ;
sf_close (file) ;
int sign ;
double *data, error ;
- print_test_name ("pcm_test_float", filename) ;
+ print_test_name (replace_float ? "pcm_test_float (replace)" : "pcm_test_float", filename) ;
items = BUFFER_SIZE ;
/* This is the best test routine. Other should be brought up to this standard. */
- print_test_name ("pcm_test_double", filename) ;
+ print_test_name (replace_float ? "pcm_test_double (replace)" : "pcm_test_double", filename) ;
items = BUFFER_SIZE ;
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
if (argc != 2)
{ printf ("Usage : %s <test>\n", argv [0]) ;
printf (" Where <test> is one of the following:\n") ;
- printf (" wav - test WAV file peak chunk\n") ;
printf (" aiff - test AIFF file PEAK chunk\n") ;
+ printf (" caf - test CAF file PEAK chunk\n") ;
+ printf (" wav - test WAV file peak chunk\n") ;
printf (" all - perform all tests\n") ;
exit (1) ;
} ;
test_count++ ;
} ;
+ if (do_all || ! strcmp (argv [1], "caf"))
+ { test_float_peak ("peak_float.caf", SF_FORMAT_CAF | SF_FORMAT_FLOAT) ;
+
+ read_write_peak_test ("rw_peak.caf", SF_FORMAT_CAF | SF_FORMAT_FLOAT) ;
+ test_count++ ;
+ } ;
+
if (test_count == 0)
{ printf ("Mono : ************************************\n") ;
printf ("Mono : * No '%s' test defined.\n", argv [1]) ;
exit (1) ;
} ;
- if (! (cptr = strstr (buffer, "Channels")) || sscanf (cptr, "Channels : %d", &channel_count) != 1)
+ channel_count = 0 ;
+ cptr = strstr (buffer, "Channels") ;
+ if (cptr && sscanf (cptr, "Channels : %d", &k) == 1)
+ channel_count = k ;
+ else if (cptr && sscanf (cptr, "Channels / frame : %d", &k) == 1)
+ channel_count = k ;
+ else
{ printf ("\n\nLine %d: Couldn't find channel count.\n", __LINE__) ;
exit (1) ;
} ;
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
#include <stdlib.h>
#include <string.h>
-#if (OS_IS_WIN32)
+#if (OS_IS_WIN32 || HAVE_PIPE == 0 || HAVE_WAITPID == 0)
int
main (void)
{
- puts (" pipe_test : this test doesn't work on win32.") ;
+ puts (" pipe_test : this test doesn't work on this OS.") ;
return 0 ;
} /* main */
[+ AutoGen5 template c +]
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
#include <stdlib.h>
#include <string.h>
-#if (OS_IS_WIN32)
+#if (OS_IS_WIN32 || HAVE_PIPE == 0 || HAVE_WAITPID == 0)
int
main (void)
{
- puts (" pipe_test : this test doesn't work on win32.") ;
+ puts (" pipe_test : this test doesn't work on this OS.") ;
return 0 ;
} /* main */
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
{ SNDFILE *sndfile ;
SF_INFO sfinfo ;
sf_count_t start ;
- int k, frames ;
+ int k ;
print_test_name ("raw_offset_test", filename) ;
sfinfo.channels = 1 ;
sfinfo.frames = 0 ;
- frames = BUFFER_LEN / sfinfo.channels ;
-
sndfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ;
start = 0 ;
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
[+ AutoGen5 template c +]
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include "sfconfig.h"
-
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
#include <sndfile.h>
#define BUFFER_SIZE (256)
-static char strbuffer [BUFFER_SIZE] ;
int
main (void)
-{ sf_command (NULL, SFC_GET_LIB_VERSION, strbuffer, sizeof (strbuffer)) ;
+{ static char strbuffer [BUFFER_SIZE] ;
+ const char * ver ;
+
+ sf_command (NULL, SFC_GET_LIB_VERSION, strbuffer, sizeof (strbuffer)) ;
+ ver = sf_version_string () ;
+
+ if (strcmp (ver, strbuffer) != 0)
+ { printf ("Version mismatch : '%s' != '%s'\n\n", ver, strbuffer) ;
+ exit (1) ;
+ } ;
printf ("%s", strbuffer) ;
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
SNDFILE *file ;
SF_INFO sfinfo ;
- int k, total ;
+ int k, total, err ;
if (typemajor == SF_FORMAT_RAW)
{ sfinfo.samplerate = 44100 ;
sfinfo.frames = 0 ;
}
else
- sfinfo.format = 0 ;
+ memset (&sfinfo, 0, sizeof (sfinfo)) ;
- if (! (file = sf_open ("-", SFM_READ, &sfinfo)))
- { fprintf (stderr, "sf_open_read failed with error : ") ;
+ if ((file = sf_open_fd (STDIN_FILENO, SFM_READ, &sfinfo, SF_TRUE)) == NULL)
+ { fprintf (stderr, "sf_open_fd failed with error : ") ;
puts (sf_strerror (NULL)) ;
dump_log_buffer (NULL) ;
exit (1) ;
} ;
+ err = sf_error (file) ;
+ if (err != SF_ERR_NO_ERROR)
+ { printf ("Line %d : unexpected error : %s\n", __LINE__, sf_error_number (err)) ;
+ exit (1) ;
+ } ;
+
if ((sfinfo.format & SF_FORMAT_TYPEMASK) != typemajor)
{ fprintf (stderr, "\n\nError : File type doesn't match.\n") ;
exit (1) ;
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
#include "utils.h"
-#if (OS_IS_WIN32)
+/* EMX is OS/2. */
+#if (OS_IS_WIN32) || defined (__EMX__)
int
main (void)
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
/*
-** Copyright (C) 2003-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2003-2011 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
static void string_rdwr_test (const char *filename, int typemajor) ;
static void string_short_rdwr_test (const char *filename, int typemajor) ;
+static void software_string_test (const char *filename) ;
+
static int str_count (const char * haystack, const char * needle) ;
int
string_multi_set_test ("multi.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV) ;
string_rdwr_test ("rdwr.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV) ;
string_short_rdwr_test ("short_rdwr.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV) ;
+
+ software_string_test ("software_string.wav") ;
test_count++ ;
} ;
license [] = "The license",
title [] = "This is the title",
long_title [] = "This is a very long and very boring title for this file",
- long_artist [] = "The artist who kept on changing its name" ;
+ long_artist [] = "The artist who kept on changing its name",
+ genre [] = "The genre",
+ trackno [] = "Track three" ;
static short data_out [BUFFER_LEN] ;
{ const char *cptr ;
SNDFILE *file ;
SF_INFO sfinfo ;
- int frames, errors = 0 ;
+ int errors = 0 ;
typemajor = typemajor ;
sfinfo.frames = 0 ;
sfinfo.format = typemajor | SF_FORMAT_PCM_16 ;
- frames = BUFFER_LEN / sfinfo.channels ;
-
file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
/* Write stuff at start of file. */
sf_set_string (file, SF_STR_TITLE, filename) ;
sf_set_string (file, SF_STR_SOFTWARE, software) ;
sf_set_string (file, SF_STR_ARTIST, artist) ;
+ sf_set_string (file, SF_STR_GENRE, genre) ;
+ sf_set_string (file, SF_STR_TRACKNUMBER, trackno) ;
/* Write data to file. */
test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ;
puts ("\n") ;
printf (" Bad date : %s\n", cptr) ;
} ;
+
+ cptr = sf_get_string (file, SF_STR_GENRE) ;
+ if (cptr == NULL || strcmp (genre, cptr) != 0)
+ { if (errors++ == 0)
+ puts ("\n") ;
+ printf (" Bad genre : %s\n", cptr) ;
+ } ;
} ;
switch (typemajor)
printf (" Bad license : %s\n", cptr) ;
} ;
+ cptr = sf_get_string (file, SF_STR_TRACKNUMBER) ;
+ if (cptr == NULL || strcmp (genre, cptr) != 0)
+ { if (errors++ == 0)
+ puts ("\n") ;
+ printf (" Bad track no. : %s\n", cptr) ;
+ } ;
break ;
} ;
{ const char *cptr ;
SNDFILE *file ;
SF_INFO sfinfo ;
- int frames, errors = 0 ;
+ int errors = 0 ;
print_test_name ("string_start_test", filename) ;
break ;
} ;
- frames = BUFFER_LEN / sfinfo.channels ;
-
file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
/* Write stuff at start of file. */
return count ;
} /* str_count */
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+
+static void
+software_string_test (const char *filename)
+{ size_t k ;
+
+ print_test_name (__func__, filename) ;
+
+ for (k = 0 ; k < 50 ; k++)
+ { const char *result ;
+ char sfname [64] ;
+ SNDFILE *file ;
+ SF_INFO info ;
+
+ sf_info_setup (&info, SF_FORMAT_WAV | SF_FORMAT_PCM_16, 44100, 1) ;
+ file = test_open_file_or_die (filename, SFM_WRITE, &info, SF_TRUE, __LINE__) ;
+
+ snprintf (sfname, MIN (k, sizeof (sfname)), "%s", "abcdefghijklmnopqrestvwxyz0123456789abcdefghijklmnopqrestvwxyz") ;
+
+ exit_if_true (sf_set_string (file, SF_STR_SOFTWARE, sfname),
+ "\n\nLine %d : sf_set_string (f, SF_STR_SOFTWARE, '%s') failed : %s\n", __LINE__, sfname, sf_strerror (file)) ;
+
+ sf_close (file) ;
+
+ file = test_open_file_or_die (filename, SFM_READ, &info, SF_TRUE, __LINE__) ;
+ result = sf_get_string (file, SF_STR_SOFTWARE) ;
+
+ exit_if_true (result == NULL, "\n\nLine %d : sf_get_string (file, SF_STR_SOFTWARE) returned NULL.\n\n", __LINE__) ;
+
+ exit_if_true (strstr (result, sfname) != result,
+ "\n\nLine %d : String '%s''%s' -> '%s'\n\n", sfname, result) ;
+ sf_close (file) ;
+ } ;
+
+ unlink (filename) ;
+ puts ("ok") ;
+} /* new_test_test */
#!/bin/sh
-if [ -f tests/sfversion@EXEEXT@ ]; then
+# Copyright (C) 2008-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the author nor the names of any contributors may be used
+# to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+HOST_TRIPLET=@HOST_TRIPLET@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+LIB_VERSION=`echo $PACKAGE_VERSION | sed "s/[a-z].*//"`
+
+if test -f tests/sfversion@EXEEXT@ ; then
cd tests
fi
-if [ ! -f sfversion@EXEEXT@ ]; then
+if test ! -f sfversion@EXEEXT@ ; then
echo "Not able to find test executables."
exit 1
fi
-sfversion=`./sfversion@EXEEXT@`
+if test -f libsndfile.so.$LIB_VERSION ; then
+ # This will work on Linux, but not on Mac.
+ # Windows is already sorted out.
+ export LD_LIBRARY_PATH=`pwd`
+ if test ! -f libsndfile.so.1 ; then
+ ln -s libsndfile.so.$LIB_VERSION libsndfile.so.1
+ fi
+ fi
+
+sfversion=`./sfversion@EXEEXT@ | sed "s/-exp$//"`
+
+if test $sfversion != libsndfile-$PACKAGE_VERSION ; then
+ echo "Error : sfversion ($sfversion) and PACKAGE_VERSION ($PACKAGE_VERSION) don't match."
+ exit 1
+ fi
# Force exit on errors.
set -e
-# generic-tests
+# Generic-tests
uname -a
+
+# Check the header file.
+sh pedantic-header-test.sh
+
+# Need this for when we're running from files collected into the
+# libsndfile-testsuite-@PACKAGE_VERSION@ tarball.
+if test -x test_main@EXEEXT@ ; then
+ echo "Running unit tests from src/ directory of source code tree."
+ ./test_main@EXEEXT@
+ echo
+ echo "Running end-to-end tests from tests/ directory."
+ fi
+
./error_test@EXEEXT@
./pcm_test@EXEEXT@
./ulaw_test@EXEEXT@
./command_test@EXEEXT@ current_sf_info
./command_test@EXEEXT@ bext
./command_test@EXEEXT@ bextch
+./command_test@EXEEXT@ chanmap
./floating_point_test@EXEEXT@
./checksum_test@EXEEXT@
./scale_clip_test@EXEEXT@
./headerless_test@EXEEXT@
+./rdwr_test@EXEEXT@
./locale_test@EXEEXT@
./win32_ordinal_test@EXEEXT@
./external_libs_test@EXEEXT@
-./cpp_test@EXEEXT@
+./format_check_test@EXEEXT@
+
+# The w64 G++ compiler requires an extra runtime DLL which we don't have,
+# so skip this test.
+case "$HOST_TRIPLET" in
+ x86_64-w64-mingw32)
+ ;;
+ i686-w64-mingw32)
+ ;;
+ *)
+ ./cpp_test@EXEEXT@
+ ;;
+ esac
+
echo "----------------------------------------------------------------------"
echo " $sfversion passed common tests."
echo "----------------------------------------------------------------------"
./lossy_comp_test@EXEEXT@ caf_ulaw
./lossy_comp_test@EXEEXT@ caf_alaw
./header_test@EXEEXT@ caf
+./peak_chunk_test@EXEEXT@ caf
./misc_test@EXEEXT@ caf
echo "----------------------------------------------------------------------"
echo " $sfversion passed tests on CAF files."
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#if HAVE_UNISTD_H
#include <unistd.h>
const char *filename ;
int k ;
+ print_test_name ("ulaw_test", "encoder") ;
+
filename = "test.raw" ;
- sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_ULAW ;
- sfinfo.samplerate = 44100 ;
- sfinfo.frames = 123456789 ;
- sfinfo.channels = 1 ;
+ sf_info_setup (&sfinfo, SF_FORMAT_RAW | SF_FORMAT_ULAW, 44100, 1) ;
if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
{ printf ("sf_open_write failed with error : ") ;
sf_close (file) ;
- printf (" ulaw_test : encoder ... ok\n") ;
+ puts ("ok") ;
+
+ print_test_name ("ulaw_test", "decoder") ;
/* Now generate a file containing all possible 8 bit encoded
** sample values and write it to disk as ulaw encoded.frames.
sf_close (file) ;
- printf (" ulaw_test : decoder ... ok\n") ;
+ puts ("ok") ;
unlink (filename) ;
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
{ static char buffer [LOG_BUFFER_SIZE] ;
int count ;
- memset (buffer, 0, LOG_BUFFER_SIZE) ;
+ memset (buffer, 0, sizeof (buffer)) ;
/* Get the log buffer data. */
count = sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
{ static char buffer [LOG_BUFFER_SIZE] ;
int count ;
- memset (buffer, 0, LOG_BUFFER_SIZE) ;
+ memset (buffer, 0, sizeof (buffer)) ;
/* Get the log buffer data. */
count = sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
void
dump_log_buffer (SNDFILE *file)
{ static char buffer [LOG_BUFFER_SIZE] ;
- int count ;
- memset (buffer, 0, LOG_BUFFER_SIZE) ;
+ memset (buffer, 0, sizeof (buffer)) ;
/* Get the log buffer data. */
- count = sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
+ sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
if (strlen (buffer) < 1)
puts ("Log buffer empty.\n") ;
SNDFILE *file ;
const char *modestr, *func_name ;
- int oflags = 0, omode = 0 ;
+ int oflags = 0, omode = 0, err ;
/*
** Need to test both sf_open() and sf_open_fd().
} ;
if (OS_IS_WIN32)
- { /* Windows doesn't support Unix file permissions so set it to zero. */
- omode = 0 ;
+ { /* Windows does not understand and ignores the S_IRGRP flag, but Wine
+ ** gives a run time warning message, so just clear it.
+ */
+ omode &= ~S_IRGRP ;
} ;
if (allow_fd && ((++count) & 1) == 1)
{ int fd ;
- fd = open (filename, oflags, omode) ;
+ /* Only use the three argument open() function if omode != 0. */
+ fd = (omode == 0) ? open (filename, oflags) : open (filename, oflags, omode) ;
if (fd < 0)
- { perror ("open") ;
+ { printf ("\n\n%s : open failed : %s\n", __func__, strerror (errno)) ;
exit (1) ;
} ;
exit (1) ;
} ;
+ err = sf_error (file) ;
+ if (err != SF_ERR_NO_ERROR)
+ { printf ("\n\nLine %d : sf_error : %s\n\n", line_num, sf_error_number (err)) ;
+ dump_log_buffer (file) ;
+ exit (1) ;
+ } ;
+
return file ;
} /* test_open_file_or_die */
} ;
return ;
-} /* test_read_short */
+} /* test_read_short_or_die */
void
test_read_int_or_die (SNDFILE *file, int pass, int *test, sf_count_t items, int line_num)
} ;
return ;
-} /* test_read_int */
+} /* test_read_int_or_die */
void
test_read_float_or_die (SNDFILE *file, int pass, float *test, sf_count_t items, int line_num)
} ;
return ;
-} /* test_read_float */
+} /* test_read_float_or_die */
void
test_read_double_or_die (SNDFILE *file, int pass, double *test, sf_count_t items, int line_num)
} ;
return ;
-} /* test_read_double */
+} /* test_read_double_or_die */
void
} ;
return ;
-} /* test_readf_short */
+} /* test_readf_short_or_die */
void
test_readf_int_or_die (SNDFILE *file, int pass, int *test, sf_count_t frames, int line_num)
} ;
return ;
-} /* test_readf_int */
+} /* test_readf_int_or_die */
void
test_readf_float_or_die (SNDFILE *file, int pass, float *test, sf_count_t frames, int line_num)
} ;
return ;
-} /* test_readf_float */
+} /* test_readf_float_or_die */
void
test_readf_double_or_die (SNDFILE *file, int pass, double *test, sf_count_t frames, int line_num)
} ;
return ;
-} /* test_readf_double */
+} /* test_readf_double_or_die */
+
+void
+test_read_raw_or_die (SNDFILE *file, int pass, void *test, sf_count_t items, int line_num)
+{ sf_count_t count ;
+
+ if ((count = sf_read_raw (file, test, items)) != items)
+ { printf ("\n\nLine %d", line_num) ;
+ if (pass > 0)
+ printf (" (pass %d)", pass) ;
+ printf (" : sf_read_raw failed with short read (%ld => %ld).\n",
+ SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
+ fflush (stdout) ;
+ puts (sf_strerror (file)) ;
+ exit (1) ;
+ } ;
+
+ return ;
+} /* test_read_raw_or_die */
} ;
return ;
-} /* test_write_short */
+} /* test_write_short_or_die */
void
test_write_int_or_die (SNDFILE *file, int pass, const int *test, sf_count_t items, int line_num)
} ;
return ;
-} /* test_write_int */
+} /* test_write_int_or_die */
void
test_write_float_or_die (SNDFILE *file, int pass, const float *test, sf_count_t items, int line_num)
} ;
return ;
-} /* test_write_float */
+} /* test_write_float_or_die */
void
test_write_double_or_die (SNDFILE *file, int pass, const double *test, sf_count_t items, int line_num)
} ;
return ;
-} /* test_write_double */
+} /* test_write_double_or_die */
void
} ;
return ;
-} /* test_writef_short */
+} /* test_writef_short_or_die */
void
test_writef_int_or_die (SNDFILE *file, int pass, const int *test, sf_count_t frames, int line_num)
} ;
return ;
-} /* test_writef_int */
+} /* test_writef_int_or_die */
void
test_writef_float_or_die (SNDFILE *file, int pass, const float *test, sf_count_t frames, int line_num)
} ;
return ;
-} /* test_writef_float */
+} /* test_writef_float_or_die */
void
test_writef_double_or_die (SNDFILE *file, int pass, const double *test, sf_count_t frames, int line_num)
} ;
return ;
-} /* test_writef_double */
+} /* test_writef_double_or_die */
+
+
+void
+test_write_raw_or_die (SNDFILE *file, int pass, const void *test, sf_count_t items, int line_num)
+{ sf_count_t count ;
+
+ if ((count = sf_write_raw (file, test, items)) != items)
+ { printf ("\n\nLine %d", line_num) ;
+ if (pass > 0)
+ printf (" (pass %d)", pass) ;
+ printf (" : sf_write_raw failed with short write (%ld => %ld).\n",
+ SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
+ fflush (stdout) ;
+ puts (sf_strerror (file)) ;
+ exit (1) ;
+ } ;
+
+ return ;
+} /* test_write_raw_or_die */
void
void
count_open_files (void)
{
-#if (defined (WIN32) || defined (_WIN32))
+#if OS_IS_WIN32
return ;
#else
int k, count = 0 ;
void
check_open_file_count_or_die (int lineno)
{
-#if (defined (WIN32) || defined (_WIN32))
+#if OS_IS_WIN32
lineno = 0 ;
return ;
#else
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
#include <stdint.h>
#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
#define SF_COUNT_TO_LONG(x) ((long) (x))
#define ARRAY_LEN(x) ((int) (sizeof (x)) / (sizeof ((x) [0])))
#define SIGNED_SIZEOF(x) ((int64_t) (sizeof (x)))
+#define NOT(x) (! (x))
#define PIPE_INDEX(x) ((x) + 500)
#define PIPE_TEST_LEN 12345
-#if (defined (WIN32) || defined (_WIN32) || defined (__OS2__))
-#define snprintf _snprintf
-#endif
void gen_windowed_sine_float (float *data, int len, double maximum) ;
void gen_windowed_sine_double (double *data, int len, double maximum) ;
#ifdef SNDFILE_H
+static inline void
+sf_info_clear (SF_INFO * info)
+{ memset (info, 0, sizeof (SF_INFO)) ;
+} /* sf_info_clear */
+
+static inline void
+sf_info_setup (SF_INFO * info, int format, int samplerate, int channels)
+{ sf_info_clear (info) ;
+
+ info->format = format ;
+ info->samplerate = samplerate ;
+ info->channels = channels ;
+} /* sf_info_setup */
+
+
void dump_log_buffer (SNDFILE *file) ;
void check_log_buffer_or_die (SNDFILE *file, int line_num) ;
int string_in_log_buffer (SNDFILE *file, const char *s) ;
(SNDFILE *file, int pass, double *test, sf_count_t frames, int line_num) ;
+void
+test_read_raw_or_die (SNDFILE *file, int pass, void *test, sf_count_t items, int line_num) ;
+
void test_write_short_or_die
(SNDFILE *file, int pass, const short *test, sf_count_t items, int line_num) ;
(SNDFILE *file, int pass, const double *test, sf_count_t frames, int line_num) ;
+void
+test_write_raw_or_die (SNDFILE *file, int pass, const void *test, sf_count_t items, int line_num) ;
+
void compare_short_or_die (const short *left, const short *right, unsigned count, int line_num) ;
void compare_int_or_die (const int *left, const int *right, unsigned count, int line_num) ;
void compare_float_or_die (const float *left, const float *right, unsigned count, int line_num) ;
[+ AutoGen5 template h c +]
/*
-** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2002-2011 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
#define SF_COUNT_TO_LONG(x) ((long) (x))
#define ARRAY_LEN(x) ((int) (sizeof (x)) / (sizeof ((x) [0])))
#define SIGNED_SIZEOF(x) ((int64_t) (sizeof (x)))
+#define NOT(x) (! (x))
#define PIPE_INDEX(x) ((x) + 500)
#define PIPE_TEST_LEN 12345
-#if (defined (WIN32) || defined (_WIN32) || defined (__OS2__))
-#define snprintf _snprintf
-#endif
[+ FOR float_type
+]void gen_windowed_sine_[+ (get "name") +] ([+ (get "name") +] *data, int len, double maximum) ;
#ifdef SNDFILE_H
+static inline void
+sf_info_clear (SF_INFO * info)
+{ memset (info, 0, sizeof (SF_INFO)) ;
+} /* sf_info_clear */
+
+static inline void
+sf_info_setup (SF_INFO * info, int format, int samplerate, int channels)
+{ sf_info_clear (info) ;
+
+ info->format = format ;
+ info->samplerate = samplerate ;
+ info->channels = channels ;
+} /* sf_info_setup */
+
+
void dump_log_buffer (SNDFILE *file) ;
void check_log_buffer_or_die (SNDFILE *file, int line_num) ;
int string_in_log_buffer (SNDFILE *file, const char *s) ;
(SNDFILE *file, int pass, [+ (get "io_element") +] *test, sf_count_t [+ (get "count_name") +], int line_num) ;
[+ ENDFOR io_type +][+ ENDFOR read_op +]
+void
+test_read_raw_or_die (SNDFILE *file, int pass, void *test, sf_count_t items, int line_num) ;
+
[+ FOR write_op +]
[+ FOR io_type
+]void test_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die
(SNDFILE *file, int pass, const [+ (get "io_element") +] *test, sf_count_t [+ (get "count_name") +], int line_num) ;
[+ ENDFOR io_type +][+ ENDFOR write_op +]
+void
+test_write_raw_or_die (SNDFILE *file, int pass, const void *test, sf_count_t items, int line_num) ;
+
[+ FOR io_type
+]void compare_[+ (get "io_element") +]_or_die (const [+ (get "io_element") +] *left, const [+ (get "io_element") +] *right, unsigned count, int line_num) ;
[+ ENDFOR io_type +]
{ static char buffer [LOG_BUFFER_SIZE] ;
int count ;
- memset (buffer, 0, LOG_BUFFER_SIZE) ;
+ memset (buffer, 0, sizeof (buffer)) ;
/* Get the log buffer data. */
count = sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
{ static char buffer [LOG_BUFFER_SIZE] ;
int count ;
- memset (buffer, 0, LOG_BUFFER_SIZE) ;
+ memset (buffer, 0, sizeof (buffer)) ;
/* Get the log buffer data. */
count = sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
void
dump_log_buffer (SNDFILE *file)
{ static char buffer [LOG_BUFFER_SIZE] ;
- int count ;
- memset (buffer, 0, LOG_BUFFER_SIZE) ;
+ memset (buffer, 0, sizeof (buffer)) ;
/* Get the log buffer data. */
- count = sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
+ sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
if (strlen (buffer) < 1)
puts ("Log buffer empty.\n") ;
SNDFILE *file ;
const char *modestr, *func_name ;
- int oflags = 0, omode = 0 ;
+ int oflags = 0, omode = 0, err ;
/*
** Need to test both sf_open() and sf_open_fd().
} ;
if (OS_IS_WIN32)
- { /* Windows doesn't support Unix file permissions so set it to zero. */
- omode = 0 ;
+ { /* Windows does not understand and ignores the S_IRGRP flag, but Wine
+ ** gives a run time warning message, so just clear it.
+ */
+ omode &= ~S_IRGRP ;
} ;
if (allow_fd && ((++count) & 1) == 1)
{ int fd ;
- fd = open (filename, oflags, omode) ;
+ /* Only use the three argument open() function if omode != 0. */
+ fd = (omode == 0) ? open (filename, oflags) : open (filename, oflags, omode) ;
if (fd < 0)
- { perror ("open") ;
+ { printf ("\n\n%s : open failed : %s\n", __func__, strerror (errno)) ;
exit (1) ;
} ;
exit (1) ;
} ;
+ err = sf_error (file) ;
+ if (err != SF_ERR_NO_ERROR)
+ { printf ("\n\nLine %d : sf_error : %s\n\n", line_num, sf_error_number (err)) ;
+ dump_log_buffer (file) ;
+ exit (1) ;
+ } ;
+
return file ;
} /* test_open_file_or_die */
} ;
return ;
-} /* test_[+ (get "op_element") +]_[+ (get "io_element") +] */
+} /* test_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die */
[+ ENDFOR io_type +][+ ENDFOR read_op +]
+void
+test_read_raw_or_die (SNDFILE *file, int pass, void *test, sf_count_t items, int line_num)
+{ sf_count_t count ;
+
+ if ((count = sf_read_raw (file, test, items)) != items)
+ { printf ("\n\nLine %d", line_num) ;
+ if (pass > 0)
+ printf (" (pass %d)", pass) ;
+ printf (" : sf_read_raw failed with short read (%ld => %ld).\n",
+ SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
+ fflush (stdout) ;
+ puts (sf_strerror (file)) ;
+ exit (1) ;
+ } ;
+
+ return ;
+} /* test_read_raw_or_die */
+
[+ FOR write_op +]
[+ FOR io_type +]
void
} ;
return ;
-} /* test_[+ (get "op_element") +]_[+ (get "io_element") +] */
+} /* test_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die */
[+ ENDFOR io_type +][+ ENDFOR write_op +]
+void
+test_write_raw_or_die (SNDFILE *file, int pass, const void *test, sf_count_t items, int line_num)
+{ sf_count_t count ;
+
+ if ((count = sf_write_raw (file, test, items)) != items)
+ { printf ("\n\nLine %d", line_num) ;
+ if (pass > 0)
+ printf (" (pass %d)", pass) ;
+ printf (" : sf_write_raw failed with short write (%ld => %ld).\n",
+ SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
+ fflush (stdout) ;
+ puts (sf_strerror (file)) ;
+ exit (1) ;
+ } ;
+
+ return ;
+} /* test_write_raw_or_die */
+
+
[+ FOR io_type
+]void
compare_[+ (get "io_element") +]_or_die (const [+ (get "io_element") +] *left, const [+ (get "io_element") +] *right, unsigned count, int line_num)
void
count_open_files (void)
{
-#if (defined (WIN32) || defined (_WIN32))
+#if OS_IS_WIN32
return ;
#else
int k, count = 0 ;
void
check_open_file_count_or_die (int lineno)
{
-#if (defined (WIN32) || defined (_WIN32))
+#if OS_IS_WIN32
lineno = 0 ;
return ;
#else
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
vio_test ("vio_pcm16.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
vio_test ("vio_pcm24.aiff", SF_FORMAT_AIFF | SF_FORMAT_PCM_24) ;
vio_test ("vio_float.au", SF_FORMAT_AU | SF_FORMAT_FLOAT) ;
+ vio_test ("vio_pcm24.paf", SF_FORMAT_PAF | SF_FORMAT_PCM_24) ;
return 0 ;
} /* main */
exit (1) ;
} ;
+ if (vfget_filelen (&vio_data) < 0)
+ { printf ("\n\nLine %d : vfget_filelen returned negative length.\n\n", __LINE__) ;
+ exit (1) ;
+ } ;
+
gen_short_data (data, ARRAY_LEN (data), 0) ;
sf_write_short (file, data, ARRAY_LEN (data)) ;
/*
-** Copyright (C) 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2007-2011 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
for (k = 0 ; k < ARRAY_LEN (float_data) ; k ++)
max_abs = max_float (max_abs, fabs (float_data [k])) ;
- if (max_abs > 1.02)
- { printf ("\n\n Error : max_abs %f should be < 1.02.\n\n", max_abs) ;
+ if (max_abs > 1.021)
+ { printf ("\n\n Error : max_abs %f should be < 1.021.\n\n", max_abs) ;
exit (1) ;
} ;
/*
-** Copyright (C) 2006-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2006-2011 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
static const char * locations [] =
-{ "../src/", "src/", "../src/.libs/", "src/.libs/",
+{ ".", "../src/", "src/", "../src/.libs/", "src/.libs/",
NULL
} ; /* locations. */
/*
-** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2001-2011 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
#include <stdio.h>
#include <stdlib.h>
+#include <assert.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#define SIGNED_SIZEOF(x) ((int) sizeof (x))
-#if defined (__CYGWIN__)
+/* EMX is OS/2. */
+#if defined (__CYGWIN__) || defined (__EMX__)
#define LSEEK lseek
#define FSTAT fstat
static void show_fstat_error (void) ;
static void show_lseek_error (void) ;
static void show_stat_fstat_error (void) ;
+static void write_to_closed_file (void) ;
int
main (void)
show_fstat_error () ;
show_lseek_error () ;
show_stat_fstat_error () ;
+ write_to_closed_file () ;
puts ("\n\n") ;
static char data [256] ;
STATBUF statbuf ;
- int fd, mode, flags, ignored ;
+ int fd, mode, flags ;
if (sizeof (statbuf.st_size) != sizeof (INT64))
{ printf ("\n\nLine %d: Error, sizeof (statbuf.st_size) != 8.\n\n", __LINE__) ;
{ printf ("\n\nLine %d: open() failed : %s\n\n", __LINE__, strerror (errno)) ;
return ;
} ;
- ignored = write (fd, data, sizeof (data)) ;
+ assert (write (fd, data, sizeof (data)) > 0) ;
close (fd) ;
printf ("1) Re-open file in read/write mode and write another %d bytes at the end.\n", SIGNED_SIZEOF (data)) ;
return ;
} ;
LSEEK (fd, 0, SEEK_END) ;
- ignored = write (fd, data, sizeof (data)) ;
+ assert (write (fd, data, sizeof (data)) > 0) ;
printf ("2) Now use system (\"%s %s\") to show the file length.\n\n", dir_cmd, filename) ;
strncat (data, " ", sizeof (data) - 1 - strlen (data)) ;
strncat (data, filename, sizeof (data) - 1 - strlen (data)) ;
- ignored = system (data) ;
+ assert (system (data) >= 0) ;
puts ("") ;
printf ("3) Now use fstat() to get the file length.\n") ;
static char data [256] ;
INT64 retval ;
- int fd, mode, flags, ignored ;
+ int fd, mode, flags ;
puts ("\n64 bit lseek() test.\n--------------------") ;
{ printf ("\n\nLine %d: open() failed : %s\n\n", __LINE__, strerror (errno)) ;
return ;
} ;
- ignored = write (fd, data, sizeof (data)) ;
+ assert (write (fd, data, sizeof (data)) > 0) ;
close (fd) ;
printf ("1) Re-open file in read/write mode and write another %d bytes at the end.\n", SIGNED_SIZEOF (data)) ;
} ;
LSEEK (fd, 0, SEEK_END) ;
- ignored = write (fd, data, sizeof (data)) ;
+ assert (write (fd, data, sizeof (data)) > 0) ;
printf ("2) Now use system (\"%s %s\") to show the file length.\n\n", dir_cmd, filename) ;
strncat (data, " ", sizeof (data) - 1 - strlen (data)) ;
strncat (data, filename, sizeof (data) - 1 - strlen (data)) ;
- ignored = system (data) ;
+ assert (system (data) >= 0) ;
puts ("") ;
printf ("3) Now use lseek() to go to the end of the file.\n") ;
static char data [256] ;
int fd, mode, flags ;
- int stat_size, fstat_size, ignored ;
+ int stat_size, fstat_size ;
struct stat buf ;
/* Known to fail on WinXP. */
return ;
} ;
- ignored = write (fd, data, sizeof (data)) ;
+ assert (write (fd, data, sizeof (data)) > 0) ;
printf ("1) Now call stat and fstat on the file and retreive the file lengths.\n") ;
} ;
fstat_size = buf.st_size ;
- printf ("3) Size returned by stat and fstat is %d and %d, ", stat_size, fstat_size) ;
+ printf ("2) Size returned by stat and fstat is %d and %d, ", stat_size, fstat_size) ;
if (stat_size == 0 || stat_size != fstat_size)
} /* show_stat_fstat_error */
+static void
+write_to_closed_file (void)
+{ const char * filename = "closed_write_test.txt" ;
+ struct stat buf ;
+ FILE * file ;
+ int fd ;
+
+ puts ("\nWrite to closed file test.\n--------------------------") ;
+
+ printf ("0) First we open file for write using fopen().\n") ;
+ if ((file = fopen (filename, "w")) == NULL)
+ { printf ("\n\nLine %d: fopen() failed : %s\n\n", __LINE__, strerror (errno)) ;
+ return ;
+ } ;
+
+ printf ("1) Now we grab the file descriptor fileno().\n") ;
+ fd = fileno (file) ;
+
+ printf ("2) Write some text via the file descriptor.\n") ;
+ assert (write (fd, "a\n", 2) > 0) ;
+
+ printf ("3) Now we close the file using fclose().\n") ;
+ fclose (file) ;
+
+ stat (filename, &buf) ;
+ printf (" File size is %d bytes.\n", (int) buf.st_size) ;
+
+ printf ("4) Now write more data to the file descriptor which should fail.\n") ;
+ if (write (fd, "b\n", 2) < 0)
+ printf ("5) Good, write returned an error code as it should have.\n") ;
+ else
+ { printf ("5) Attempting to write to a closed file should have failed but didn't! *** WRONG ***\n") ;
+
+ stat (filename, &buf) ;
+ printf (" File size is %d bytes.\n", (int) buf.st_size) ;
+ } ;
+
+ unlink (filename) ;
+
+ return ;
+} /* write_to_closed_file */
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
} ;
if (do_all || ! strcmp (argv [1], "sds"))
- { pcm_test_char ("char.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_S8, SF_TRUE) ;
- pcm_test_short ("short.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_16, SF_TRUE) ;
- pcm_test_24bit ("24bit.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_24, SF_TRUE) ;
+ { pcm_test_char ("char.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_S8, SF_FALSE) ;
+ pcm_test_short ("short.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_16, SF_FALSE) ;
+ pcm_test_24bit ("24bit.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_24, SF_FALSE) ;
empty_file_test ("empty_char.sds", SF_FORMAT_SDS | SF_FORMAT_PCM_S8) ;
empty_file_test ("empty_short.sds", SF_FORMAT_SDS | SF_FORMAT_PCM_16) ;
static void
pcm_test_char (const char *filename, int format, int long_file_ok)
{ SF_INFO sfinfo ;
- short *orig, *test ;
- int k, items, allow_fd ;
+ short *orig ;
+ int k, allow_fd ;
/* Sd2 files cannot be opened from an existing file descriptor. */
allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 32000.0) ;
orig = orig_data.s ;
- test = test_data.s ;
/* Make this a macro so gdb steps over it in one go. */
CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
- items = DATA_LENGTH ;
-
/* Some test broken out here. */
mono_char_test (filename, format, long_file_ok, allow_fd) ;
static void
pcm_test_short (const char *filename, int format, int long_file_ok)
{ SF_INFO sfinfo ;
- short *orig, *test ;
- int k, items, allow_fd ;
+ short *orig ;
+ int k, allow_fd ;
/* Sd2 files cannot be opened from an existing file descriptor. */
allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 32000.0) ;
orig = orig_data.s ;
- test = test_data.s ;
/* Make this a macro so gdb steps over it in one go. */
CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
- items = DATA_LENGTH ;
-
/* Some test broken out here. */
mono_short_test (filename, format, long_file_ok, allow_fd) ;
static void
pcm_test_24bit (const char *filename, int format, int long_file_ok)
{ SF_INFO sfinfo ;
- int *orig, *test ;
- int k, items, allow_fd ;
+ int *orig ;
+ int k, allow_fd ;
/* Sd2 files cannot be opened from an existing file descriptor. */
allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
gen_windowed_sine_double (orig_data.d, DATA_LENGTH, (1.0 * 0x7F000000)) ;
orig = orig_data.i ;
- test = test_data.i ;
/* Make this a macro so gdb steps over it in one go. */
CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
- items = DATA_LENGTH ;
-
/* Some test broken out here. */
mono_24bit_test (filename, format, long_file_ok, allow_fd) ;
static void
pcm_test_int (const char *filename, int format, int long_file_ok)
{ SF_INFO sfinfo ;
- int *orig, *test ;
- int k, items, allow_fd ;
+ int *orig ;
+ int k, allow_fd ;
/* Sd2 files cannot be opened from an existing file descriptor. */
allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
gen_windowed_sine_double (orig_data.d, DATA_LENGTH, (1.0 * 0x7F000000)) ;
orig = orig_data.i ;
- test = test_data.i ;
/* Make this a macro so gdb steps over it in one go. */
CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
- items = DATA_LENGTH ;
-
/* Some test broken out here. */
mono_int_test (filename, format, long_file_ok, allow_fd) ;
static void
pcm_test_float (const char *filename, int format, int long_file_ok)
{ SF_INFO sfinfo ;
- float *orig, *test ;
- int k, items, allow_fd ;
+ float *orig ;
+ int k, allow_fd ;
/* Sd2 files cannot be opened from an existing file descriptor. */
allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 1.0) ;
orig = orig_data.f ;
- test = test_data.f ;
/* Make this a macro so gdb steps over it in one go. */
CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
- items = DATA_LENGTH ;
-
/* Some test broken out here. */
mono_float_test (filename, format, long_file_ok, allow_fd) ;
static void
pcm_test_double (const char *filename, int format, int long_file_ok)
{ SF_INFO sfinfo ;
- double *orig, *test ;
- int k, items, allow_fd ;
+ double *orig ;
+ int k, allow_fd ;
/* Sd2 files cannot be opened from an existing file descriptor. */
allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
gen_windowed_sine_double (orig_data.d, DATA_LENGTH, 1.0) ;
orig = orig_data.d ;
- test = test_data.d ;
/* Make this a macro so gdb steps over it in one go. */
CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
- items = DATA_LENGTH ;
-
/* Some test broken out here. */
mono_double_test (filename, format, long_file_ok, allow_fd) ;
[+ AutoGen5 template c +]
/*
-** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 1999-2011 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
} ;
if (do_all || ! strcmp (argv [1], "sds"))
- { pcm_test_char ("char.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_S8, SF_TRUE) ;
- pcm_test_short ("short.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_16, SF_TRUE) ;
- pcm_test_24bit ("24bit.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_24, SF_TRUE) ;
+ { pcm_test_char ("char.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_S8, SF_FALSE) ;
+ pcm_test_short ("short.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_16, SF_FALSE) ;
+ pcm_test_24bit ("24bit.sds" , SF_FORMAT_SDS | SF_FORMAT_PCM_24, SF_FALSE) ;
empty_file_test ("empty_char.sds", SF_FORMAT_SDS | SF_FORMAT_PCM_S8) ;
empty_file_test ("empty_short.sds", SF_FORMAT_SDS | SF_FORMAT_PCM_16) ;
static void
pcm_test_[+ (get "type_name") +] (const char *filename, int format, int long_file_ok)
{ SF_INFO sfinfo ;
- [+ (get "data_type") +] *orig, *test ;
- int k, items, allow_fd ;
+ [+ (get "data_type") +] *orig ;
+ int k, allow_fd ;
/* Sd2 files cannot be opened from an existing file descriptor. */
allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
gen_windowed_sine_double (orig_data.d, DATA_LENGTH, [+ (get "max_val") +]) ;
orig = orig_data.[+ (get "data_field") +] ;
- test = test_data.[+ (get "data_field") +] ;
/* Make this a macro so gdb steps over it in one go. */
CONVERT_DATA (k, DATA_LENGTH, orig, orig_data.d) ;
- items = DATA_LENGTH ;
-
/* Some test broken out here. */
mono_[+ (get "type_name") +]_test (filename, format, long_file_ok, allow_fd) ;
context->sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM;
context->sfinfo.channels = 1;
context->sfinfo.samplerate = 8000;
+ } else if (!strcmp(ext, "oga")) {
+ context->sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS;
+ context->sfinfo.samplerate = handle->samplerate;
}
if ((mode & SFM_WRITE) && sf_format_check(&context->sfinfo) == 0) {