Imported Upstream version 1.1.0 20/285120/1 upstream/1.1.0
authorSeungbae Shin <seungbae.shin@samsung.com>
Tue, 6 Dec 2022 10:21:45 +0000 (19:21 +0900)
committerSeungbae Shin <seungbae.shin@samsung.com>
Tue, 6 Dec 2022 10:44:54 +0000 (19:44 +0900)
Change-Id: I7f253c192c45ded9144add418210ac5e3a29e0a9

139 files changed:
Building-for-Android.md
CHANGELOG.md [new file with mode: 0644]
CMakeLists.txt
CONTRIBUTING.md
Makefile.am
NEWS.OLD [moved from NEWS with 100% similarity]
README
README.md
SECURITY.md [new file with mode: 0644]
cmake/FindLame.cmake [new file with mode: 0644]
cmake/FindMpg123.cmake [new file with mode: 0644]
cmake/SetupABIVersions.cmake [new file with mode: 0644]
cmake/SndFileChecks.cmake
cmake/SndFileConfig.cmake.in
configure.ac
docs/FAQ.md
docs/_config.yml
docs/_layouts/home.html
docs/api.md
docs/command.md
docs/development.md
docs/formats.md
docs/index.md
examples/generate.c
examples/make_sine.c
examples/sfprocess.c
examples/sndfile-loopify.c
examples/sndfile-to-text.c
include/sndfile.h.in
include/sndfile.hh
m4/ax_add_fortify_source.m4
m4/extra_pkg.m4
m4/mkoctfile_version.m4
m4/octave.m4
m4/stack_protect.m4 [deleted file]
man/sndfile-play.1
ossfuzz/ossfuzz.sh
ossfuzz/sndfile_alt_fuzzer.cc [new file with mode: 0644]
ossfuzz/sndfile_fuzz_header.h [new file with mode: 0644]
ossfuzz/sndfile_fuzzer.cc
programs/common.c
programs/sndfile-concat.c
programs/sndfile-convert.c
programs/sndfile-deinterleave.c
programs/sndfile-info.c
programs/sndfile-interleave.c
programs/sndfile-play.c
programs/sndfile-salvage.c
regtest/database.c
sndfile.pc.in
src/ALAC/ag_dec.c
src/ALAC/ag_enc.c
src/ALAC/alac_codec.h
src/ALAC/alac_decoder.c
src/ALAC/dp_dec.c
src/ALAC/dp_enc.c
src/ALAC/shift.h
src/G72x/g72x_priv.h
src/GSM610/gsm610_priv.h
src/aiff.c
src/alac.c
src/alaw.c
src/avr.c
src/broadcast.c
src/caf.c
src/cart.c
src/chunk.c
src/command.c
src/common.c
src/common.h
src/config.h.cmake
src/dither.c
src/double64.c
src/dwd.c
src/dwvw.c
src/file_io.c
src/flac.c
src/float32.c
src/g72x.c
src/gsm610.c
src/id3.c
src/id3.h [new file with mode: 0644]
src/ima_adpcm.c
src/mpc2k.c
src/mpeg.c [new file with mode: 0644]
src/mpeg.h [new file with mode: 0644]
src/mpeg_decode.c [new file with mode: 0644]
src/mpeg_l3_encode.c [new file with mode: 0644]
src/ms_adpcm.c
src/nms_adpcm.c
src/ogg_opus.c
src/ogg_vorbis.c
src/paf.c
src/pcm.c
src/rf64.c
src/sd2.c
src/sds.c
src/sfendian.h
src/sndfile.c
src/svx.c
src/test_broadcast_var.c
src/test_conversions.c
src/test_file_io.c
src/test_log_printf.c
src/ulaw.c
src/vox_adpcm.c
src/w64.c
src/wav.c
src/wavlike.c
src/wavlike.h
src/windows.c
src/xi.c
tests/alaw_test.c
tests/chunk_test.c
tests/command_test.c
tests/compression_size_test.c
tests/dwvw_test.c
tests/error_test.c
tests/floating_point_test.tpl
tests/format_check_test.c
tests/generate.c
tests/header_test.tpl
tests/headerless_test.c
tests/locale_test.c
tests/long_read_write_test.c
tests/lossy_comp_test.c
tests/mpeg_test.c [new file with mode: 0644]
tests/multi_file_test.c
tests/ogg_opus_test.c
tests/ogg_test.c
tests/stdin_test.c
tests/stdout_test.c
tests/string_test.c
tests/test_wrapper.sh.in
tests/ulaw_test.c
tests/utils.tpl
tests/virtual_io_test.c
tests/write_read_test.tpl
vcpkg.json [new file with mode: 0644]

index 72b302d..c664281 100644 (file)
@@ -15,3 +15,32 @@ by setting them before the script is run.
 Since I (erikd), do almost zero Android development, I am happy accept patches
 for this documentation and script to improve its utility for real Android
 developers.
+
+---
+
+## Using CMake
+
+(Tested on Linux)
+
+For convenience, export the following variables:
+
+```
+export ANDROID_ABI=arm64-v8a
+export ANDROID_PLATFORM_API_LEVEL=29
+export NDK_ROOT=/path/to/android/ndk
+```
+
+Set `ANDROID_ABI`,  `ANDROID_PLATFORM_API_LEVEL`  according to your target system. Now cd into the libsndfile root directory, and run
+
+```
+cmake -S . -B build  -DCMAKE_TOOLCHAIN_FILE=$NDK_ROOT/build/cmake/android.toolchain.cmake -DANDROID_ABI=$ANDROID_ABI -DANDROID_PLATFORM=$ANDROID_PLATFORM_API_LEVEL
+```
+
+cd into `build` and run make
+
+```
+cd build
+make [-j <number of parallel jobs>]
+```
+
+This will build libsndfile for android.
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644 (file)
index 0000000..3719e0f
--- /dev/null
@@ -0,0 +1,132 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+## [1.1.0] - 2022-03-27
+
+### Added
+
+* MPEG Encode/Decode Support.
+
+  Uses libmpg123 for decode, liblame for encode. Encoding and decoding support
+  is independent of each other and is split into separate files. MPEG support
+  is generalized as subformats, `SF_FORMAT_MPEG_LAYER`(I,II,III) so that it
+  might be used by other containers (`MPEG1WAVEFORMAT` for example), but also
+  contains a major format `SF_FORMAT_MPEG` for 'mp3 files.'
+
+  Encoding Status:
+  * Layer III encoding
+  * ID3v1 writing
+  * ID3v2 writing
+  * Lame/Xing Tag writing
+  * Bitrate selection command
+  * VBR or CBR
+  
+  Decoding Status:
+  * Layers I/II/III decoding
+  * ID3v1 reading
+  * ID3v2 reading
+  * Seeking
+* New fuzzer for OSS-Fuzz, thanks @DavidKorczynski.
+* This `CHANGELOG.md`. All notable changes to this project will be documented in
+  this file. The old `NEWS` file has been renamed to `NEWS.OLD` and is no longer
+  updated.
+* Add support for decoding MPEG III Audio in WAV files.
+* `SECURITY.md` file to give people instructions for reporting security
+  vulnerabilities, thanks @zidingz.
+* Support for [Vcpkg manifest mode](https://vcpkg.readthedocs.io/en/latest/users/manifests/).
+
+  If you have problems with manifest mode, disable it with `VCPKG_MANIFEST_MODE`
+  switch.
+* [Export CMake targets from the build tree (PR #802)](https://cmake.org/cmake/help/latest/guide/importing-exporting/index.html#exporting-targets-from-the-build-tree)
+* CIFuzz fuzzer, thanks to @AdamKorcz (PR #796)
+
+### Changed
+
+* `SFC_SET_DITHER_ON_READ` and `SFC_SET_DITHER_ON_WRITE` enums comments in
+  public header, thanks @SmiVan (issue #677).
+* `ENABLE_SNDFILE_WINDOWS_PROTOTYPES` define is deprecated and not needed
+  anymore.
+
+  Previously, in order for the [`sf_wchar_open`()](http://libsndfile.github.io/libsndfile/api.html#open)
+  function to become available on   the Windows platform, it was required to
+  perform certain actions:
+
+  ```c
+  #include <windows.h>
+  #define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
+  #including <sndfile.h>
+  ```
+
+  These steps are no longer required and the `sf_wchar_open`() function is
+  always available on the Windows platform.
+* Use UTF-8 as internal path encoding on Windows platform.
+
+  This is an internal change to unify and simplify the handling of file paths.
+
+  On the Windows platform, the file path is always converted to UTF-8 and
+  converted to UTF-16 only for calls to WinAPI functions.
+
+  The behavior of the functions for opening files on other platforms does not
+  change.
+* Switch to .xz over .bz2 for release tarballs.
+* Disable static builds using Autotools by default. If you want static
+  libraries, pass --enable-static to ./configure
+
+### Fixed
+
+* Typo in `docs/index.md`.
+* Typo in `programs/sndfile-convert.c`, thanks @fjl.
+* Memory leak in `caf_read_header`(), credit to OSS-Fuzz ([issue 30375](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=30375)).
+* Stack overflow in `guess_file_type`(), thanks @bobsayshilol, credit to
+  OSS-Fuzz ([issue 29339](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29339)).
+* Abort in fuzzer, thanks @bobsayshilol, credit to OSS-Fuzz
+  ([issue 26257](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=26257)).
+* Infinite loop in `svx_read_header`(), thanks @bobsayshilol, credit to OSS-Fuzz
+  ([issue 25442](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25442)).
+* GCC and Clang pedantic warnings, thanks @bobsayshilol.
+* Normalisation issue when scaling floating point data to `int` in
+  `replace_read_f2i`(), thanks @bobsayshilol, (issue #702).
+* Missing samples when doing a partial read of Ogg file from index till the end
+  of file, thanks @arthurt (issue #643).
+* sndfile-salvage: Handle files > 4 GB on Windows OS
+* Undefined shift in `dyn_get_32bit`(), credit to OSS-Fuzz
+  ([issue 27366](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=27366)).
+* Integer overflow in `nms_adpcm_update`(), credit to OSS-Fuzz
+  ([issue 25522](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25522)).
+* Integer overflow in `psf_log_printf`(), credit to OSS-Fuzz
+  ([issue 28441](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28441)),
+  ([issue 25624](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25624)).
+* ABI version incompatibility between Autotools and CMake build on Apple
+  platforms.
+
+  Now ABI must be compatible with Autotools builds. Note that this change
+  requires CMake >= 3.17 for building dylib on Apple platforms.
+
+* Fix build with Autotools + MinGW toolchain on Windows platform.
+
+  See https://github.com/msys2/MINGW-packages/issues/5803 for details.
+
+### Security
+
+* Heap buffer overflow in `wavlike_ima_decode_block`(), thanks @bobsayshilol,
+  credit to OSS-Fuzz ([issue 25530](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25530)).
+* Heap buffer overflow in `msadpcm_decode_block`(), thanks @bobsayshilol,
+  credit to OSS-Fuzz ([issue 26803](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=26803)).
+* Heap buffer overflow in `psf_binheader_readf`(), thanks @bobsayshilol,
+  credit to OSS-Fuzz ([issue 26026](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=26026)).
+* Index out of bounds in `psf_nms_adpcm_decode_block`(), credit to OSS-Fuzz
+  ([issue 25561](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25561)).
+* Heap buffer overflow in `flac_buffer_copy`(), thanks @yuawn,  @bobsayshilol.
+* Heap buffer overflow in `copyPredictorTo24`(), thanks @bobsayshilol,
+  credit to OSS-Fuzz ([issue 27503](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=27503)).
+* Uninitialized variable in `psf_binheader_readf`(), thanks @shao-hua-li,
+  credit to OSS-Fuzz ([issue 25364](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25364)).
+
+[Unreleased]: https://github.com/libsndfile/libsndfile/compare/1.1.0...HEAD
+[1.1.0]: https://github.com/libsndfile/libsndfile/compare/1.0.31...1.1.0
index de98145..b1b49e9 100644 (file)
@@ -15,7 +15,27 @@ if (POLICY CMP0091)
        endif ()
 endif ()
 
-project(libsndfile VERSION 1.0.31)
+option (ENABLE_EXTERNAL_LIBS "Enable FLAC, Vorbis, and Opus codecs" ON)
+if (ENABLE_EXTERNAL_LIBS)
+       list (APPEND VCPKG_MANIFEST_FEATURES "external-libs")
+endif ()
+
+option (ENABLE_MPEG "Enable MPEG codecs" ON)
+if (ENABLE_MPEG)
+       list (APPEND VCPKG_MANIFEST_FEATURES "mpeg")
+endif ()
+
+option (ENABLE_EXPERIMENTAL "Enable experimental code" OFF)
+if (ENABLE_EXPERIMENTAL)
+       list (APPEND VCPKG_MANIFEST_FEATURES "speex")
+endif ()
+
+option (BUILD_REGTEST "Build regtest" OFF)
+if (BUILD_REGTEST)
+       list (APPEND VCPKG_MANIFEST_FEATURES "regtest")
+endif ()
+
+project(libsndfile VERSION 1.1.0)
 
 #
 # Variables
@@ -54,7 +74,6 @@ endif ()
 option (BUILD_PROGRAMS "Build programs" ON)
 option (BUILD_EXAMPLES "Build examples" ON)
 option (ENABLE_CPACK "Enable CPack support" ON)
-option (ENABLE_EXPERIMENTAL "Enable experimental code" OFF)
 option (ENABLE_BOW_DOCS "Enable black-on-white html docs" OFF)
 if (MSVC AND (DEFINED ENABLE_STATIC_RUNTIME))
        option (ENABLE_STATIC_RUNTIME "Enable static runtime" ${ENABLE_STATIC_RUNTIME})
@@ -75,9 +94,16 @@ endif ()
 
 include(SndFileChecks)
 
+if (ENABLE_EXTERNAL_LIBS AND NOT (Vorbis_FOUND OR FLAC_FOUND OR OPUS_FOUND))
+       set (ENABLE_EXTERNAL_LIBS OFF)
+endif()
+if(ENABLE_MPEG AND (NOT HAVE_MPEG_LIBS))
+       set (ENABLE_MPEG OFF)
+endif()
+if (BUILD_REGTEST AND (NOT SQLITE3_FOUND))
+       set (BUILD_REGTEST OFF)
+endif()
 
-cmake_dependent_option (BUILD_REGTEST "Build regtest" ON "SQLITE3_FOUND" OFF)
-cmake_dependent_option (ENABLE_EXTERNAL_LIBS "Enable FLAC, Vorbis, and Opus codecs" ON "Vorbis_FOUND;FLAC_FOUND;OPUS_FOUND" OFF)
 cmake_dependent_option (ENABLE_CPU_CLIP "Enable tricky cpu specific clipper" ON "CPU_CLIPS_POSITIVE;CPU_CLIPS_NEGATIVE" OFF)
 if (NOT ENABLE_CPU_CLIP)
        set (CPU_CLIPS_POSITIVE FALSE)
@@ -104,11 +130,12 @@ set (HAVE_ALSA_ASOUNDLIB_H ${ALSA_FOUND})
 set (HAVE_SNDIO_H ${SNDIO_FOUND})
 
 set (ENABLE_EXPERIMENTAL_CODE ${ENABLE_EXPERIMENTAL})
+set (HAVE_MPEG ${ENABLE_MPEG})
 set (HAVE_SPEEX ${ENABLE_EXPERIMENTAL})
-set (HAVE_OPUS ${ENABLE_EXPERIMENTAL})
 
 add_feature_info (BUILD_SHARED_LIBS BUILD_SHARED_LIBS "build shared libraries")
 add_feature_info (ENABLE_EXTERNAL_LIBS ENABLE_EXTERNAL_LIBS "enable FLAC, Vorbis, and Opus codecs")
+add_feature_info (ENABLE_MPEG ENABLE_MPEG "enable MPEG audio (including mp3) codecs")
 add_feature_info (ENABLE_EXPERIMENTAL ENABLE_EXPERIMENTAL "enable experimental code")
 add_feature_info (BUILD_TESTING BUILD_TESTING "build tests")
 add_feature_info (BUILD_REGTEST BUILD_REGTEST "build regtest")
@@ -147,6 +174,18 @@ set_package_properties (FLAC PROPERTIES
        DESCRIPTION "Free Lossless Audio Codec Library"
        PURPOSE "Enables FLAC support"
        )
+set_package_properties (Lame PROPERTIES
+       TYPE RECOMMENDED
+       URL "https://lame.sourceforge.io/"
+       DESCRIPTION "High quality MPEG Audio Layer III (MP3) encoder"
+       PURPOSE "Enables MPEG layer III (MP3) writing support"
+       )
+set_package_properties (MPG123 PROPERTIES
+       TYPE RECOMMENDED
+       URL "https://www.mpg123.de/"
+       DESCRIPTION "MPEG Audio Layer I/II/III decoder"
+       PURPOSE "Enables MPEG Audio reading support"
+       )
 set_package_properties(Opus PROPERTIES
        TYPE RECOMMENDED
        URL     "www.opus-codec.org/"
@@ -196,6 +235,23 @@ if (INSTALL_PKGCONFIG_MODULE)
                        set (EXTERNAL_XIPH_REQUIRE "${EXTERNAL_XIPH_REQUIRE} speex")
                endif ()
        endif ()
+       if (ENABLE_MPEG)
+               set (EXTERNAL_MPEG_REQUIRE "libmpg123")
+               get_filename_component(LAME_WE ${LAME_LIBRARY} NAME_WE)
+               if (LAME_HIP_LIBRARY)
+                       get_filename_component(LAME_HIP_WE ${LAME_HIP_LIBRARY} NAME_WE)
+               endif ()
+               if (CMAKE_IMPORT_LIBRARY_PREFIX)
+                       string (REGEX REPLACE "^${CMAKE_IMPORT_LIBRARY_PREFIX}" "" LAME_WE_NO_PREFIX ${LAME_WE})
+                       if (LAME_HIP_LIBRARY)
+                               string (REGEX REPLACE "^${CMAKE_IMPORT_LIBRARY_PREFIX}" "" LAME_HIP_WE_NO_PREFIX ${LAME_HIP_WE})
+                       endif ()
+               endif ()
+               set (EXTERNAL_MPEG_LIBS "-l${LAME_WE_NO_PREFIX}")
+               if (LAME_HIP_LIBRARY)
+                       set (EXTERNAL_MPEG_LIBS "${MPEG_LIBS} -l${LAME_HIP_WE}")
+               endif ()
+       endif ()
 
        configure_file (sndfile.pc.in sndfile.pc @ONLY)
 
@@ -247,6 +303,7 @@ add_library (sndfile
        src/ogg.c
        src/chanmap.h
        src/chanmap.c
+       src/id3.h
        src/id3.c
        $<$<BOOL:${WIN32}>:src/windows.c>
        src/sndfile.c
@@ -284,8 +341,12 @@ add_library (sndfile
        src/ogg_speex.c
        src/ogg_pcm.c
        src/ogg_opus.c
+       src/ogg_vcomment.h
        src/ogg_vcomment.c
        src/nms_adpcm.c
+       src/mpeg.c
+       src/mpeg_decode.c
+       src/mpeg_l3_encode.c
        src/GSM610/config.h
        src/GSM610/gsm.h
        src/GSM610/gsm610_priv.h
@@ -349,6 +410,8 @@ target_link_libraries (sndfile
                $<$<BOOL:${HAVE_EXTERNAL_XIPH_LIBS}>:FLAC::FLAC>
                $<$<AND:$<BOOL:${ENABLE_EXPERIMENTAL}>,$<BOOL:${HAVE_EXTERNAL_XIPH_LIBS}>,$<BOOL:${HAVE_SPEEX}>>:Speex::Speex>
                $<$<BOOL:${HAVE_EXTERNAL_XIPH_LIBS}>:Opus::opus>
+               $<$<BOOL:${HAVE_MPEG}>:MPG123::libmpg123>
+               $<$<BOOL:${HAVE_MPEG}>:Lame::Lame>
        )
 set_target_properties (sndfile PROPERTIES
        PUBLIC_HEADER "${sndfile_HDRS}"
@@ -368,6 +431,28 @@ endif ()
 
 if (BUILD_SHARED_LIBS)
 
+       #
+       # ABI version of library.
+       #
+
+       #
+       # Read libtool version from `configure.ac` and set libsndfile ABI version:
+       #
+       #   SNDFILE_ABI_VERSION_MAJOR
+       #   SNDFILE_ABI_VERSION_MINOR
+       #   SNDFILE_ABI_VERSION_PATCH
+       #   SNDFILE_ABI_VERSION
+       #
+       # and Mach-O current and compatibility versions:
+       #
+       #   SNDFILE_MACHO_CURRENT_VERSION
+       #   SNDFILE_MACHO_COMPATIBILITY_VERSION
+       #
+
+       include (SetupABIVersions)
+
+       setup_abi_versions()
+
        if (WIN32)
                set (VERSION_MAJOR ${CPACK_PACKAGE_VERSION_MAJOR})
                set (GEN_TOOL cmake)
@@ -380,11 +465,23 @@ if (BUILD_SHARED_LIBS)
                target_sources (sndfile PRIVATE ${PROJECT_BINARY_DIR}/src/version-metadata.rc)
        endif ()
 
+
        set_target_properties (sndfile PROPERTIES
-               SOVERSION ${PROJECT_VERSION_MAJOR}
-               VERSION ${PROJECT_VERSION}
+               SOVERSION ${SNDFILE_ABI_VERSION_MAJOR}
+               VERSION ${SNDFILE_ABI_VERSION}
                )
 
+       if (APPLE)
+               if (NOT (CMAKE_VERSION VERSION_LESS 3.17))
+                       set_target_properties (sndfile PROPERTIES
+                               MACHO_CURRENT_VERSION ${SNDFILE_MACHO_CURRENT_VERSION}
+                               MACHO_COMPATIBILITY_VERSION ${SNDFILE_MACHO_COMPATIBILITY_VERSION}
+                               )
+               else ()
+                       message (FATAL_ERROR "Apple platform requires cmake >= 3.17 to build dylib.")
+               endif ()
+       endif ()
+
        # Symbol files generation
 
        if (WIN32)
@@ -404,7 +501,7 @@ if (BUILD_SHARED_LIBS)
        if (DEFINED SYMBOL_OS)
                add_custom_command (
                        OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/${SYMBOL_FILENAME}
-                       COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/src/create_symbols_file.py ${SYMBOL_OS} ${PROJECT_VERSION} > ${CMAKE_CURRENT_BINARY_DIR}/src/${SYMBOL_FILENAME}
+                       COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/src/create_symbols_file.py ${SYMBOL_OS} ${SNDFILE_ABI_VERSION} > ${CMAKE_CURRENT_BINARY_DIR}/src/${SYMBOL_FILENAME}
                        COMMENT "Generating ${SYMBOL_FILENAME}..."
                        )
 
@@ -647,6 +744,11 @@ if (BUILD_EXAMPLES)
                        $<$<BOOL:${LIBM_REQUIRED}>:m>
                )
 
+# generate
+
+       add_executable (generate examples/generate.c)
+       target_link_libraries (generate PRIVATE sndfile)
+
 # sndfilehandle
 
        add_executable (sndfilehandle examples/sndfilehandle.cc)
@@ -658,6 +760,7 @@ if (BUILD_EXAMPLES)
                make_sine
                sfprocess
                list_formats
+               generate
                sndfilehandle
                )
 
@@ -716,6 +819,8 @@ if (ENABLE_PACKAGE_CONFIG)
                PUBLIC_HEADER DESTINATION       ${CMAKE_INSTALL_INCLUDEDIR}
        )
 
+       export (EXPORT SndFileTargets NAMESPACE SndFile:: FILE ${PROJECT_BINARY_DIR}/SndFileTargets.cmake)
+
        include (CMakePackageConfigHelpers)
 
        if (ENABLE_EXTERNAL_LIBS)
@@ -724,8 +829,19 @@ if (ENABLE_PACKAGE_CONFIG)
                set (SndFile_WITH_EXTERNAL_LIBS 0)
        endif ()
 
+       if(ENABLE_MPEG)
+               set (SndFile_WITH_MPEG 1)
+       else ()
+               set (SndFile_WITH_MPEG 0)
+       endif ()
+
        set (INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
        configure_package_config_file(cmake/SndFileConfig.cmake.in SndFileConfig.cmake
+               INSTALL_DESTINATION ${PROJECT_BINARY_DIR}
+               INSTALL_PREFIX ${PROJECT_BINARY_DIR}
+               PATH_VARS INCLUDE_INSTALL_DIR
+               )
+       configure_package_config_file(cmake/SndFileConfig.cmake.in SndFileConfig2.cmake
                INSTALL_DESTINATION ${CMAKE_INSTALL_PACKAGEDIR}
                PATH_VARS INCLUDE_INSTALL_DIR
                )
@@ -736,8 +852,12 @@ if (ENABLE_PACKAGE_CONFIG)
                DESTINATION ${CMAKE_INSTALL_PACKAGEDIR}
                )
        install(
+               FILES ${CMAKE_CURRENT_BINARY_DIR}/SndFileConfig2.cmake
+               RENAME SndFileConfig.cmake
+               DESTINATION     ${CMAKE_INSTALL_PACKAGEDIR}
+               )
+       install(
                FILES
-                       ${CMAKE_CURRENT_BINARY_DIR}/SndFileConfig.cmake
                        ${CMAKE_CURRENT_BINARY_DIR}/SndFileConfigVersion.cmake
                DESTINATION     ${CMAKE_INSTALL_PACKAGEDIR}
                )
@@ -1181,6 +1301,14 @@ if (BUILD_TESTING)
                        $<$<BOOL:${LIBM_REQUIRED}>:m>
                )
 
+       add_executable (mpeg_test tests/mpeg_test.c)
+       target_link_libraries (mpeg_test
+               PRIVATE
+                       sndfile
+                       test_utils
+                       $<$<BOOL:${LIBM_REQUIRED}>:m>
+               )
+
        add_executable (stdin_test tests/stdin_test.c)
        target_link_libraries (stdin_test
                PRIVATE
@@ -1412,6 +1540,10 @@ if (BUILD_TESTING)
        add_test (lossy_comp_test_ogg_opus lossy_comp_test ogg_opus)
        add_test (string_test_opus string_test opus)
 
+       ### mpeg-tests ###
+       add_test (mpeg_test mpeg_test)
+       add_test (compression_size_test_mpeg compression_size_test mpeg)
+
        ### io-tests
        add_test (stdio_test stdio_test)
        add_test (pipe_test pipe_test)
@@ -1467,5 +1599,8 @@ if (BUILD_TESTING)
 endif ()
 
 if (ENABLE_CPACK)
+       if ((NOT CPACK_PACKAGE_VERSION) AND CPACK_PACKAGE_VERSION_STAGE)
+               set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_FULL}")
+       endif ()
        include (CPack)
 endif ()
index afdcb55..0bf14b7 100644 (file)
 * Patches should always be submitted via a either Github "pull request" or a
   via emailed patches created using "git format-patch".
 * Patches for new features should include tests and documentation.
+* Commit messages should follow the ["How to Write a Git Commit Message"](https://chris.beams.io/posts/git-commit/) guide:
+  1. Separate subject from body with a blank line
+  2. Limit the subject line to 50 characters
+  3. Capitalize the subject line
+  4. Do not end the subject line with a period
+  5. Use the imperative mood in the subject line
+  6. Wrap the body at 72 characters
+  7. Use the body to explain what and why vs. how
+
+  Additional rule: the commit message may contain a prefix. The prefix must
+  contain the name of the feature or source file related to the commit and must
+  end with a colon followed by the message body.
+
+  Examples of good commit messages:
+  1. Fix typo
+  2. Update CHANGELOG.md
+  3. Add ACT file format support
+  4. ogg_vorbis: Fix granule position when seeking Vorbis streams
+
+  Examples of bad commit messages:
+  1. Fixed bug (rule 5)
+  2. update docs (rule 3)
+  3. Add very cool feature. (rule 4)
+
 * Patches to fix bugs should either pass all tests, or modify the tests in some
   sane way.
 * When a new feature is added for a particular file format and that feature
index 0b8bfa1..d2bbdcb 100644 (file)
@@ -13,8 +13,8 @@ endif
 endif
 
 EXTRA_DIST = libsndfile.spec.in sndfile.pc.in Scripts/android-configure.sh \
-       Scripts/linux-to-win-cross-configure.sh \
-       CMakeLists.txt $(cmake_files) Win32
+       NEWS.OLD CHANGELOG.md Scripts/linux-to-win-cross-configure.sh \
+       CMakeLists.txt $(cmake_files) Win32 SECURITY.md
 
 cmake_files = cmake/ClipMode.cmake cmake/FindFLAC.cmake \
        cmake/CMakeAutoGen.cmake cmake/CMakeAutoGenScript.cmake \
@@ -23,7 +23,8 @@ cmake_files = cmake/ClipMode.cmake cmake/FindFLAC.cmake \
        cmake/SndFileChecks.cmake cmake/TestInline.cmake \
        cmake/TestLargeFiles.cmake cmake/TestInline.c.in \
        cmake/FindOpus.cmake cmake/SndFileConfig.cmake.in \
-       cmake/CheckCPUArch.cmake cmake/CheckCPUArch.c.in
+       cmake/CheckCPUArch.cmake cmake/CheckCPUArch.c.in \
+       cmake/SetupABIVersions.cmake
 
 pkgconfig_DATA = sndfile.pc
 
@@ -62,26 +63,26 @@ endif
 lib_LTLIBRARIES = src/libsndfile.la
 include_HEADERS = include/sndfile.hh
 nodist_include_HEADERS = include/sndfile.h
-src_libsndfile_la_CFLAGS = $(EXTERNAL_XIPH_CFLAGS)
+src_libsndfile_la_CFLAGS = $(EXTERNAL_XIPH_CFLAGS) $(MPEG_CFLAGS)
 # MinGW requires -no-undefined if a DLL is to be built.
 src_libsndfile_la_LDFLAGS = -no-undefined -version-info $(SHARED_VERSION_INFO) $(SHLIB_VERSION_ARG)
 src_libsndfile_la_SOURCES = src/sndfile.c src/aiff.c src/au.c src/avr.c src/caf.c src/dwd.c src/flac.c src/g72x.c src/htk.c src/ircam.c \
        src/macos.c src/mat4.c src/mat5.c src/nist.c src/paf.c src/pvf.c src/raw.c src/rx2.c src/sd2.c \
        src/sds.c src/svx.c src/txw.c src/voc.c src/wve.c src/w64.c src/wavlike.c src/wav.c src/xi.c src/mpc2k.c src/rf64.c \
-       src/ogg_vorbis.c src/ogg_speex.c src/ogg_pcm.c src/ogg_opus.c src/ogg_vcomment.c \
-       src/common.h src/sfconfig.h src/sfendian.h src/wavlike.h src/sf_unistd.h src/ogg.h src/chanmap.h src/ogg_vcomment.h
+       src/ogg.c src/ogg.h src/ogg_vorbis.c src/ogg_speex.c src/ogg_pcm.c src/ogg_opus.c src/ogg_vcomment.c src/ogg_vcomment.h \
+       src/common.h src/sfconfig.h src/sfendian.h src/wavlike.h src/sf_unistd.h src/chanmap.h src/mpeg.c
 nodist_src_libsndfile_la_SOURCES = $(nodist_include_HEADERS)
 src_libsndfile_la_LIBADD = src/GSM610/libgsm.la src/G72x/libg72x.la src/ALAC/libalac.la \
-       src/libcommon.la $(EXTERNAL_XIPH_LIBS) -lm
+       src/libcommon.la $(EXTERNAL_XIPH_LIBS) -lm $(MPEG_LIBS)
 EXTRA_src_libsndfile_la_DEPENDENCIES = $(SYMBOL_FILES)
 
 noinst_LTLIBRARIES = src/libcommon.la
-src_libcommon_la_CFLAGS = $(EXTERNAL_XIPH_CFLAGS)
+src_libcommon_la_CFLAGS = $(EXTERNAL_XIPH_CFLAGS) $(MPEG_CFLAGS)
 src_libcommon_la_SOURCES = src/common.c src/file_io.c src/command.c src/pcm.c src/ulaw.c src/alaw.c \
        src/float32.c src/double64.c src/ima_adpcm.c src/ms_adpcm.c src/gsm610.c src/dwvw.c src/vox_adpcm.c \
        src/interleave.c src/strings.c src/dither.c src/cart.c src/broadcast.c src/audio_detect.c \
-       src/ima_oki_adpcm.c src/ima_oki_adpcm.h src/alac.c src/chunk.c src/ogg.c src/chanmap.c \
-       src/windows.c src/id3.c src/nms_adpcm.c $(WIN_VERSION_FILE)
+       src/ima_oki_adpcm.c src/ima_oki_adpcm.h src/alac.c src/chunk.c src/chanmap.c \
+       src/windows.c src/id3.c src/id3.h src/nms_adpcm.c src/mpeg_decode.c src/mpeg_l3_encode.c src/mpeg.h $(WIN_VERSION_FILE)
 
 check_PROGRAMS = src/test_main
 src_test_main_SOURCES = src/test_main.c src/test_main.h src/test_conversions.c src/test_float.c src/test_endswap.c \
@@ -135,19 +136,19 @@ src_ALAC_libalac_la_SOURCES = src/ALAC/ALACAudioTypes.h src/ALAC/ALACBitUtilitie
 SYMBOL_SCRIPT = $(top_srcdir)/src/create_symbols_file.py
 
 src/Symbols.gnu-binutils: $(SYMBOL_SCRIPT)
-       $(PYTHON) $(SYMBOL_SCRIPT) linux $(VERSION) > $(top_srcdir)/$@
+       $(PYTHON) $(SYMBOL_SCRIPT) linux $(ABI_VERSION) > $(top_srcdir)/$@
 
 src/Symbols.darwin: $(SYMBOL_SCRIPT)
-       $(PYTHON) $(SYMBOL_SCRIPT) darwin $(VERSION) > $(top_srcdir)/$@
+       $(PYTHON) $(SYMBOL_SCRIPT) darwin $(ABI_VERSION) > $(top_srcdir)/$@
 
 src/libsndfile-1.def: $(SYMBOL_SCRIPT)
-       $(PYTHON) $(SYMBOL_SCRIPT) win32 $(VERSION) > $(top_srcdir)/$@
+       $(PYTHON) $(SYMBOL_SCRIPT) win32 $(ABI_VERSION) > $(top_srcdir)/$@
 
 src/Symbols.os2: $(SYMBOL_SCRIPT)
-       $(PYTHON) $(SYMBOL_SCRIPT) os2 $(VERSION) > $(top_srcdir)/$@
+       $(PYTHON) $(SYMBOL_SCRIPT) os2 $(ABI_VERSION) > $(top_srcdir)/$@
 
 src/Symbols.static: $(SYMBOL_SCRIPT)
-       $(PYTHON) $(SYMBOL_SCRIPT) static $(VERSION) > $(top_srcdir)/$@
+       $(PYTHON) $(SYMBOL_SCRIPT) static $(ABI_VERSION) > $(top_srcdir)/$@
 
 #===============================================================================
 # Building windows resource files (if needed).
@@ -221,7 +222,8 @@ check_PROGRAMS += tests/sfversion tests/floating_point_test tests/write_read_tes
        tests/locale_test tests/win32_ordinal_test tests/ogg_test tests/compression_size_test \
        tests/checksum_test tests/external_libs_test tests/rdwr_test tests/format_check_test $(CPP_TEST) \
        tests/channel_test tests/long_read_write_test tests/stdin_test tests/stdout_test \
-       tests/dither_test tests/fix_this tests/largefile_test tests/benchmark tests/ogg_opus_test
+       tests/dither_test tests/fix_this tests/largefile_test tests/benchmark tests/ogg_opus_test \
+       tests/mpeg_test
 
 BUILT_SOURCES += \
        tests/write_read_test.c \
@@ -377,6 +379,9 @@ tests_cpp_test_LDADD = src/libsndfile.la
 tests_checksum_test_SOURCES = tests/checksum_test.c tests/utils.c tests/utils.h
 tests_checksum_test_LDADD = src/libsndfile.la
 
+tests_mpeg_test_SOURCES = tests/mpeg_test.c tests/utils.c tests/utils.h
+tests_mpeg_test_LDADD = src/libsndfile.la
+
 # Lite remove start
 tests_dwvw_test_SOURCES = tests/dwvw_test.c tests/utils.c tests/utils.h
 tests_dwvw_test_LDADD = src/libsndfile.la
@@ -457,7 +462,8 @@ endif
 
 if USE_OSSFUZZERS
 noinst_PROGRAMS += \
-       ossfuzz/sndfile_fuzzer
+       ossfuzz/sndfile_fuzzer \
+       ossfuzz/sndfile_alt_fuzzer
 
 noinst_LTLIBRARIES += \
        ossfuzz/libstandaloneengine.la
@@ -468,6 +474,11 @@ ossfuzz_sndfile_fuzzer_CXXFLAGS = $(AM_CXXFLAGS) $(FUZZ_FLAG)
 ossfuzz_sndfile_fuzzer_LDFLAGS = $(AM_LDFLAGS) -static
 ossfuzz_sndfile_fuzzer_LDADD = src/libsndfile.la $(FUZZ_LDADD)
 
+ossfuzz_sndfile_alt_fuzzer_SOURCES = ossfuzz/sndfile_alt_fuzzer.cc
+ossfuzz_sndfile_alt_fuzzer_CXXFLAGS = $(AM_CXXFLAGS) $(FUZZ_FLAG)
+ossfuzz_sndfile_alt_fuzzer_LDFLAGS = $(AM_LDFLAGS) -static
+ossfuzz_sndfile_alt_fuzzer_LDADD = src/libsndfile.la $(FUZZ_LDADD)
+
 ossfuzz_libstandaloneengine_la_SOURCES = ossfuzz/standaloneengine.cc ossfuzz/testinput.h
 ossfuzz_libstandaloneengine_la_CXXFLAGS = $(AM_CXXFLAGS)
 
diff --git a/NEWS b/NEWS.OLD
similarity index 100%
rename from NEWS
rename to NEWS.OLD
diff --git a/README b/README
index 93b4b29..3ad4b34 100644 (file)
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-This is libsndfile, 1.0.29
+This is libsndfile, 1.1.0
 
 libsndfile is a library of C routines for reading and writing
 files containing sampled audio data.
index c12bc1a..82b0b39 100644 (file)
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ for details.
 ## Hacking
 
 The canonical source code repository for libsndfile is at
-[http://libsndfile.github.io/libsndfile/][github].
+<https://github.com/libsndfile/libsndfile>.
 
 You can grab the source code using:
 
@@ -33,14 +33,15 @@ below.
 Setting up a build environment for libsndfile on Debian or Ubuntu is as simple as:
 
     sudo apt install autoconf autogen automake build-essential libasound2-dev \
-      libflac-dev libogg-dev libtool libvorbis-dev libopus-dev pkg-config python
+      libflac-dev libogg-dev libtool libvorbis-dev libopus-dev libmp3lame-dev \
+      libmpg123-dev pkg-config python
 
 For other Linux distributions or any of the *BSDs, the setup should be similar
 although the package install tools and package names may be slightly different.
 
 Similarly on Mac OS X, assuming [brew] is already installed:
 
-    brew install autoconf autogen automake flac libogg libtool libvorbis opus pkg-config
+    brew install autoconf autogen automake flac libogg libtool libvorbis opus mpg123 pkg-config
 
 Once the build environment has been set up, building and testing libsndfile is
 as simple as:
@@ -134,6 +135,8 @@ You can pass additional options with `/D<parameter>=<value>` when you run
   `ON` by default. Setting `BUILD_SHARED_LIBS` to `ON` disables this option.
 * `ENABLE_EXTERNAL_LIBS` - enable Ogg, Vorbis, FLAC and Opus support. This
   option is available and set to `ON` if all dependency libraries were found.
+* `ENABLE_MPEG` - MP3 support. This option is available and set to `ON` if all
+  dependency libraries were found.
 * `ENABLE_CPU_CLIP` - enable tricky cpu specific clipper. Enabled and set to
   `ON` when CPU clips negative\positive. Don't touch it if you are not sure
 * `ENABLE_BOW_DOCS` - enable black-on-white documentation theme, `OFF` by
@@ -232,7 +235,7 @@ You can find related option in Visual Studio project properties:
 
     C/C++ -> Code Generation -> Runtime Library
 
-Dynamic version of system CRT library is defaut and it means that end user needs
+Dynamic version of system CRT library is default and it means that end user needs
 to have the same runtime library installed on his system. Most likely it is so,
 but if it is not, the user will see this error message using libsndfile DLL:
 
@@ -270,21 +273,35 @@ have standard option `CMAKE_MSVC_RUNTIME_LIBRARY` now.
 
 Second advice is about Ogg, Vorbis FLAC and Opus support. Searching external
 libraries under Windows is a little bit tricky. The best way is to use
-[Vcpkg](https://github.com/Microsoft/vcpkg). You need to install static libogg,
-libvorbis, libflac and libopus libraries:
+[Vcpkg](https://github.com/Microsoft/vcpkg).
 
-    vcpkg install libogg:x64-windows-static libvorbis:x64-windows-static
-    libflac:x64-windows-static opus:x64-windows-static libogg:x86-windows-static
-    libvorbis:x86-windows-static libflac:x86-windows-static opus:x86-windows-static
-
-Then and add this parameter to cmake command line:
+Install Vcpkg and then add this parameter to cmake command line:
 
     -DCMAKE_TOOLCHAIN_FILE=<path-to-vcpkg>/scripts/buildsystems/vcpkg.cmake
 
-You also need to set `VCPKG_TARGET_TRIPLET` because you use static libraries:
+You also need to set `VCPKG_TARGET_TRIPLET` if you want to use static libraries:
 
     -DVCPKG_TARGET_TRIPLET=x64-windows-static
 
+Then you need to install static libogg, libvorbis, libflac, libopus, mpg123 and
+mp3lame Vcpkg packages.
+
+After 1.1.0beta2 you don't need to install dependencies manually. Libsndfile
+now supports [Vcpkg manifest mode](https://vcpkg.readthedocs.io/en/latest/users/manifests/)
+and all dependencies are installed automatically.
+
+However, you can turn off the manifest mode and return to the classic mode using
+the `VCPKG_MANIFEST_MODE` parameter from the command line:
+
+    -DVCPKG_MANIFEST_MODE=OFF
+
+In classic mode, you need to install the required libraries manually:
+
+    vcpkg install libvorbis:x64-windows-static libflac:x64-windows-static
+    opus:x64-windows-static mp3lame:x86-windows-static mpg123:x86-windows-static
+    libvorbis:x86-windows-static libflac:x86-windows-static
+    opus:x86-windows-static mp3lame:x86-windows-static mpg123:x86-windows-static
+
 **Note**: Use must use the same CRT library for external libraries and the
 libsndfile library itself. For `*-static` triplets Vcpkg uses
 [static CRT](https://vcpkg.readthedocs.io/en/latest/users/triplets/).
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644 (file)
index 0000000..a32393d
--- /dev/null
@@ -0,0 +1,11 @@
+# Security Policy
+
+## Supported Versions
+
+| Version | Supported          |
+| ------- | ------------------ |
+| 1.1.x   | :white_check_mark: |
+
+## Reporting a Vulnerability
+
+Please send report privately to evpobry@gmail.com, and include how would you like to be credited.
diff --git a/cmake/FindLame.cmake b/cmake/FindLame.cmake
new file mode 100644 (file)
index 0000000..be32475
--- /dev/null
@@ -0,0 +1,66 @@
+# - Find lame
+# Find the native lame includes and libraries
+#
+#  LAME_INCLUDE_DIRS - where to find lame.h, etc.
+#  LAME_LIBRARIES    - List of libraries when using lame.
+#  LAME_FOUND        - True if Lame found.
+
+if (LAME_INCLUDE_DIR)
+    # Already in cache, be silent
+    set(LAME_FIND_QUIETLY TRUE)
+endif ()
+
+find_path (LAME_INCLUDE_DIR lame/lame.h
+       HINTS
+               ${LAME_ROOT}
+       )
+
+# MSVC built lame may be named mp3lame_static.
+# The provided project files name the library with the lib prefix.
+
+find_library (LAME_LIBRARY
+       NAMES
+               mp3lame
+               mp3lame_static
+               libmp3lame
+               libmp3lame_static
+               libmp3lame-static
+       HINTS
+               ${LAME_ROOT}
+       )
+
+find_library (LAME_HIP_LIBRARY
+       NAMES
+               mpghip-static
+               libmpghip-static
+       HINTS
+               ${LAME_ROOT}
+       )
+
+# Handle the QUIETLY and REQUIRED arguments and set LAME_FOUND
+# to TRUE if all listed variables are TRUE.
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args (Lame
+       REQUIRED_VARS
+               LAME_LIBRARY
+               LAME_INCLUDE_DIR
+       )
+
+if (LAME_FOUND)
+       set (LAME_LIBRARIES ${LAME_LIBRARY} ${LAME_HIP_LIBRARY})
+       set (LAME_INCLUDE_DIRS ${LAME_INCLUDE_DIR})
+
+       if (NOT TARGET Lame::Lame)
+               add_library (Lame::Lame UNKNOWN IMPORTED)
+               set_target_properties (Lame::Lame PROPERTIES
+                       INTERFACE_INCLUDE_DIRECTORIES "${LAME_INCLUDE_DIRS}"
+                       IMPORTED_LOCATION "${LAME_LIBRARY}"
+               )
+               if (LAME_HIP_LIBRARY)
+                       set_property (TARGET Lame::Lame APPEND PROPERTY
+                               INTERFACE_LINK_LIBRARIES "${LAME_HIP_LIBRARY}")
+               endif ()
+       endif ()
+endif ()
+
+mark_as_advanced(LAME_INCLUDE_DIR LAME_LIBRARY LAME_HIP_LIBRARY)
diff --git a/cmake/FindMpg123.cmake b/cmake/FindMpg123.cmake
new file mode 100644 (file)
index 0000000..88b1622
--- /dev/null
@@ -0,0 +1,64 @@
+# - Find mpg123
+# Find the native mpg123 includes and libraries
+#
+#  MPG123_INCLUDE_DIRS - where to find mpg123.h, etc.
+#  MPG123_LIBRARIES    - List of libraries when using mpg123.
+#  MPG123_FOUND        - True if Mpg123 found.
+
+if (MPG123_INCLUDE_DIR)
+    # Already in cache, be silent
+    set(MPG123_FIND_QUIETLY TRUE)
+endif ()
+
+find_package (PkgConfig QUIET)
+pkg_check_modules(PC_MPG123 QUIET libmpg123>=1.25.10)
+
+set (MPG123_VERSION ${PC_MPG123_VERSION})
+
+find_path (MPG123_INCLUDE_DIR mpg123.h
+       HINTS
+               ${PC_MPG123_INCLUDEDIR}
+               ${PC_MPG123_INCLUDE_DIRS}
+               ${MPG123_ROOT}
+       )
+
+# MSVC built mpg123 may be named mpg123_static.
+# The provided project files name the library with the lib prefix.
+
+find_library (MPG123_LIBRARY
+       NAMES
+               mpg123
+               mpg123_static
+               libmpg123
+               libmpg123_static
+       HINTS
+               ${PC_MPG123_LIBDIR}
+               ${PC_MPG123_LIBRARY_DIRS}
+               ${MPG123_ROOT}
+       )
+
+# Handle the QUIETLY and REQUIRED arguments and set MPG123_FOUND
+# to TRUE if all listed variables are TRUE.
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args (Mpg123
+       REQUIRED_VARS
+               MPG123_LIBRARY
+               MPG123_INCLUDE_DIR
+       VERSION_VAR
+               MPG123_VERSION
+       )
+
+if (MPG123_FOUND)
+       set (MPG123_LIBRARIES ${MPG123_LIBRARY})
+       set (MPG123_INCLUDE_DIRS ${MPG123_INCLUDE_DIR})
+
+       if (NOT TARGET MPG123::libmpg123)
+               add_library (MPG123::libmpg123 UNKNOWN IMPORTED)
+               set_target_properties (MPG123::libmpg123 PROPERTIES
+                       INTERFACE_INCLUDE_DIRECTORIES "${MPG123_INCLUDE_DIRS}"
+                       IMPORTED_LOCATION "${MPG123_LIBRARIES}"
+               )
+       endif ()
+endif ()
+
+mark_as_advanced(MPG123_INCLUDE_DIR MPG123_LIBRARY)
diff --git a/cmake/SetupABIVersions.cmake b/cmake/SetupABIVersions.cmake
new file mode 100644 (file)
index 0000000..331a2bd
--- /dev/null
@@ -0,0 +1,56 @@
+# Inspiration: https://github.com/ros2-dotnet/Fast-RTPS
+
+macro (SETUP_ABI_VERSIONS)
+
+    file (STRINGS ${PROJECT_SOURCE_DIR}/configure.ac CONFIGURE_AC_CONTENT)
+    file (STRINGS
+        configure.ac
+        SNDFILE_LT_CURRENT_TMP
+        REGEX "^m4_define\\(\\[?lt_current\\]?, *\\[?[0-9]+\\]?\\)"
+        )
+    string (REGEX REPLACE "m4_define\\(\\[?lt_current\\]?, *\\[?([0-9]+)\\]?\\)"
+        "\\1"
+        SNDFILE_LT_CURRENT
+        ${SNDFILE_LT_CURRENT_TMP}
+        )
+
+    file (STRINGS
+        configure.ac
+        SNDFILE_LT_REVISION_TMP
+        REGEX "^m4_define\\(\\[?lt_revision\\]?, *\\[?[0-9]+\\]?\\)"
+        )
+    string (REGEX REPLACE "m4_define\\(\\[?lt_revision\\]?, *\\[?([0-9]+)\\]?\\)"
+        "\\1"
+        SNDFILE_LT_REVISION
+        ${SNDFILE_LT_REVISION_TMP}
+        )
+
+    file (STRINGS
+        configure.ac
+        SNDFILE_LT_AGE_TMP
+        REGEX "^m4_define\\(\\[?lt_age\\]?, *\\[?[0-9]+\\]?\\)"
+        )
+    string (REGEX REPLACE "m4_define\\(\\[?lt_age\\]?, *\\[?([0-9]+)\\]?\\)"
+        "\\1"
+        SNDFILE_LT_AGE
+        ${SNDFILE_LT_AGE_TMP}
+        )
+
+    #
+    # Calculate CMake compatible ABI version from libtool version.
+    #
+
+    math (EXPR SNDFILE_ABI_VERSION_MAJOR "${SNDFILE_LT_CURRENT} - ${SNDFILE_LT_AGE}")
+    set (SNDFILE_ABI_VERSION_MINOR ${SNDFILE_LT_AGE})
+    set (SNDFILE_ABI_VERSION_PATCH ${SNDFILE_LT_REVISION})
+    set (SNDFILE_ABI_VERSION "${SNDFILE_ABI_VERSION_MAJOR}.${SNDFILE_ABI_VERSION_MINOR}.${SNDFILE_ABI_VERSION_PATCH}")
+
+    #
+    # Apple platform current and compatibility versions.
+    #
+
+    math (EXPR SNDFILE_MACHO_CURRENT_VERSION_MAJOR "${SNDFILE_ABI_VERSION_MAJOR} + ${SNDFILE_ABI_VERSION_MINOR} + 1")
+    set (SNDFILE_MACHO_CURRENT_VERSION "${SNDFILE_MACHO_CURRENT_VERSION_MAJOR}.${SNDFILE_ABI_VERSION_PATCH}.0")
+    set (SNDFILE_MACHO_COMPATIBILITY_VERSION "${SNDFILE_MACHO_CURRENT_VERSION_MAJOR}.0.0")
+
+endmacro (SETUP_ABI_VERSIONS)
index 9b52d15..f5d5994 100644 (file)
@@ -56,6 +56,14 @@ else ()
        set (HAVE_EXTERNAL_XIPH_LIBS 0)
 endif ()
 
+find_package (Lame)
+find_package (Mpg123 1.25.10)
+if (LAME_FOUND AND (TARGET MPG123::libmpg123))
+       set (HAVE_MPEG_LIBS 1)
+else ()
+       set (HAVE_MPEG_LIBS 0)
+endif()
+
 find_package (Speex)
 find_package (SQLite3)
 
@@ -70,6 +78,7 @@ check_include_file (sys/time.h                HAVE_SYS_TIME_H)
 check_include_file (sys/types.h                HAVE_SYS_TYPES_H)
 check_include_file (unistd.h           HAVE_UNISTD_H)
 check_include_file (immintrin.h                HAVE_IMMINTRIN_H)
+check_include_file (stdbool.h          HAVE_STDBOOL_H)
 
 check_cpu_arch_x86 (CPU_IS_X86)
 check_cpu_arch_x64 (CPU_IS_X64)
index e33c56b..1d5463a 100644 (file)
@@ -4,6 +4,7 @@ set(SndFile_VERSION_MINOR @PROJECT_VERSION_MINOR@)
 set(SndFile_VERSION_PATCH @PROJECT_VERSION_PATCH@)
 
 set (SndFile_WITH_EXTERNAL_LIBS @SndFile_WITH_EXTERNAL_LIBS@)
+set (SndFile_WITH_MPEG @SndFile_WITH_MPEG@)
 
 @PACKAGE_INIT@
 
@@ -16,6 +17,11 @@ if (SndFile_WITH_EXTERNAL_LIBS AND NOT @BUILD_SHARED_LIBS@)
        find_dependency (Opus)
 endif ()
 
+if (SndFile_WITH_MPEG AND NOT @BUILD_SHARED_LIBS@)
+       find_dependency (Lame)
+       find_dependency (MPG123)
+endif ()
+
 include (${CMAKE_CURRENT_LIST_DIR}/SndFileTargets.cmake)
 
 set_and_check (SndFile_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
index 78a79da..727b67b 100644 (file)
@@ -1,9 +1,9 @@
-dnl Copyright (C) 1999-2021  Erik de Castro Lopo <erikd@mega-nerd.com>.
+dnl Copyright (C) 1999-2022  Erik de Castro Lopo <erikd@mega-nerd.com>.
 
 dnl Require autoconf version >= 2.69
 AC_PREREQ([2.69])
 
-AC_INIT([libsndfile],[1.0.31],[sndfile@mega-nerd.com],
+AC_INIT([libsndfile],[1.1.0],[sndfile@mega-nerd.com],
                [libsndfile],[http://libsndfile.github.io/libsndfile/])
 
 dnl Check whether we want to set defaults for CFLAGS, CXXFLAGS, CPPFLAGS and LDFLAGS
@@ -30,7 +30,7 @@ AC_CANONICAL_HOST
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_HEADERS([src/config.h])
 
-AM_INIT_AUTOMAKE([1.14 foreign dist-bzip2 no-dist-gzip serial-tests subdir-objects])
+AM_INIT_AUTOMAKE([1.14 foreign dist-xz no-dist-gzip serial-tests subdir-objects])
 AM_SILENT_RULES([yes])
 
 dnl ====================================================================================
@@ -57,7 +57,7 @@ AC_LANG_POP([C++])
 AC_PROG_SED
 AM_PROG_AR
 
-LT_INIT([win32-dll])
+LT_INIT([disable-static win32-dll])
 LT_PROG_RC
 
 AC_PROG_INSTALL
@@ -84,17 +84,29 @@ dnl   5. If any interfaces have been added since the last public release, then i
 dnl      age.
 dnl   6. If any interfaces have been removed since the last public release, then set age
 dnl      to 0.
-SHARED_VERSION_INFO="1:31:0"
 
-dnl ------------------------------------------------------------------------------------
+dnl   This is libtool version of library, we add it to `--version-info` property.
+
+m4_define([lt_current], [1])
+m4_define([lt_revision], [34])
+m4_define([lt_age], [0])
+
+dnl This is ABI version for linker scripts, CMake uses the same format for
+dnl VERSION property of shared library.
+dnl The formula is: c:r:a -> c-a:a:r
+
+m4_define([abi_version_major], [m4_eval(lt_current - lt_age)])
+m4_define([abi_version_minor], [lt_age])
+m4_define([abi_version_patch], [lt_revision])
 
-AC_HEADER_STDC
+dnl ------------------------------------------------------------------------------------
 
 AC_CHECK_HEADERS([endian.h])
 AC_CHECK_HEADERS([byteswap.h])
 AC_CHECK_HEADERS([locale.h])
 AC_CHECK_HEADERS([sys/time.h])
 AC_CHECK_HEADERS([immintrin.h])
+AC_CHECK_HEADERS([stdbool.h])
 
 AC_HEADER_SYS_WAIT
 
@@ -129,9 +141,6 @@ AC_DEFINE_UNQUOTED([ENABLE_EXPERIMENTAL_CODE], [${EXPERIMENTAL_CODE}], [Set to 1
 AC_ARG_ENABLE([werror],
        [AS_HELP_STRING([--enable-werror], [enable -Werror in all Makefiles])])
 
-AC_ARG_ENABLE([stack-smash-protection],
-       [AS_HELP_STRING([--enable-stack-smash-protection], [Enable GNU GCC stack smash protection])])
-
 AC_ARG_ENABLE([cpu-clip],
        [AS_HELP_STRING([--disable-cpu-clip], [disable tricky cpu specific clipper])])
 
@@ -147,6 +156,9 @@ AC_ARG_ENABLE([alsa],
 AC_ARG_ENABLE([external-libs],
        [AS_HELP_STRING([--disable-external-libs], [disable use of FLAC, Ogg and Vorbis [[default=no]]])])
 
+AC_ARG_ENABLE([mpeg],
+       [AS_HELP_STRING([--disable-mpeg], [disable use of LAME/MPG123 for MPEG (MP3) [[defaults=no]]])])
+
 AC_ARG_ENABLE(octave,
        [AS_HELP_STRING([--enable-octave], [enable building of GNU Octave module])])
 
@@ -374,8 +386,8 @@ AS_IF([test -n "$PKG_CONFIG"], [
                                        fi
                                ], [
                                        AS_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([[*** One or more of the external libraries (ie libflac, libogg,]])
+                                       AC_MSG_WARN([[*** libvorbis and libopus) 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]])
@@ -388,6 +400,53 @@ AS_IF([test -n "$PKG_CONFIG"], [
 AC_DEFINE_UNQUOTED([HAVE_EXTERNAL_XIPH_LIBS], [$HAVE_EXTERNAL_XIPH_LIBS], [Will be set to 1 if flac, ogg, vorbis, and opus are available.])
 
 dnl ====================================================================================
+dnl  Check for MPEG libraris liblame
+
+ac_cv_lame="no"
+ac_cv_mpg123="no"
+HAVE_MPEG=0
+EXTERNAL_MPEG_REQUIRE=""
+EXTERNAL_MPEG_LIBS=""
+
+AS_IF([test -n "$PKG_CONFIG"], [
+               AS_IF([test "x$enable_mpeg" = "xno"], [
+                               AC_MSG_WARN([[*** MPEG (Lame/MPG123) disabled. ***]])
+                       ], [
+                               AC_CHECK_HEADER(lame/lame.h,
+                                                               lame_header_found="yes",
+                                                               lame_header_found="no")
+                               AC_SEARCH_LIBS(lame_set_VBR_q, [lame mp3lame], [lame_lib_found="yes"], [lame_lib_found="no"])
+                               AS_IF([test "x$lame_lib_found$lame_header_found" = "xyesyes"], [
+                                               ac_cv_lame="yes"
+                                       ], [
+                                               AC_MSG_WARN([["MPEG support selected but external Lame library cannot be found.]])
+                                       ])
+
+                               PKG_CHECK_MOD_VERSION([MPG123], [libmpg123 >= 1.25.10], [
+                                               ac_cv_mpg123="yes"
+                                       ], [
+                                               AC_MSG_WARN([["MPEG support selected but external MPG123 library cannot be found.]])
+                                       ])
+
+                               AS_IF([test "x$ac_cv_lame$ac_cv_mpg123" = "xyesyes"], [
+                                               enable_mpeg="yes"
+                                               HAVE_MPEG=1
+                                               EXTERNAL_MPEG_REQUIRE="libmpg123"
+                                               EXTERNAL_MPEG_LIBS="-lmp3lame"
+                                               MPEG_CFLAGS="$MPG123_CFLAGS"
+                                               MPEG_LIBS="$MPG123_LIBS"
+                                       ], [
+                                               enable_mpeg="no"
+                                               AS_ECHO([""])
+                                               AC_MSG_WARN([[*** MPEG support disabled.]])
+                                               AS_ECHO([""])
+                                       ])
+                       ])
+       ])
+
+AC_DEFINE_UNQUOTED([HAVE_MPEG], [$HAVE_MPEG], [Will be set to 1 if lame, mpg123 mpeg support is available.])
+
+dnl ====================================================================================
 dnl  Check for libsqlite3 (only used in regtest).
 
 ac_cv_sqlite3=0
@@ -574,18 +633,24 @@ AS_IF([test "x$enable_werror" = "xyes"], [
                AC_LANG_POP([C++])
        ])
 
-common_flags="-Wall -Wextra -Wpointer-arith -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Wundef -Wuninitialized -Winit-self -Wno-format-truncation"
-AX_APPEND_COMPILE_FLAGS([${common_flags} -Wvla -Wbad-function-cast -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Waggregate-return], [CFLAGS])
+common_flags="-Wall -Wextra -Wpointer-arith -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Wundef -Wuninitialized -Winit-self"
+common_cflags="${common_flags}"
+dnl Clang doesn't know about -Wno-format-truncation
+dnl and would spew tons of warnings otherwise.
+AS_IF([test "x$ax_cv_c_compiler_vendor" = "xgnu"], [
+               common_cflags+=" -Wno-format-truncation"
+       ])
+common_cxxflags="${common_flags}"
+AS_IF([test "x$ax_cv_cxx_compiler_vendor" = "xgnu"], [
+               common_cxxflags+=" -Wno-format-truncation"
+       ])
+
+AX_APPEND_COMPILE_FLAGS([${common_cflags} -Wvla -Wbad-function-cast -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Waggregate-return], [CFLAGS])
 
 AC_LANG_PUSH([C++])
-AX_APPEND_COMPILE_FLAGS([${common_flags} -Wctor-dtor-privacy -Wnon-virtual-dtor -Woverloaded-virtual -Wreorder -Wsign-promo], [CXXFLAGS])
+AX_APPEND_COMPILE_FLAGS([${common_cxxflags} -Wctor-dtor-privacy -Wnon-virtual-dtor -Woverloaded-virtual -Wreorder -Wsign-promo], [CXXFLAGS])
 AC_LANG_POP([C++])
 
-AS_IF([test "x$enable_stack_smash_protection" = "xyes"], [
-               XIPH_GCC_STACK_PROTECTOR
-               XIPH_GXX_STACK_PROTECTOR
-       ])
-
 AS_IF([test "x$enable_test_coverage" = "xyes"], [
                AX_APPEND_COMPILE_FLAGS([-coverage], [CFLAGS])
        ])
@@ -638,7 +703,7 @@ AS_IF([test "$HOST_TRIPLET" = "x86_64-w64-mingw32"], [
                OS_SPECIFIC_LINKS=" -static-libgcc $OS_SPECIFIC_LINKS"
        ])
 
-WIN_RC_VERSION=`echo $PACKAGE_VERSION | $SED -e "s/p.*//" -e "s/\./,/g"`
+WIN_RC_VERSION=`echo $PACKAGE_VERSION | $SED -e "s/pre.*//" -e "s/beta.*//" -e "s/\./,/g"`
 
 
 AS_IF([test "x$enable_static" = "xno"], [
@@ -657,7 +722,8 @@ AC_SUBST(HTML_BGCOLOUR)
 AC_SUBST(HTML_FGCOLOUR)
 
 AC_SUBST(SHLIB_VERSION_ARG)
-AC_SUBST(SHARED_VERSION_INFO)
+AC_SUBST([SHARED_VERSION_INFO], [lt_current:lt_revision:lt_age])
+AC_SUBST([ABI_VERSION], [abi_version_major.abi_version_minor.abi_version_patch])
 AC_SUBST(CLEAN_VERSION)
 AC_SUBST(VERSION_MAJOR)
 AC_SUBST(GEN_TOOL)
@@ -665,6 +731,7 @@ AC_SUBST(GEN_TOOL)
 AC_SUBST(WIN_RC_VERSION)
 
 AC_SUBST(HAVE_EXTERNAL_XIPH_LIBS)
+AC_SUBST(HAVE_MPEG)
 AC_SUBST(OS_SPECIFIC_CFLAGS)
 AC_SUBST(OS_SPECIFIC_LINKS)
 AC_SUBST(SNDIO_LIBS)
@@ -672,6 +739,11 @@ AC_SUBST(SNDIO_LIBS)
 AC_SUBST(EXTERNAL_XIPH_CFLAGS)
 AC_SUBST(EXTERNAL_XIPH_LIBS)
 AC_SUBST(EXTERNAL_XIPH_REQUIRE)
+AC_SUBST(EXTERNAL_MPEG_REQUIRE)
+AC_SUBST(MPG123_CFLAGS)
+AC_SUBST(MPG123_LIBS)
+AC_SUBST(MPEG_CFLAGS)
+AC_SUBST(MPEG_LIBS)
 AC_SUBST(SRC_BINDIR)
 AC_SUBST(TEST_BINDIR)
 
@@ -717,6 +789,7 @@ AC_MSG_RESULT([
     Experimental code : ................... ${enable_experimental:-no}
     Using ALSA in example programs : ...... ${enable_alsa:-no}
     External FLAC/Ogg/Vorbis/Opus : ....... ${enable_external_libs:-no}
+    External MPEG Lame/MPG123 : ........... ${enable_mpeg:-no}
     Building Octave interface : ........... ${OCTAVE_BUILD}
 
   Tools :
@@ -725,7 +798,6 @@ AC_MSG_RESULT([
     CXX Compiler Vendor is : .............. ${ax_cv_cxx_compiler_vendor} (${ax_cv_cxx_compiler_version})
 
     Sanitizer enabled : ................... ${enable_sanitizer:-no}
-    Stack smash protection : .............. ${enable_stack_smash_protection:-no}
 
   Installation directories :
 
index cca4714..e7c98e2 100644 (file)
@@ -438,10 +438,12 @@ Use CMake project.
 
 ## Q20 : Why doesn't libsndfile support MP3? {#Q020}
 
-In the past, MP3 was not supported because the technology behind MP3 was
+~~In the past, MP3 was not supported because the technology behind MP3 was
 patented. Those patents have now expired and there is an
 [open ticket](https://github.com/libsndfile/libsndfile/issues/258) to implement
-MP3 support.
+MP3 support.~~
+
+**Update :** Starting from version 1.1.0 libsndfile supports MP3 format.
 
 ## Q21 : How do I use libsndfile in a closed source or commercial program and comply with the license? {#Q021}
 
index c9f19d7..b3b6ea9 100644 (file)
@@ -1,6 +1,6 @@
 ---
 author: "The libsndfile team"
-version: "1.0.31"
+version: "1.1.0"
 
 markdown: kramdown
 plugins:
index 5a20c13..6c8119d 100644 (file)
@@ -12,7 +12,7 @@ title: libsndfile home page
     <a href="#history">History</a> -+-
     <a href="#features">Features</a> -+-
     <a href="#similar-or-related-projects">Similar or related projects</a> -+-
-    <a href="https://github.com/libsndfile/libsndfile/blob/master/NEWS">News</a>
+    <a href="https://github.com/libsndfile/libsndfile/blob/master/CHANGELOG.md">News</a>
     <br>
     <a href="development.html">Development</a> -+-
     <a href="api.html">Programming interface</a> -+-
index f009b74..7025443 100644 (file)
@@ -97,6 +97,11 @@ calling **sf_open**(). The only exception to this is the case of RAW files where
 the caller has to set the **samplerate**, **channels** and **format** fields to
 valid values. All other fields of the structure are filled in by the library.
 
+**Note:** The libsndfile library will reject values â€‹â€‹for **samplerate** field
+that are greater than `655350` and values â€‹â€‹for field **channels** that are
+greater than `1024`. These values â€‹â€‹represent the maximum theoretical limit and
+may be less for specific formats.
+
 When opening a file for write, the caller must fill in structure members
 **samplerate**, **channels**, and **format**.
 
@@ -107,74 +112,78 @@ value. The currently understood formats are listed in *sndfile.h* as follows and
 also include bitmasks for separating major and minor file types. Not all
 combinations of endian-ness and major and minor file types are valid.
 
-| Name                   | Value      | Description                                |
-|:-----------------------|:-----------|:-------------------------------------------|
-| **Major formats.**                                                               |
-| SF_FORMAT_WAV          | 0x010000   | Microsoft WAV format (little endian).      |
-| SF_FORMAT_AIFF         | 0x020000   | Apple/SGI AIFF format (big endian).        |
-| SF_FORMAT_AU           | 0x030000   | Sun/NeXT AU format (big endian).           |
-| SF_FORMAT_RAW          | 0x040000   | RAW PCM data.                              |
-| SF_FORMAT_PAF          | 0x050000   | Ensoniq PARIS file format.                 |
-| SF_FORMAT_SVX          | 0x060000   | Amiga IFF / SVX8 / SV16 format.            |
-| SF_FORMAT_NIST         | 0x070000   | Sphere NIST format.                        |
-| SF_FORMAT_VOC          | 0x080000   | VOC files.                                 |
-| SF_FORMAT_IRCAM        | 0x0A0000   | Berkeley/IRCAM/CARL                        |
-| SF_FORMAT_W64          | 0x0B0000   | Sonic Foundry's 64 bit RIFF/WAV            |
-| SF_FORMAT_MAT4         | 0x0C0000   | Matlab (tm) V4.2 / GNU Octave 2.0          |
-| SF_FORMAT_MAT5         | 0x0D0000   | Matlab (tm) V5.0 / GNU Octave 2.1          |
-| SF_FORMAT_PVF          | 0x0E0000   | Portable Voice Format                      |
-| SF_FORMAT_XI           | 0x0F0000   | Fasttracker 2 Extended Instrument          |
-| SF_FORMAT_HTK          | 0x100000   | HMM Tool Kit format                        |
-| SF_FORMAT_SDS          | 0x110000   | Midi Sample Dump Standard                  |
-| SF_FORMAT_AVR          | 0x120000   | Audio Visual Research                      |
-| SF_FORMAT_WAVEX        | 0x130000   | MS WAVE with WAVEFORMATEX                  |
-| 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.**                                                                    |
-| SF_FORMAT_PCM_S8       | 0x0001     | Signed 8 bit data                          |
-| SF_FORMAT_PCM_16       | 0x0002     | Signed 16 bit data                         |
-| SF_FORMAT_PCM_24       | 0x0003     | Signed 24 bit data                         |
-| SF_FORMAT_PCM_32       | 0x0004     | Signed 32 bit data                         |
-| SF_FORMAT_PCM_U8       | 0x0005     | Unsigned 8 bit data (WAV and RAW only)     |
-| SF_FORMAT_FLOAT        | 0x0006     | 32 bit float data                          |
-| SF_FORMAT_DOUBLE       | 0x0007     | 64 bit float data                          |
-| SF_FORMAT_ULAW         | 0x0010     | U-Law encoded.                             |
-| SF_FORMAT_ALAW         | 0x0011     | A-Law encoded.                             |
-| SF_FORMAT_IMA_ADPCM    | 0x0012     | IMA ADPCM.                                 |
-| SF_FORMAT_MS_ADPCM     | 0x0013     | Microsoft ADPCM.                           |
-| SF_FORMAT_GSM610       | 0x0020     | GSM 6.10 encoding.                         |
-| SF_FORMAT_VOX_ADPCM    | 0x0021     | OKI / Dialogix ADPCM                       |
-| SF_FORMAT_NMS_ADPCM_16 | 0x0022     | 16kbs NMS G721-variant encoding.           |
-| SF_FORMAT_NMS_ADPCM_24 | 0x0023     | 24kbs NMS G721-variant encoding.           |
-| SF_FORMAT_NMS_ADPCM_32 | 0x0024     | 32kbs NMS G721-variant encoding.           |
-| SF_FORMAT_G721_32      | 0x0030     | 32kbs G721 ADPCM encoding.                 |
-| SF_FORMAT_G723_24      | 0x0031     | 24kbs G723 ADPCM encoding.                 |
-| SF_FORMAT_G723_40      | 0x0032     | 40kbs G723 ADPCM encoding.                 |
-| SF_FORMAT_DWVW_12      | 0x0040     | 12 bit Delta Width Variable Word encoding. |
-| SF_FORMAT_DWVW_16      | 0x0041     | 16 bit Delta Width Variable Word encoding. |
-| SF_FORMAT_DWVW_24      | 0x0042     | 24 bit Delta Width Variable Word encoding. |
-| SF_FORMAT_DWVW_N       | 0x0043     | N bit Delta Width Variable Word encoding.  |
-| 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.                      |
-| SF_FORMAT_OPUS         | 0x0064     | Xiph/Skype Opus encoding.                  |
-| SF_FORMAT_ALAC_16      | 0x0070     | Apple Lossless Audio Codec (16 bit).       |
-| SF_FORMAT_ALAC_20      | 0x0071     | Apple Lossless Audio Codec (20 bit).       |
-| SF_FORMAT_ALAC_24      | 0x0072     | Apple Lossless Audio Codec (24 bit).       |
-| SF_FORMAT_ALAC_32      | 0x0073     | Apple Lossless Audio Codec (32 bit).       |
-| **Endian-ness options.**                                                         |
-| SF_ENDIAN_FILE         | 0x00000000 | Default file endian-ness.                  |
-| SF_ENDIAN_LITTLE       | 0x10000000 | Force little endian-ness.                  |
-| SF_ENDIAN_BIG          | 0x20000000 | Force big endian-ness.                     |
-| SF_ENDIAN_CPU          | 0x30000000 | Force CPU endian-ness.                     |
-| SF_FORMAT_SUBMASK      | 0x0000FFFF |                                            |
-| SF_FORMAT_TYPEMASK     | 0x0FFF0000 |                                            |
-| SF_FORMAT_ENDMASK      | 0x30000000 |                                            |
+| Name                     | Value      | Description                                |
+|:-------------------------|:-----------|:-------------------------------------------|
+| **Major formats.**                                                                 |
+| SF_FORMAT_WAV            | 0x010000   | Microsoft WAV format (little endian).      |
+| SF_FORMAT_AIFF           | 0x020000   | Apple/SGI AIFF format (big endian).        |
+| SF_FORMAT_AU             | 0x030000   | Sun/NeXT AU format (big endian).           |
+| SF_FORMAT_RAW            | 0x040000   | RAW PCM data.                              |
+| SF_FORMAT_PAF            | 0x050000   | Ensoniq PARIS file format.                 |
+| SF_FORMAT_SVX            | 0x060000   | Amiga IFF / SVX8 / SV16 format.            |
+| SF_FORMAT_NIST           | 0x070000   | Sphere NIST format.                        |
+| SF_FORMAT_VOC            | 0x080000   | VOC files.                                 |
+| SF_FORMAT_IRCAM          | 0x0A0000   | Berkeley/IRCAM/CARL                        |
+| SF_FORMAT_W64            | 0x0B0000   | Sonic Foundry's 64 bit RIFF/WAV            |
+| SF_FORMAT_MAT4           | 0x0C0000   | Matlab (tm) V4.2 / GNU Octave 2.0          |
+| SF_FORMAT_MAT5           | 0x0D0000   | Matlab (tm) V5.0 / GNU Octave 2.1          |
+| SF_FORMAT_PVF            | 0x0E0000   | Portable Voice Format                      |
+| SF_FORMAT_XI             | 0x0F0000   | Fasttracker 2 Extended Instrument          |
+| SF_FORMAT_HTK            | 0x100000   | HMM Tool Kit format                        |
+| SF_FORMAT_SDS            | 0x110000   | Midi Sample Dump Standard                  |
+| SF_FORMAT_AVR            | 0x120000   | Audio Visual Research                      |
+| SF_FORMAT_WAVEX          | 0x130000   | MS WAVE with WAVEFORMATEX                  |
+| 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                              |
+| SF_FORMAT_MPEG           | 0x230000   | MPEG-1/2 audio stream                      |
+| **Subtypes.**                                                                      |
+| SF_FORMAT_PCM_S8         | 0x0001     | Signed 8 bit data                          |
+| SF_FORMAT_PCM_16         | 0x0002     | Signed 16 bit data                         |
+| SF_FORMAT_PCM_24         | 0x0003     | Signed 24 bit data                         |
+| SF_FORMAT_PCM_32         | 0x0004     | Signed 32 bit data                         |
+| SF_FORMAT_PCM_U8         | 0x0005     | Unsigned 8 bit data (WAV and RAW only)     |
+| SF_FORMAT_FLOAT          | 0x0006     | 32 bit float data                          |
+| SF_FORMAT_DOUBLE         | 0x0007     | 64 bit float data                          |
+| SF_FORMAT_ULAW           | 0x0010     | U-Law encoded.                             |
+| SF_FORMAT_ALAW           | 0x0011     | A-Law encoded.                             |
+| SF_FORMAT_IMA_ADPCM      | 0x0012     | IMA ADPCM.                                 |
+| SF_FORMAT_MS_ADPCM       | 0x0013     | Microsoft ADPCM.                           |
+| SF_FORMAT_GSM610         | 0x0020     | GSM 6.10 encoding.                         |
+| SF_FORMAT_VOX_ADPCM      | 0x0021     | OKI / Dialogix ADPCM                       |
+| SF_FORMAT_NMS_ADPCM_16   | 0x0022     | 16kbs NMS G721-variant encoding.           |
+| SF_FORMAT_NMS_ADPCM_24   | 0x0023     | 24kbs NMS G721-variant encoding.           |
+| SF_FORMAT_NMS_ADPCM_32   | 0x0024     | 32kbs NMS G721-variant encoding.           |
+| SF_FORMAT_G721_32        | 0x0030     | 32kbs G721 ADPCM encoding.                 |
+| SF_FORMAT_G723_24        | 0x0031     | 24kbs G723 ADPCM encoding.                 |
+| SF_FORMAT_G723_40        | 0x0032     | 40kbs G723 ADPCM encoding.                 |
+| SF_FORMAT_DWVW_12        | 0x0040     | 12 bit Delta Width Variable Word encoding. |
+| SF_FORMAT_DWVW_16        | 0x0041     | 16 bit Delta Width Variable Word encoding. |
+| SF_FORMAT_DWVW_24        | 0x0042     | 24 bit Delta Width Variable Word encoding. |
+| SF_FORMAT_DWVW_N         | 0x0043     | N bit Delta Width Variable Word encoding.  |
+| 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.                      |
+| SF_FORMAT_OPUS           | 0x0064     | Xiph/Skype Opus encoding.                  |
+| SF_FORMAT_ALAC_16        | 0x0070     | Apple Lossless Audio Codec (16 bit).       |
+| SF_FORMAT_ALAC_20        | 0x0071     | Apple Lossless Audio Codec (20 bit).       |
+| SF_FORMAT_ALAC_24        | 0x0072     | Apple Lossless Audio Codec (24 bit).       |
+| SF_FORMAT_ALAC_32        | 0x0073     | Apple Lossless Audio Codec (32 bit).       |
+| SF_FORMAT_MPEG_LAYER_I   | 0x0080     | MPEG-1 Audio Layer I.                      |
+| SF_FORMAT_MPEG_LAYER_II  | 0x0081     | MPEG-1 Audio Layer II.                     |
+| SF_FORMAT_MPEG_LAYER_III | 0x0082     | MPEG-2 Audio Layer III.                    |
+| **Endian-ness options.**                                                           |
+| SF_ENDIAN_FILE           | 0x00000000 | Default file endian-ness.                  |
+| SF_ENDIAN_LITTLE         | 0x10000000 | Force little endian-ness.                  |
+| SF_ENDIAN_BIG            | 0x20000000 | Force big endian-ness.                     |
+| SF_ENDIAN_CPU            | 0x30000000 | Force CPU endian-ness.                     |
+| SF_FORMAT_SUBMASK        | 0x0000FFFF |                                            |
+| SF_FORMAT_TYPEMASK       | 0x0FFF0000 |                                            |
+| SF_FORMAT_ENDMASK        | 0x30000000 |                                            |
 
 Every call to **sf_open**() should be matched with a call to
 [**sf_close**()](#close) to free up memory allocated during the call to **sf_open**().
index 5e6606f..6d2133a 100644 (file)
@@ -81,6 +81,8 @@ The available commands are as follows:
 | [SFC_RF64_AUTO_DOWNGRADE](#sfc_rf64_auto_downgrade)               | Set auto downgrade from RF64 to WAV.                    |
 | [SFC_GET_ORIGINAL_SAMPLERATE](#sfc_get_original_samplerate)       | Get original samplerate metadata.                       |
 | [SFC_SET_ORIGINAL_SAMPLERATE](#sfc_set_original_samplerate)       | Set original samplerate metadata.                       |
+| [SFC_GET_BITRATE_MODE](#sfc_get_bitrate_mode)                     | Get bitrate mode.
+| [SFC_SET_BITRATE_MODE](#sfc_set_bitrate_mode)                     | Set bitrate mode.
 
 ---
 
@@ -1927,3 +1929,63 @@ Returns SF_TRUE on success, SF_FALSE otherwise.
 On write, can only succeed if no data has been written. On read, if successful,
 [SFC_GET_CURRENT_SF_INFO](#sfc_get_current_sf_info) should be called to
 determine the new frames count and samplerate
+
+## SFC_GET_BITRATE_MODE
+
+Get bitrate mode.
+
+The bitrate mode is one of:
+
+| Name                     | Value | Description       |
+|:-------------------------|:------|:------------------|
+| SF_BITRATE_MODE_CONSTANT | 800   | Constant bitrate. |
+| SF_BITRATE_MODE_AVERAGE  | 801   | Average bitrate.  |
+| SF_BITRATE_MODE_VARIABLE | 802   | Variable bitrate. |
+
+### Parameters
+
+sndfile
+: A valid SNDFILE* pointer
+
+cmd
+: SFC_GET_BITRATE_MODE
+
+data
+: NULL
+
+datasize
+: anything
+
+### Return value
+
+Returns one of `SF_BITRATE_MODE_XXX` on success, `-1` otherwise.
+
+## SFC_SET_BITRATE_MODE
+
+Set bitrate mode.
+
+The bitrate mode is one of:
+
+| Name                     | Value | Description       |
+|:-------------------------|:------|:------------------|
+| SF_BITRATE_MODE_CONSTANT | 800   | Constant bitrate. |
+| SF_BITRATE_MODE_AVERAGE  | 801   | Average bitrate.  |
+| SF_BITRATE_MODE_VARIABLE | 802   | Variable bitrate. |
+
+### Parameters
+
+sndfile
+: A valid SNDFILE* pointer
+
+cmd
+: SFC_SET_BITRATE_MODE
+
+data
+: pointer to an integer
+
+datasize
+: sizeof (int)
+
+### Return value
+
+Returns `SF_TRUE` on success, `SF_FALSE` otherwise.
index c5b39de..068e910 100644 (file)
@@ -9,7 +9,7 @@ interested in helping can raise an issue on Github.
 
 The main repository can be found on Github:
 
-<http://libsndfile.github.io/libsndfile/">
+<https://github.com/libsndfile/libsndfile/>
 
 and includes [instuctions](https://github.com/libsndfile/libsndfile/blob/master/README.md)
 on how to build libsndfile from the Git repo.
index 13bab52..1d96737 100644 (file)
@@ -40,11 +40,12 @@ From version 1.0.18, libsndfile also reads and writes
 From version 1.0.29, libsndfile can read and write
 [Ogg/Opus](https://opus-codec.org/).
 
+From version 1.1.0, libsndfile can read and write MP3.
+
 Some of the file formats I am also interested in adding are:
 
 - Kurzweil K2000 sampler files.
 - Ogg Speex.
-- MPEG Layer 3 (commonly known as MP3)
 
 Other file formats may also be added on request.
 
index 3779fdf..b666335 100644 (file)
@@ -142,6 +142,8 @@ Here is the release history for libsndfile:
   problems, delete old generated sndfile.h from $(top_builddir)/src.
 * Version 1.0.31 (January 24 2021) Bugfix release. Fix multiple memory leaks
   reported by OSS-Fuzz. More SSE2-optimized functions for x86 and amd64.
+* Version 1.1.0 (March 27 2022) Minor release, backward compatible with previous
+  releases. Added long-awaited MP3 support. Numerous improvements and bugfixes.
 
 ## Similar or Related Projects
 
@@ -194,7 +196,7 @@ long as you abide by [the license](http://www.gnu.org/copyleft/lesser.html).
 Check latest version on
 [GitHub Releases page](https://github.com/libsndfile/libsndfile/releases/).
 
-Binatries and source packages are signed by current releaser David Seifert aka
+Binaries and source packages are signed by current releaser David Seifert aka
 @SoapGentoo. You can verify signatures with his public GPG key:
 
 ```
index dade7d9..9b59f4a 100644 (file)
@@ -118,7 +118,7 @@ encode_file (const char *infilename, const char *outfilename, int filetype)
                exit (1) ;
                } ;
 
-       while ((readcount = sf_read_float (infile, buffer, BUFFER_LEN)) > 0)
+       while ((readcount = (int) sf_read_float (infile, buffer, BUFFER_LEN)) > 0)
                sf_write_float (outfile, buffer, readcount) ;
 
        sf_close (infile) ;
index 76f35b0..b905b2a 100644 (file)
@@ -74,12 +74,12 @@ main (void)
 
        if (sfinfo.channels == 1)
        {       for (k = 0 ; k < SAMPLE_COUNT ; k++)
-                       buffer [k] = AMPLITUDE * sin (LEFT_FREQ * 2 * k * M_PI) ;
+                       buffer [k] = (int) (AMPLITUDE * sin (LEFT_FREQ * 2 * k * M_PI)) ;
                }
        else if (sfinfo.channels == 2)
        {       for (k = 0 ; k < SAMPLE_COUNT ; k++)
-               {       buffer [2 * k] = AMPLITUDE * sin (LEFT_FREQ * 2 * k * M_PI) ;
-                       buffer [2 * k + 1] = AMPLITUDE * sin (RIGHT_FREQ * 2 * k * M_PI) ;
+               {       buffer [2 * k] = (int) (AMPLITUDE * sin (LEFT_FREQ * 2 * k * M_PI)) ;
+                       buffer [2 * k + 1] = (int) (AMPLITUDE * sin (RIGHT_FREQ * 2 * k * M_PI)) ;
                        } ;
                }
        else
index 1c141a4..ce1bda8 100644 (file)
@@ -98,19 +98,21 @@ main (void)
 
        if (sfinfo.channels > MAX_CHANNELS)
        {       printf ("Not able to process more than %d channels\n", MAX_CHANNELS) ;
+               sf_close (infile) ;
                return 1 ;
                } ;
        /* Open the output file. */
        if (! (outfile = sf_open (outfilename, SFM_WRITE, &sfinfo)))
        {       printf ("Not able to open output file %s.\n", outfilename) ;
                puts (sf_strerror (NULL)) ;
+               sf_close (infile) ;
                return 1 ;
                } ;
 
        /* While there are.frames in the input file, read them, process
        ** them and write them to the output file.
        */
-       while ((readcount = sf_read_double (infile, data, BUFFER_LEN)))
+       while ((readcount = (int) sf_read_double (infile, data, BUFFER_LEN)))
        {       process_data (data, readcount, sfinfo.channels) ;
                sf_write_double (outfile, data, readcount) ;
                } ;
index b0aded4..12b6b6b 100644 (file)
 
 #define BUFFER_LEN             (1 << 14)
 
-
-typedef        struct
-{      char    *infilename, *outfilename ;
-       SF_INFO infileinfo, outfileinfo ;
-} OptionData ;
-
 const char * program_name (const char * argv0) ;
 static void sfe_copy_data_int (SNDFILE *outfile, SNDFILE *infile, int channels) ;
 static void add_instrument_data (SNDFILE *outfile, const SF_INFO * in_info) ;
@@ -105,6 +99,7 @@ main (int argc, char * argv [])
        /* Open the output file. */
        if ((outfile = sf_open (outfilename, SFM_WRITE, &out_sfinfo)) == NULL)
        {       printf ("Not able to open output file %s : %s\n", outfilename, sf_strerror (NULL)) ;
+               sf_close (infile) ;
                return 1 ;
                } ;
 
@@ -143,7 +138,7 @@ sfe_copy_data_int (SNDFILE *outfile, SNDFILE *infile, int channels)
        readcount = frames ;
 
        while (readcount > 0)
-       {       readcount = sf_readf_int (infile, data, frames) ;
+       {       readcount = (int) sf_readf_int (infile, data, frames) ;
                sf_writef_int (outfile, data, readcount) ;
                } ;
 
index d5d0ec9..58ee069 100644 (file)
@@ -60,15 +60,21 @@ print_usage (char *progname)
 
 } /* print_usage */
 
-static void
+static int
 convert_to_text (SNDFILE * infile, FILE * outfile, int channels, int full_precision)
-{      float buf [BLOCK_SIZE] ;
+{      float *buf ;
        sf_count_t frames ;
        int k, m, readcount ;
 
+       buf = malloc (BLOCK_SIZE * sizeof (float)) ;
+       if (buf == NULL)
+       {       printf ("Error : Out of memory.\n\n") ;
+               return 1 ;
+               } ;
+
        frames = BLOCK_SIZE / channels ;
 
-       while ((readcount = sf_readf_float (infile, buf, frames)) > 0)
+       while ((readcount = (int) sf_readf_float (infile, buf, frames)) > 0)
        {       for (k = 0 ; k < readcount ; k++)
                {       for (m = 0 ; m < channels ; m++)
                                if (full_precision)
@@ -79,7 +85,9 @@ convert_to_text (SNDFILE * infile, FILE * outfile, int channels, int full_precis
                        } ;
                } ;
 
-       return ;
+       free (buf) ;
+
+       return 0 ;
 } /* convert_to_text */
 
 int
@@ -89,6 +97,7 @@ main (int argc, char * argv [])
        FILE            *outfile = NULL ;
        SF_INFO         sfinfo ;
        int             full_precision = 0 ;
+       int     ret = 1 ;
 
        progname = strrchr (argv [0], '/') ;
        progname = progname ? progname + 1 : argv [0] ;
@@ -97,7 +106,7 @@ main (int argc, char * argv [])
        {       case 4 :
                        if (!strcmp ("--full-precision", argv [3]))
                        {       print_usage (progname) ;
-                               return 1 ;
+                               goto cleanup ;
                                } ;
                        full_precision = 1 ;
                        argv++ ;
@@ -105,7 +114,7 @@ main (int argc, char * argv [])
                        break ;
                default:
                        print_usage (progname) ;
-                       return 1 ;
+                       goto cleanup ;
                } ;
 
        infilename = argv [1] ;
@@ -114,19 +123,19 @@ main (int argc, char * argv [])
        if (strcmp (infilename, outfilename) == 0)
        {       printf ("Error : Input and output filenames are the same.\n\n") ;
                print_usage (progname) ;
-               return 1 ;
+               goto cleanup ;
                } ;
 
        if (infilename [0] == '-')
        {       printf ("Error : Input filename (%s) looks like an option.\n\n", infilename) ;
                print_usage (progname) ;
-               return 1 ;
+               goto cleanup ;
                } ;
 
        if (outfilename [0] == '-')
        {       printf ("Error : Output filename (%s) looks like an option.\n\n", outfilename) ;
                print_usage (progname) ;
-               return 1 ;
+               goto cleanup ;
                } ;
 
        memset (&sfinfo, 0, sizeof (sfinfo)) ;
@@ -134,23 +143,26 @@ main (int argc, char * argv [])
        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 ;
+               goto cleanup ;
                } ;
 
        /* Open the output file. */
        if ((outfile = fopen (outfilename, "w")) == NULL)
        {       printf ("Not able to open output file %s : %s\n", outfilename, sf_strerror (NULL)) ;
-               return 1 ;
+               goto cleanup ;
                } ;
 
        fprintf (outfile, "# Converted from file %s.\n", infilename) ;
        fprintf (outfile, "# Channels %d, Sample rate %d\n", sfinfo.channels, sfinfo.samplerate) ;
 
-       convert_to_text (infile, outfile, sfinfo.channels, full_precision) ;
+       ret = convert_to_text (infile, outfile, sfinfo.channels, full_precision) ;
+
+cleanup :
 
        sf_close (infile) ;
-       fclose (outfile) ;
+       if (outfile != NULL)
+               fclose (outfile) ;
 
-       return 0 ;
+       return ret ;
 } /* main */
 
index 917ff4b..2bcbdb1 100644 (file)
@@ -71,6 +71,7 @@ enum
        SF_FORMAT_OGG                   = 0x200000,             /* Xiph OGG container */
        SF_FORMAT_MPC2K                 = 0x210000,             /* Akai MPC 2000 sampler */
        SF_FORMAT_RF64                  = 0x220000,             /* RF64 WAV file */
+       SF_FORMAT_MPEG                  = 0x230000,             /* MPEG-1/2 audio stream */
 
        /* Subtypes from here on. */
 
@@ -116,6 +117,10 @@ enum
        SF_FORMAT_ALAC_24               = 0x0072,               /* Apple Lossless Audio Codec (24 bit). */
        SF_FORMAT_ALAC_32               = 0x0073,               /* Apple Lossless Audio Codec (32 bit). */
 
+       SF_FORMAT_MPEG_LAYER_I  = 0x0080,               /* MPEG-1 Audio Layer I */
+       SF_FORMAT_MPEG_LAYER_II = 0x0081,               /* MPEG-1 Audio Layer II */
+       SF_FORMAT_MPEG_LAYER_III = 0x0082,              /* MPEG-2 Audio Layer III */
+
        /* Endian-ness options. */
 
        SF_ENDIAN_FILE                  = 0x00000000,   /* Default file endian-ness. */
@@ -173,6 +178,7 @@ enum
 
        SFC_SET_RAW_START_OFFSET                = 0x1090,
 
+       /* Commands reserved for dithering, which is not implemented. */
        SFC_SET_DITHER_ON_WRITE                 = 0x10A0,
        SFC_SET_DITHER_ON_READ                  = 0x10A1,
 
@@ -217,6 +223,9 @@ enum
        SFC_SET_OGG_PAGE_LATENCY_MS             = 0x1302,
        SFC_SET_OGG_PAGE_LATENCY                = 0x1303,
 
+       SFC_GET_BITRATE_MODE                    = 0x1304,
+       SFC_SET_BITRATE_MODE                    = 0x1305,
+
        /* Cart Chunk support */
        SFC_SET_CART_INFO                               = 0x1400,
        SFC_GET_CART_INFO                               = 0x1401,
@@ -333,10 +342,18 @@ enum
        SF_CHANNEL_MAP_MAX
 } ;
 
+/* Bitrate mode values (for use with SFC_GET/SET_BITRATE_MODE)
+*/
+enum
+{      SF_BITRATE_MODE_CONSTANT = 0,
+       SF_BITRATE_MODE_AVERAGE,
+       SF_BITRATE_MODE_VARIABLE
+} ;
+
 
 /* A SNDFILE* pointer can be passed around much like stdio.h's FILE* pointer. */
 
-typedef        struct SNDFILE_tag      SNDFILE ;
+typedef        struct sf_private_tag   SNDFILE ;
 
 /* The following typedef is system specific and is defined when libsndfile is
 ** compiled. sf_count_t will be a 64 bit value when the underlying OS allows
@@ -386,8 +403,7 @@ typedef struct
 
 /*
 ** Enums and typedefs for adding dither on read and write.
-** See the html documentation for sf_command(), SFC_SET_DITHER_ON_WRITE
-** and SFC_SET_DITHER_ON_READ.
+** Reserved for future implementation.
 */
 
 enum
@@ -755,16 +771,10 @@ 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) ;
+#ifdef _WIN32
+SNDFILE* sf_wchar_open (const wchar_t *wpath, int mode, SF_INFO *sfinfo) ;
 #endif
 
 
index ae9af3f..a8db0de 100644 (file)
@@ -47,6 +47,8 @@
 **
 ** API documentation is in the doc/ directory of the source code tarball
 ** and at http://libsndfile.github.io/libsndfile/api.html.
+**
+** This file is intended to compile with C++98 and newer.
 */
 
 #ifndef SNDFILE_HH
 #include <string>
 #include <new> // for std::nothrow
 
-#if __cplusplus < 201100
-#ifndef nullptr
-#define nullptr NULL
-#endif
+#if ((defined (_MSC_VER) && (_MSC_VER >= 1600)) || (__cplusplus >= 201100L))
+#define SF_NULL nullptr
+#else
+#define SF_NULL NULL
 #endif
 
 class SndfileHandle
@@ -78,7 +80,7 @@ class SndfileHandle
 
        public :
                        /* Default constructor */
-                       SndfileHandle (void) : p (nullptr) {} ;
+                       SndfileHandle (void) : p (SF_NULL) {} ;
                        SndfileHandle (const char *path, int mode = SFM_READ,
                                                        int format = 0, int channels = 0, int samplerate = 0) ;
                        SndfileHandle (std::string const & path, int mode = SFM_READ,
@@ -88,8 +90,8 @@ class SndfileHandle
                        SndfileHandle (SF_VIRTUAL_IO &sfvirtual, void *user_data, 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,
+#ifdef _WIN32
+                       SndfileHandle (const wchar_t *wpath, int mode = SFM_READ,
                                                        int format = 0, int channels = 0, int samplerate = 0) ;
 #endif
 
@@ -99,9 +101,9 @@ class SndfileHandle
                        SndfileHandle & operator = (const SndfileHandle &rhs) ;
 
                /* Mainly for debugging/testing. */
-               int refCount (void) const { return (p == nullptr) ? 0 : p->ref ; }
+               int refCount (void) const { return (p == SF_NULL) ? 0 : p->ref ; }
 
-               operator bool () const { return (p != nullptr) ; }
+               operator bool () const { return (p != SF_NULL) ; }
 
                bool operator == (const SndfileHandle &rhs) const { return (p == rhs.p) ; }
 
@@ -161,20 +163,20 @@ class SndfileHandle
 
 inline
 SndfileHandle::SNDFILE_ref::SNDFILE_ref (void)
-: sf (nullptr), sfinfo (), ref (1)
+: sf (SF_NULL), sfinfo (), ref (1)
 {}
 
 inline
 SndfileHandle::SNDFILE_ref::~SNDFILE_ref (void)
-{      if (sf != nullptr) sf_close (sf) ; }
+{      if (sf != SF_NULL) sf_close (sf) ; }
 
 inline
 SndfileHandle::SndfileHandle (const char *path, int mode, int fmt, int chans, int srate)
-: p (nullptr)
+: p (SF_NULL)
 {
        p = new (std::nothrow) SNDFILE_ref () ;
 
-       if (p != nullptr)
+       if (p != SF_NULL)
        {       p->ref = 1 ;
 
                p->sfinfo.frames = 0 ;
@@ -192,11 +194,11 @@ SndfileHandle::SndfileHandle (const char *path, int mode, int fmt, int chans, in
 
 inline
 SndfileHandle::SndfileHandle (std::string const & path, int mode, int fmt, int chans, int srate)
-: p (nullptr)
+: p (SF_NULL)
 {
        p = new (std::nothrow) SNDFILE_ref () ;
 
-       if (p != nullptr)
+       if (p != SF_NULL)
        {       p->ref = 1 ;
 
                p->sfinfo.frames = 0 ;
@@ -214,14 +216,14 @@ SndfileHandle::SndfileHandle (std::string const & path, int mode, int fmt, int c
 
 inline
 SndfileHandle::SndfileHandle (int fd, bool close_desc, int mode, int fmt, int chans, int srate)
-: p (nullptr)
+: p (SF_NULL)
 {
        if (fd < 0)
                return ;
 
        p = new (std::nothrow) SNDFILE_ref () ;
 
-       if (p != nullptr)
+       if (p != SF_NULL)
        {       p->ref = 1 ;
 
                p->sfinfo.frames = 0 ;
@@ -239,11 +241,11 @@ SndfileHandle::SndfileHandle (int fd, bool close_desc, int mode, int fmt, int ch
 
 inline
 SndfileHandle::SndfileHandle (SF_VIRTUAL_IO &sfvirtual, void *user_data, int mode, int fmt, int chans, int srate)
-: p (nullptr)
+: p (SF_NULL)
 {
        p = new (std::nothrow) SNDFILE_ref () ;
 
-       if (p != nullptr)
+       if (p != SF_NULL)
        {       p->ref = 1 ;
 
                p->sfinfo.frames = 0 ;
@@ -261,7 +263,7 @@ SndfileHandle::SndfileHandle (SF_VIRTUAL_IO &sfvirtual, void *user_data, int mod
 
 inline
 SndfileHandle::~SndfileHandle (void)
-{      if (p != nullptr && -- p->ref == 0)
+{      if (p != SF_NULL && -- p->ref == 0)
                delete p ;
 } /* SndfileHandle destructor */
 
@@ -269,7 +271,7 @@ SndfileHandle::~SndfileHandle (void)
 inline
 SndfileHandle::SndfileHandle (const SndfileHandle &orig)
 : p (orig.p)
-{      if (p != nullptr)
+{      if (p != SF_NULL)
                ++ p->ref ;
 } /* SndfileHandle copy constructor */
 
@@ -278,11 +280,11 @@ SndfileHandle::operator = (const SndfileHandle &rhs)
 {
        if (&rhs == this)
                return *this ;
-       if (p != nullptr && -- p->ref == 0)
+       if (p != SF_NULL && -- p->ref == 0)
                delete p ;
 
        p = rhs.p ;
-       if (p != nullptr)
+       if (p != SF_NULL)
                ++ p->ref ;
 
        return *this ;
@@ -407,30 +409,30 @@ SndfileHandle::writeRaw (const void *ptr, sf_count_t bytes)
 
 inline SNDFILE *
 SndfileHandle::rawHandle (void)
-{      return (p ? p->sf : nullptr) ; }
+{      return (p ? p->sf : SF_NULL) ; }
 
 inline SNDFILE *
 SndfileHandle::takeOwnership (void)
 {
-       if (p == nullptr || (p->ref != 1))
-               return nullptr ;
+       if (p == SF_NULL || (p->ref != 1))
+               return SF_NULL ;
 
        SNDFILE * sf = p->sf ;
-       p->sf = nullptr ;
+       p->sf = SF_NULL ;
        delete p ;
-       p = nullptr ;
+       p = SF_NULL ;
        return sf ;
 }
 
-#ifdef ENABLE_SNDFILE_WINDOWS_PROTOTYPES
+#ifdef _WIN32
 
 inline
-SndfileHandle::SndfileHandle (LPCWSTR wpath, int mode, int fmt, int chans, int srate)
-: p (nullptr)
+SndfileHandle::SndfileHandle (const wchar_t *wpath, int mode, int fmt, int chans, int srate)
+: p (SF_NULL)
 {
        p = new (std::nothrow) SNDFILE_ref () ;
 
-       if (p != nullptr)
+       if (p != SF_NULL)
        {       p->ref = 1 ;
 
                p->sfinfo.frames = 0 ;
index d443814..7e15312 100644 (file)
@@ -1,5 +1,5 @@
 # ===========================================================================
-#   http://www.gnu.org/software/autoconf-archive/ax_add_fortify_source.html
+#  https://www.gnu.org/software/autoconf-archive/ax_add_fortify_source.html
 # ===========================================================================
 #
 # SYNOPSIS
@@ -9,9 +9,9 @@
 # DESCRIPTION
 #
 #   Check whether -D_FORTIFY_SOURCE=2 can be added to CPPFLAGS without macro
-#   redefinition warnings. Some distributions (such as Gentoo Linux) enable
-#   _FORTIFY_SOURCE globally in their compilers, leading to unnecessary
-#   warnings in the form of
+#   redefinition warnings, other cpp warnings or linker. Some distributions
+#   (such as Gentoo Linux) enable _FORTIFY_SOURCE globally in their
+#   compilers, leading to unnecessary warnings in the form of
 #
 #     <command-line>:0:0: error: "_FORTIFY_SOURCE" redefined [-Werror]
 #     <built-in>: note: this is the location of the previous definition
 #   _FORTIFY_SOURCE is already defined, and if not, adds -D_FORTIFY_SOURCE=2
 #   to CPPFLAGS.
 #
+#   Newer mingw-w64 msys2 package comes with a bug in
+#   headers-git-7.0.0.5546.d200317d-1. It broke -D_FORTIFY_SOURCE support,
+#   and would need -lssp or -fstack-protector.  See
+#   https://github.com/msys2/MINGW-packages/issues/5803. Try to actually
+#   link it.
+#
 # LICENSE
 #
 #   Copyright (c) 2017 David Seifert <soap@gentoo.org>
+#   Copyright (c) 2019 Reini Urban <rurban@cpan.org>
 #
 #   Copying and distribution of this file, with or without modification, are
 #   permitted in any medium without royalty provided the copyright notice
 #   and this notice are preserved.  This file is offered as-is, without any
 #   warranty.
 
-#serial 1
+#serial 4
 
 AC_DEFUN([AX_ADD_FORTIFY_SOURCE],[
+    ac_save_cflags=$CFLAGS
+    ac_cwerror_flag=yes
+    AX_CHECK_COMPILE_FLAG([-Werror],[CFLAGS="$CFLAGS -Werror"])
     AC_MSG_CHECKING([whether to add -D_FORTIFY_SOURCE=2 to CPPFLAGS])
     AC_LINK_IFELSE([
-        AC_LANG_SOURCE(
+        AC_LANG_PROGRAM([],
             [[
-                int main() {
                 #ifndef _FORTIFY_SOURCE
                     return 0;
                 #else
                     this_is_an_error;
                 #endif
-                }
             ]]
-        )], [
-            AC_MSG_RESULT([yes])
-            CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2"
-        ], [
-            AC_MSG_RESULT([no])
-    ])
+        )],
+        AC_LINK_IFELSE([
+            AC_LANG_SOURCE([[
+                #define _FORTIFY_SOURCE 2
+                #include <string.h>
+                int main() {
+                    char *s = " ";
+                    strcpy(s, "x");
+                    return strlen(s)-1;
+                }
+              ]]
+            )],
+            [
+              AC_MSG_RESULT([yes])
+              CFLAGS=$ac_save_cflags
+              CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2"
+            ], [
+              AC_MSG_RESULT([no])
+              CFLAGS=$ac_save_cflags
+            ],
+        ),
+        [
+          AC_MSG_RESULT([no])
+          CFLAGS=$ac_save_cflags
+        ])
 ])
index ce4ecb8..8a04c35 100644 (file)
@@ -55,10 +55,10 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>]], [puts ("")])], pkg_link=
 CFLAGS=$pkg_link_saved_CFLAGS
 LIBS=$pkg_link_saved_LIBS
 
-if test $pkg_link = no ; then
-       $as_echo_n "link failed ... "
+AS_IF([test x$pkg_link = xno], [
+       AS_ECHO_N(["link failed ... "])
        pkg_failed=yes
-       fi
+])
 
 m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
 and $1[]_LIBS to avoid the need to call pkg-config.
index c17333e..04a58e5 100644 (file)
@@ -16,7 +16,7 @@ AC_DEFUN([OCTAVE_MKOCTFILE_VERSION],
 
 
 AC_ARG_WITH(mkoctfile,
-       AC_HELP_STRING([--with-mkoctfile], [choose the mkoctfile version]),
+       AS_HELP_STRING([--with-mkoctfile], [choose the mkoctfile version]),
        [ with_mkoctfile=$withval ])
 
 test -z "$with_mkoctfile" && with_mkoctfile=mkoctfile
index 88d5a5b..fda043d 100644 (file)
@@ -29,7 +29,7 @@ AC_DEFUN([AC_OCTAVE_VERSION],
 [
 
 AC_ARG_WITH(octave,
-       AC_HELP_STRING([--with-octave], [choose the octave version]),
+       AS_HELP_STRING([--with-octave], [choose the octave version]),
        [ with_octave=$withval ])
 
 test -z "$with_octave" && with_octave=octave
@@ -63,7 +63,7 @@ AC_DEFUN([AC_OCTAVE_CONFIG_VERSION],
 [
 
 AC_ARG_WITH(octave-config,
-       AC_HELP_STRING([--with-octave-config], [choose the octave-config version]),
+       AS_HELP_STRING([--with-octave-config], [choose the octave-config version]),
        [ with_octave_config=$withval ])
 
 test -z "$with_octave_config" && with_octave_config=octave-config
diff --git a/m4/stack_protect.m4 b/m4/stack_protect.m4
deleted file mode 100644 (file)
index bf27e6e..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-dnl Copyright (C) 2013  Xiph.org Foundation
-dnl
-dnl Redistribution and use in source and binary forms, with or without
-dnl modification, are permitted provided that the following conditions
-dnl are met:
-dnl
-dnl - Redistributions of source code must retain the above copyright
-dnl notice, this list of conditions and the following disclaimer.
-dnl
-dnl - Redistributions in binary form must reproduce the above copyright
-dnl notice, this list of conditions and the following disclaimer in the
-dnl documentation and/or other materials provided with the distribution.
-dnl
-dnl - Neither the name of the Xiph.org Foundation nor the names of its
-dnl contributors may be used to endorse or promote products derived from
-dnl this software without specific prior written permission.
-dnl
-dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-dnl ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-dnl LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-dnl A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
-dnl CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-dnl EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-dnl PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-dnl PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-dnl LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-dnl NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-dnl SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-dnl Want to know of GCC stack protector works, botfor the C and for the C++
-dnl compiler.
-dnl
-dnl Just checking if the compiler accepts the required CFLAGSs is not enough
-dnl because we have seen at least one instance where this check was
-dnl in-sufficient.
-dnl
-dnl Instead, try to compile and link a test program with the stack protector
-dnl flags. If that works, we use it.
-
-AC_DEFUN([XIPH_GCC_STACK_PROTECTOR],
-[AC_LANG_ASSERT(C)
-       AC_MSG_CHECKING([if $CC supports stack smash protection])
-       xiph_stack_check_old_cflags="$CFLAGS"
-       SSP_FLAGS="-fstack-protector --param ssp-buffer-size=4"
-       CFLAGS=$SSP_FLAGS
-       AC_TRY_LINK([
-                       #include <stdio.h>
-                       ],
-               [puts("Hello, World!"); return 0;],
-               AC_MSG_RESULT([yes])
-                       CFLAGS="$xiph_stack_check_old_cflags $SSP_FLAGS",
-               AC_MSG_RESULT([no])
-                       CFLAGS="$xiph_stack_check_old_cflags"
-               )
-])# XIPH_GCC_STACK_PROTECTOR
-
-AC_DEFUN([XIPH_GXX_STACK_PROTECTOR],
-[AC_LANG_PUSH([C++])
-       AC_MSG_CHECKING([if $CXX supports stack smash protection])
-       xiph_stack_check_old_cflags="$CFLAGS"
-       SSP_FLAGS="-fstack-protector --param ssp-buffer-size=4"
-       CFLAGS=$SSP_FLAGS
-       AC_TRY_LINK([
-                       #include <cstdio>
-                       ],
-               [puts("Hello, World!"); return 0;],
-               AC_MSG_RESULT([yes])
-                       CFLAGS="$xiph_stack_check_old_cflags $SSP_FLAGS",
-               AC_MSG_RESULT([no])
-                       CFLAGS="$xiph_stack_check_old_cflags"
-               )
-       AC_LANG_POP([C++])
-])# XIPH_GXX_STACK_PROTECTOR
index f36d131..4d570ea 100644 (file)
@@ -1,4 +1,4 @@
-.Dd November 2, 2014
+.Dd September 10, 2021
 .Dt SNDFILE-PLAY 1
 .Os
 .Sh NAME
@@ -19,6 +19,8 @@ ALSA or OSS
 sndio
 .It FreeBSD
 /dev/dsp (OSS)
+.It NetBSD
+/dev/audio
 .It Solaris
 /dev/audio
 .It MacOSX 10.6
index b93d4fc..a4d98d9 100755 (executable)
@@ -29,3 +29,4 @@ make V=1
 
 # Copy the fuzzer to the output directory.
 cp -v ossfuzz/sndfile_fuzzer $OUT/
+cp -v ossfuzz/sndfile_alt_fuzzer $OUT/
diff --git a/ossfuzz/sndfile_alt_fuzzer.cc b/ossfuzz/sndfile_alt_fuzzer.cc
new file mode 100644 (file)
index 0000000..e69fcdf
--- /dev/null
@@ -0,0 +1,79 @@
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sndfile.h>
+#include <inttypes.h>
+
+#include "sndfile_fuzz_header.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
+{   // One byte is needed for deciding which function to target.
+    if (size == 0)
+       return 0 ;
+
+    const uint8_t decider = *data ;
+    data += 1 ;
+    size -= 1 ;
+
+    SF_INFO sndfile_info ;
+    VIO_DATA vio_data ;
+    SF_VIRTUAL_IO vio ;
+    SNDFILE *sndfile = NULL ;
+    int err = sf_init_file(data, size, &sndfile, &vio_data, &vio, &sndfile_info) ;
+    if (err)
+      goto EXIT_LABEL ;
+
+    // Just the right number of channels. Create some buffer space for reading.
+    switch (decider % 3)
+    {   case 0  :
+                {
+                  short* read_buffer = NULL ;
+                  read_buffer = (short*)malloc(sizeof(short) * size);
+                  if (read_buffer == NULL)
+                    abort() ;
+
+                  while (sf_read_short(sndfile, read_buffer, size))
+                  {
+                    // Do nothing with the data.
+                  }
+                  free(read_buffer) ;
+                }
+                break ;
+        case 1  :
+                {
+                  int* read_buffer = NULL ;
+                  read_buffer = (int*)malloc(sizeof(int) * size) ;
+                  if (read_buffer == NULL)
+                    abort() ;
+
+                  while (sf_read_int(sndfile, read_buffer, size))
+                  {
+                    // Do nothing with the data.
+                  }
+                  free(read_buffer) ;
+                }
+                break ;
+        case 2  :
+                {
+                  double* read_buffer = NULL ;
+                  read_buffer = (double*)malloc(sizeof(double) * size) ;
+                  if (read_buffer == NULL)
+                    abort() ;
+
+                  while (sf_read_double(sndfile, read_buffer, size))
+                  {
+                    // Do nothing with the data.
+                  }
+                  free(read_buffer) ;
+                }
+                break ;
+        default :
+                break ;
+                } ;
+
+  EXIT_LABEL:
+    if (sndfile != NULL)
+      sf_close(sndfile);
+
+    return 0 ;
+}
diff --git a/ossfuzz/sndfile_fuzz_header.h b/ossfuzz/sndfile_fuzz_header.h
new file mode 100644 (file)
index 0000000..898aec4
--- /dev/null
@@ -0,0 +1,119 @@
+#ifndef SNDFILE_FUZZ_HEADER_H
+#define SNDFILE_FUZZ_HEADER_H
+
+typedef struct
+{
+  sf_count_t offset ;
+  sf_count_t length ;
+  const unsigned char *data ;
+} VIO_DATA ;
+
+static sf_count_t vfget_filelen (void *user_data)
+{  VIO_DATA *vf = (VIO_DATA *)user_data ;
+   return vf->length ;
+}
+
+static sf_count_t vfseek (sf_count_t offset, int whence, void *user_data)
+{
+  VIO_DATA *vf = (VIO_DATA *)user_data ;
+  sf_count_t new_offset ;
+
+  switch (whence)
+  {   case SEEK_SET :
+        new_offset = offset ;
+        break ;
+
+    case SEEK_CUR :
+        new_offset = vf->offset + offset ;
+        break ;
+
+    case SEEK_END :
+        new_offset = vf->length + offset ;
+        break ;
+
+    default :
+        break ;
+  }
+
+  /* Ensure you can't seek outside the data */
+  if (new_offset > vf->length)
+  {  /* Trying to seek past the end of the data */
+     printf("vf overseek: new_offset(%" PRId64 ") > vf->length(%" PRId64 ");"
+            "  whence(%d), vf->offset(%" PRId64 "), offset(%" PRId64 ")\n",
+            new_offset, vf->length, whence, vf->offset, offset) ;
+     new_offset = vf->length ;
+  }
+  else if (new_offset < 0)
+  {  /* Trying to seek before the start of the data */
+     printf("vf underseek: new_offset(%" PRId64 ") < 0;  whence(%d), vf->offset"
+            "(%" PRId64 "), vf->length(%" PRId64 "), offset(%" PRId64 ")\n",
+            new_offset, whence, vf->offset, vf->length, offset) ;
+     new_offset = 0 ;
+  }
+  vf->offset = new_offset ;
+
+  return vf->offset ;
+}
+
+static sf_count_t vfread (void *ptr, sf_count_t count, void *user_data)
+{  VIO_DATA *vf = (VIO_DATA *)user_data ;
+
+   if (vf->offset + count > vf->length)
+     count = vf->length - vf->offset ;
+
+   memcpy(ptr, vf->data + vf->offset, count) ;
+   vf->offset += count ;
+
+   return count ;
+}
+
+static sf_count_t vfwrite (const void *ptr, sf_count_t count, void *user_data)
+{
+  (void)ptr ;
+  (void)count ;
+  (void)user_data ;
+
+  // Cannot write to this virtual file.
+  return 0;
+}
+
+static sf_count_t vftell (void *user_data)
+{ VIO_DATA *vf = (VIO_DATA *)user_data ;
+
+  return vf->offset ;
+}
+
+int sf_init_file(const uint8_t *data, 
+                size_t size, 
+                SNDFILE **sndfile, 
+                VIO_DATA *vio_data, 
+                SF_VIRTUAL_IO *vio, SF_INFO *sndfile_info)
+{  float* read_buffer = NULL ;
+
+   // Initialize the virtual IO structure.
+   vio->get_filelen = vfget_filelen ;
+   vio->seek = vfseek ;
+   vio->read = vfread ;
+   vio->write = vfwrite ;
+   vio->tell = vftell ;
+
+   // Initialize the VIO user data.
+   vio_data->data = data ;
+   vio_data->length = size ;
+   vio_data->offset = 0 ;
+
+   memset(sndfile_info, 0, sizeof(SF_INFO)) ;
+
+   // Try and open the virtual file.
+   *sndfile = sf_open_virtual(vio, SFM_READ, sndfile_info, vio_data) ;
+
+   if (sndfile_info->channels == 0)
+                return -1 ;
+
+   if (sndfile_info->channels > 1024 * 1024)
+                return -1 ;
+
+   return 0;
+}
+
+#endif
index 3c85073..2a3d693 100644 (file)
 #include <sndfile.h>
 #include <inttypes.h>
 
-typedef struct
-{
-  sf_count_t offset;
-  sf_count_t length;
-  const unsigned char *data;
-} VIO_DATA;
-
-static sf_count_t vfget_filelen (void *user_data)
-{
-  VIO_DATA *vf = (VIO_DATA *)user_data;
-  return vf->length;
-}
-
-static sf_count_t vfseek (sf_count_t offset, int whence, void *user_data)
-{
-  VIO_DATA *vf = (VIO_DATA *)user_data;
-  sf_count_t new_offset;
-
-  switch (whence)
-  {
-    case SEEK_SET:
-      new_offset = offset;
-      break ;
-
-    case SEEK_CUR:
-      new_offset = vf->offset + offset;
-      break ;
-
-    case SEEK_END:
-      new_offset = vf->length + offset;
-      break;
-
-    default:
-      break;
-  }
-
-  /* Ensure you can't seek outside the data */
-  if (new_offset > vf->length)
-  {
-    /* Trying to seek past the end of the data */
-    printf("vf overseek: new_offset(%" PRId64 ") > vf->length(%" PRId64 ");"
-           "  whence(%d), vf->offset(%" PRId64 "), offset(%" PRId64 ")\n",
-           new_offset, vf->length, whence, vf->offset, offset);
-    new_offset = vf->length;
-  }
-  else if (new_offset < 0)
-  {
-    /* Trying to seek before the start of the data */
-    printf("vf underseek: new_offset(%" PRId64 ") < 0;  whence(%d), vf->offset"
-           "(%" PRId64 "), vf->length(%" PRId64 "), offset(%" PRId64 ")\n",
-           new_offset, whence, vf->offset, vf->length, offset);
-    new_offset = 0;
-  }
-  vf->offset = new_offset;
-
-  return vf->offset;
-}
-
-static sf_count_t vfread (void *ptr, sf_count_t count, void *user_data)
-{
-  VIO_DATA *vf = (VIO_DATA *)user_data;
-
-  if (vf->offset + count > vf->length)
-  {
-    count = vf->length - vf->offset;
-  }
-
-  memcpy(ptr, vf->data + vf->offset, count);
-  vf->offset += count;
-
-  return count;
-}
-
-static sf_count_t vfwrite (const void *ptr, sf_count_t count, void *user_data)
-{
-  (void)ptr;
-  (void)count;
-  (void)user_data;
-
-  // Cannot write to this virtual file.
-  return 0;
-}
-
-static sf_count_t vftell (void *user_data)
-{ VIO_DATA *vf = (VIO_DATA *)user_data;
-
-  return vf->offset;
-}
+#include "sndfile_fuzz_header.h"
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
-{
-  VIO_DATA vio_data;
-  SF_VIRTUAL_IO vio;
-  SF_INFO sndfile_info;
-  SNDFILE *sndfile = NULL;
-  float* read_buffer = NULL;
-
-  // Initialize the virtual IO structure.
-  vio.get_filelen = vfget_filelen;
-  vio.seek = vfseek;
-  vio.read = vfread;
-  vio.write = vfwrite;
-  vio.tell = vftell;
-
-  // Initialize the VIO user data.
-  vio_data.data = data;
-  vio_data.length = size;
-  vio_data.offset = 0;
-
-  memset(&sndfile_info, 0, sizeof(SF_INFO));
-
-  // Try and open the virtual file.
-  sndfile = sf_open_virtual(&vio, SFM_READ, &sndfile_info, &vio_data);
-
-  if (sndfile_info.channels == 0)
-  {
-    // No sound channels in file.
-    goto EXIT_LABEL;
-  }
-  else if (sndfile_info.channels > 1024 * 1024)
-  {
-    // Too many channels to handle.
-    goto EXIT_LABEL;
-  }
-
-  // Just the right number of channels. Create some buffer space for reading.
-  read_buffer = (float*)malloc(sizeof(float) * sndfile_info.channels);
-  if (read_buffer == NULL)
-  {
-    abort();
-  }
-
-  while (sf_readf_float(sndfile, read_buffer, 1))
-  {
-    // Do nothing with the data.
-  }
+{  VIO_DATA vio_data ;
+   SF_VIRTUAL_IO vio ;
+   SF_INFO sndfile_info ;
+   SNDFILE *sndfile = NULL ;
+   float* read_buffer = NULL ;
+
+   int err = sf_init_file(data, size, &sndfile, &vio_data, &vio, &sndfile_info) ;
+   if (err)
+     goto EXIT_LABEL ;
+
+   // Just the right number of channels. Create some buffer space for reading.
+   read_buffer = (float*)malloc(sizeof(float) * sndfile_info.channels);
+   if (read_buffer == NULL)
+     abort() ;
+
+   while (sf_readf_float(sndfile, read_buffer, 1))
+   {
+     // Do nothing with the data.
+   }
 
 EXIT_LABEL:
 
-  if (sndfile != NULL)
-  {
-    sf_close(sndfile);
-  }
+   if (sndfile != NULL)
+     sf_close(sndfile) ;
 
-  free(read_buffer);
+   free(read_buffer) ;
 
-  return 0;
+   return 0 ;
 }
index fb479f0..7ff0d41 100644 (file)
@@ -73,7 +73,7 @@ sfe_copy_data_fp (SNDFILE *outfile, SNDFILE *infile, int channels, int normalize
                        {       data [k] /= max ;
 
                                if (!isfinite (data [k])) /* infinite or NaN */
-                                       return 1;
+                                       return 1 ;
                                }
                        sf_writef_double (outfile, data, readcount) ;
                        } ;
@@ -91,7 +91,7 @@ sfe_copy_data_int (SNDFILE *outfile, SNDFILE *infile, int channels)
        readcount = frames ;
 
        while (readcount > 0)
-       {       readcount = sf_readf_int (infile, data, frames) ;
+       {       readcount = (int) sf_readf_int (infile, data, frames) ;
                sf_writef_int (outfile, data, readcount) ;
                } ;
 
@@ -119,6 +119,7 @@ merge_broadcast_info (SNDFILE * infile, SNDFILE * outfile, int format, const MET
        {       case SF_FORMAT_PCM_16 :
                case SF_FORMAT_PCM_24 :
                case SF_FORMAT_PCM_32 :
+               case SF_FORMAT_MPEG_LAYER_III :
                        break ;
 
                default :
@@ -177,7 +178,7 @@ merge_broadcast_info (SNDFILE * infile, SNDFILE * outfile, int format, const MET
        /* Special case for coding_history because we may want to append. */
        if (info->coding_history != NULL)
        {       if (info->coding_hist_append)
-               {       int slen = strlen (binfo.coding_history) ;
+               {       int slen = (int) strlen (binfo.coding_history) ;
 
                        while (slen > 1 && isspace (binfo.coding_history [slen - 1]))
                                slen -- ;
@@ -189,7 +190,7 @@ merge_broadcast_info (SNDFILE * infile, SNDFILE * outfile, int format, const MET
 
                        memset (binfo.coding_history, 0, sizeof (binfo.coding_history)) ;
                        memcpy (binfo.coding_history, info->coding_history, slen) ;
-                       binfo.coding_history_size = slen ;
+                       binfo.coding_history_size = (uint32_t) slen ;
                        } ;
                } ;
 
@@ -339,11 +340,12 @@ static OUTPUT_FORMAT_MAP format_map [] =
        {       "caf",          0,      SF_FORMAT_CAF   },
        {       "wve",          0,      SF_FORMAT_WVE   },
        {       "prc",          0,      SF_FORMAT_WVE   },
-       {       "ogg",          0,      SF_FORMAT_OGG   },
        {       "oga",          0,      SF_FORMAT_OGG   },
+       {       "ogg",          0,      SF_FORMAT_OGG | SF_FORMAT_VORBIS },
        {       "opus",         0,      SF_FORMAT_OGG | SF_FORMAT_OPUS },
        {       "mpc",          0,      SF_FORMAT_MPC2K },
        {       "rf64",         0,      SF_FORMAT_RF64  },
+       {       "mp3",          0,      SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III },
 } ; /* format_map */
 
 int
@@ -453,6 +455,7 @@ sfe_container_name (int format)
                case SF_FORMAT_OGG : return "OGG" ;
                case SF_FORMAT_MPC2K : return "MPC2K" ;
                case SF_FORMAT_RF64 : return "RF64" ;
+               case SF_FORMAT_MPEG : return "MPEG" ;
                default : break ;
                } ;
 
@@ -491,6 +494,9 @@ sfe_codec_name (int format)
                case SF_FORMAT_ALAC_24 : return "24 bit ALAC" ;
                case SF_FORMAT_ALAC_32 : return "32 bit ALAC" ;
                case SF_FORMAT_OPUS : return "Opus" ;
+               case SF_FORMAT_MPEG_LAYER_I : return "MPEG layer 1" ;
+               case SF_FORMAT_MPEG_LAYER_II : return "MPEG layer 2" ;
+               case SF_FORMAT_MPEG_LAYER_III : return "MPEG layer 3" ;
                default : break ;
                } ;
        return "unknown" ;
index 3a02a94..49380fd 100644 (file)
@@ -143,7 +143,7 @@ concat_data_fp (SNDFILE *wfile, SNDFILE *rofile, int channels)
        sf_seek (wfile, 0, SEEK_END) ;
 
        while (readcount > 0)
-       {       readcount = sf_readf_double (rofile, data, frames) ;
+       {       readcount = (int) sf_readf_double (rofile, data, frames) ;
                sf_writef_double (wfile, data, readcount) ;
                } ;
 
@@ -161,7 +161,7 @@ concat_data_int (SNDFILE *wfile, SNDFILE *rofile, int channels)
        sf_seek (wfile, 0, SEEK_END) ;
 
        while (readcount > 0)
-       {       readcount = sf_readf_int (rofile, data, frames) ;
+       {       readcount = (int) sf_readf_int (rofile, data, frames) ;
                sf_writef_int (wfile, data, readcount) ;
                } ;
 
index 5aa4fdf..b946862 100644 (file)
@@ -281,7 +281,7 @@ main (int argc, char * argv [])
                        continue ;
                        } ;
 
-               printf ("Error : Not able to decode argunment '%s'.\n", argv [k]) ;
+               printf ("Error : Not able to decode argument '%s'.\n", argv [k]) ;
                exit (1) ;
                } ;
 
@@ -354,7 +354,10 @@ main (int argc, char * argv [])
                        || (outfileminor == SF_FORMAT_DOUBLE) || (outfileminor == SF_FORMAT_FLOAT)
                        || (infileminor == SF_FORMAT_DOUBLE) || (infileminor == SF_FORMAT_FLOAT)
                        || (infileminor == SF_FORMAT_OPUS) || (outfileminor == SF_FORMAT_OPUS)
-                       || (infileminor == SF_FORMAT_VORBIS) || (outfileminor == SF_FORMAT_VORBIS))
+                       || (infileminor == SF_FORMAT_VORBIS) || (outfileminor == SF_FORMAT_VORBIS)
+                       || (infileminor == SF_FORMAT_MPEG_LAYER_I)
+                       || (infileminor == SF_FORMAT_MPEG_LAYER_II)
+                       || (infileminor == SF_FORMAT_MPEG_LAYER_III) || (outfileminor == SF_FORMAT_MPEG_LAYER_III))
        {       if (sfe_copy_data_fp (outfile, infile, sfinfo.channels, normalize) != 0)
                {       printf ("Error : Not able to decode input file %s.\n", infilename) ;
                        return 1 ;
@@ -388,7 +391,7 @@ copy_metadata (SNDFILE *outfile, SNDFILE *infile, int channels)
        memset (&binfo, 0, sizeof (binfo)) ;
 
        if (channels < ARRAY_LEN (chanmap))
-       {       size_t size = channels * sizeof (chanmap [0]) ;
+       {       int 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) ;
index 616761e..42d4750 100644 (file)
@@ -65,43 +65,48 @@ static void deinterleave_double (STATE * state) ;
 
 int
 main (int argc, char **argv)
-{      STATE state ;
+{      STATE *state = NULL ;
        SF_INFO sfinfo ;
        char pathname [512], ext [32], *cptr ;
-       int ch, double_split ;
+       int ch, double_split, ret = 1 ;
 
        if (argc != 2)
        {       if (argc != 1)
                        puts ("\nError : need a single input file.\n") ;
                usage_exit () ;
+               goto cleanup ;
                } ;
 
-       memset (&state, 0, sizeof (state)) ;
+       state = calloc (1, sizeof (*state)) ;
+       if (!state)
+       {       printf ("\nError : Out of memory.\n") ;
+               goto cleanup ;
+               } ;
        memset (&sfinfo, 0, sizeof (sfinfo)) ;
 
-       if ((state.infile = sf_open (argv [1], SFM_READ, &sfinfo)) == NULL)
+       if ((state->infile = sf_open (argv [1], SFM_READ, &sfinfo)) == NULL)
        {       printf ("\nError : Not able to open input file '%s'\n%s\n", argv [1], sf_strerror (NULL)) ;
-               exit (1) ;
+               goto cleanup ;
                } ;
 
        if (sfinfo.channels < 2)
        {       printf ("\nError : Input file '%s' only has one channel.\n", argv [1]) ;
-               exit (1) ;
+               goto cleanup ;
                } ;
 
        if (sfinfo.channels > MAX_CHANNELS)
        {       printf ("\nError : Input file '%s' has too many (%d) channels. Limit is %d.\n",
                        argv [1], sfinfo.channels, MAX_CHANNELS) ;
-               exit (1) ;
+               goto cleanup ;
                } ;
 
 
-       state.channels = sfinfo.channels ;
+       state->channels = sfinfo.channels ;
        sfinfo.channels = 1 ;
 
        if (snprintf (pathname, sizeof (pathname), "%s", argv [1]) > (int) sizeof (pathname))
        {       printf ("\nError : Length of provided filename '%s' exceeds MAX_PATH (%d).\n", argv [1], (int) sizeof (pathname)) ;
-               exit (1) ;
+               goto cleanup ;
                } ;
 
        if ((cptr = strrchr (pathname, '.')) == NULL)
@@ -114,7 +119,7 @@ main (int argc, char **argv)
        printf ("Input file : %s\n", pathname) ;
        puts ("Output files :") ;
 
-       for (ch = 0 ; ch < state.channels ; ch++)
+       for (ch = 0 ; ch < state->channels ; ch++)
        {       char filename [520] ;
                size_t count ;
 
@@ -124,9 +129,9 @@ main (int argc, char **argv)
                {       printf ("File name truncated to %s\n", filename) ;
                        } ;
 
-               if ((state.outfile [ch] = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
+               if ((state->outfile [ch] = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
                {       printf ("Not able to open output file '%s'\n%s\n", filename, sf_strerror (NULL)) ;
-                       exit (1) ;
+                       goto cleanup ;
                        } ;
 
                printf ("    %s\n", filename) ;
@@ -145,16 +150,24 @@ main (int argc, char **argv)
                } ;
 
        if (double_split)
-               deinterleave_double (&state) ;
+               deinterleave_double (state) ;
        else
-               deinterleave_int (&state) ;
+               deinterleave_int (state) ;
+
+       ret = 0 ;
+
+cleanup :
+
+       if (state != NULL)
+       {       sf_close (state->infile) ;
+               for (ch = 0 ; ch < MAX_CHANNELS ; ch++)
+                       if (state->outfile [ch] != NULL)
+                               sf_close (state->outfile [ch]) ;
+               } ;
 
-       sf_close (state.infile) ;
-       for (ch = 0 ; ch < MAX_CHANNELS ; ch++)
-               if (state.outfile [ch] != NULL)
-                       sf_close (state.outfile [ch]) ;
+       free (state) ;
 
-       return 0 ;
+       return ret ;
 } /* main */
 
 /*------------------------------------------------------------------------------
@@ -170,7 +183,6 @@ usage_exit (void)
                "a_00.wav, a_01.wav and so on.\n"
                ) ;
        printf ("Using %s.\n\n", sf_version_string ()) ;
-       exit (1) ;
 } /* usage_exit */
 
 static void
@@ -179,7 +191,7 @@ deinterleave_int (STATE * state)
        int ch, k ;
 
        do
-       {       read_len = sf_readf_int (state->infile, state->din.i, BUFFER_LEN) ;
+       {       read_len = (int) sf_readf_int (state->infile, state->din.i, BUFFER_LEN) ;
 
                for (ch = 0 ; ch < state->channels ; ch ++)
                {       for (k = 0 ; k < read_len ; k++)
@@ -197,7 +209,7 @@ deinterleave_double (STATE * state)
        int ch, k ;
 
        do
-       {       read_len = sf_readf_double (state->infile, state->din.d, BUFFER_LEN) ;
+       {       read_len = (int) sf_readf_double (state->infile, state->din.d, BUFFER_LEN) ;
 
                for (ch = 0 ; ch < state->channels ; ch ++)
                {       for (k = 0 ; k < read_len ; k++)
index e0e4882..ae44654 100644 (file)
@@ -110,8 +110,6 @@ main (int argc, char *argv [])
 **     Print version and usage.
 */
 
-static double  data [BUFFER_LEN] ;
-
 static void
 usage_exit (const char *progname)
 {      printf ("Usage :\n  %s <file> ...\n", progname) ;
@@ -167,6 +165,8 @@ calc_decibels (SF_INFO * sfinfo, double max)
 
                case SF_FORMAT_FLOAT :
                case SF_FORMAT_DOUBLE :
+               case SF_FORMAT_VORBIS :
+               case SF_FORMAT_OPUS :
                        decibels = max / 1.0 ;
                        break ;
 
@@ -313,7 +313,9 @@ instrument_dump (const char *filename)
        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) ;
+               printf ("  %-2d    Mode : %s    Start : %6" PRIu32 "   End : %6" PRIu32
+                       "   Count : %6" PRIu32 "\n", k, str_of_type (inst.loops [k].mode),
+                       inst.loops [k].start, inst.loops [k].end, inst.loops [k].count) ;
 
        putchar ('\n') ;
        return 0 ;
index 4c04443..2b44efb 100644 (file)
@@ -60,46 +60,54 @@ typedef struct
 } STATE ;
 
 
-static void usage_exit (void) ;
+static void print_usage (void) ;
 static void interleave_int (STATE * state) ;
 static void interleave_double (STATE * state) ;
 
 
 int
 main (int argc, char **argv)
-{      STATE state ;
+{      STATE *state = NULL ;
        SF_INFO sfinfo ;
        int k, double_merge = 0 ;
+       int ret = 1 ;
 
        if (argc < 5)
        {       if (argc > 1)
                        puts ("\nError : need at least 2 input files.") ;
-               usage_exit () ;
+               print_usage () ;
+               goto cleanup ;
                } ;
 
        if (strcmp (argv [argc - 2], "-o") != 0)
        {       puts ("\nError : second last command line parameter should be '-o'.\n") ;
-               usage_exit () ;
+               print_usage () ;
+               goto cleanup ;
                } ;
 
        if (argc - 3 > MAX_INPUTS)
        {       printf ("\nError : Cannot handle more than %d input channels.\n\n", MAX_INPUTS) ;
-               exit (1) ;
+               goto cleanup ;
+               } ;
+
+       state = calloc (1, sizeof (STATE)) ;
+       if (state == NULL)
+       {       puts ("\nError : out of memory.\n") ;
+               goto cleanup ;
                } ;
 
-       memset (&state, 0, sizeof (state)) ;
        memset (&sfinfo, 0, sizeof (sfinfo)) ;
 
        for (k = 1 ; k < argc - 2 ; k++)
        {
-               if ((state.infile [k - 1] = sf_open (argv [k], SFM_READ, &sfinfo)) == NULL)
+               if ((state->infile [k - 1] = sf_open (argv [k], SFM_READ, &sfinfo)) == NULL)
                {       printf ("\nError : Not able to open input file '%s'\n%s\n", argv [k], sf_strerror (NULL)) ;
-                       exit (1) ;
+                       goto cleanup ;
                        } ;
 
                if (sfinfo.channels != 1)
                {       printf ("\bError : Input file '%s' should be mono (has %d channels).\n", argv [k], sfinfo.channels) ;
-                       exit (1) ;
+                       goto cleanup ;
                        } ;
 
                switch (sfinfo.format & SF_FORMAT_SUBMASK)
@@ -113,28 +121,36 @@ main (int argc, char **argv)
                                break ;
                        } ;
 
-               state.channels ++ ;
+               state->channels ++ ;
                } ;
 
-       sfinfo.channels = state.channels ;
+       sfinfo.channels = state->channels ;
        sfinfo.format = sfe_file_type_of_ext (argv [argc - 1], sfinfo.format) ;
 
-       if ((state.outfile = sf_open (argv [argc - 1], SFM_WRITE, &sfinfo)) == NULL)
+       if ((state->outfile = sf_open (argv [argc - 1], SFM_WRITE, &sfinfo)) == NULL)
        {       printf ("Not able to open output file '%s'\n%s\n", argv [argc - 1], sf_strerror (NULL)) ;
-               exit (1) ;
+               goto cleanup ;
                } ;
 
        if (double_merge)
-               interleave_double (&state) ;
+               interleave_double (state) ;
        else
-               interleave_int (&state) ;
+               interleave_int (state) ;
+
+       ret = 0 ;
+
+cleanup :
+
+       if (state != NULL)
+       {       for (k = 0 ; k < MAX_INPUTS ; k++)
+                       if (state->infile [k] != NULL)
+                               sf_close (state->infile [k]) ;
+               sf_close (state->outfile) ;
+               }
 
-       for (k = 0 ; k < MAX_INPUTS ; k++)
-               if (state.infile [k] != NULL)
-                       sf_close (state.infile [k]) ;
-       sf_close (state.outfile) ;
+       free (state) ;
 
-       return 0 ;
+       return ret ;
 } /* main */
 
 /*------------------------------------------------------------------------------
@@ -142,12 +158,11 @@ main (int argc, char **argv)
 
 
 static void
-usage_exit (void)
+print_usage (void)
 {      puts ("\nUsage : sndfile-interleave <input 1> <input 2> ... -o <output file>\n") ;
        puts ("Merge two or more mono files into a single multi-channel file.\n") ;
        printf ("Using %s.\n\n", sf_version_string ()) ;
-       exit (1) ;
-} /* usage_exit */
+} /* print_usage */
 
 
 static void
@@ -159,7 +174,7 @@ interleave_int (STATE * state)
        {       max_read_len = 0 ;
 
                for (ch = 0 ; ch < state->channels ; ch ++)
-               {       read_len = sf_read_int (state->infile [ch], state->din.i, BUFFER_LEN) ;
+               {       read_len = (int) sf_read_int (state->infile [ch], state->din.i, BUFFER_LEN) ;
                        if (read_len < BUFFER_LEN)
                                memset (state->din.i + read_len, 0, sizeof (state->din.i [0]) * (BUFFER_LEN - read_len)) ;
 
@@ -185,7 +200,7 @@ interleave_double (STATE * state)
        {       max_read_len = 0 ;
 
                for (ch = 0 ; ch < state->channels ; ch ++)
-               {       read_len = sf_read_double (state->infile [ch], state->din.d, BUFFER_LEN) ;
+               {       read_len = (int) sf_read_double (state->infile [ch], state->din.d, BUFFER_LEN) ;
                        if (read_len < BUFFER_LEN)
                                memset (state->din.d + read_len, 0, sizeof (state->din.d [0]) * (BUFFER_LEN - read_len)) ;
 
index cd5cc27..16aaf4d 100644 (file)
@@ -64,7 +64,7 @@
 #elif HAVE_SNDIO_H
        #include <sndio.h>
 
-#elif (defined (sun) && defined (unix))
+#elif (defined (sun) && defined (unix)) || defined(__NetBSD__)
        #include <fcntl.h>
        #include <sys/ioctl.h>
        #include <sys/audioio.h>
@@ -328,10 +328,12 @@ alsa_write_float (snd_pcm_t *alsa_dev, float *data, int frames, int channels)
                                        return 0 ;
                                        break ;
 
+#if defined ESTRPIPE && ESTRPIPE != EPIPE
                        case -ESTRPIPE :
                                        fprintf (stderr, "alsa_write_float: Suspend event.n") ;
                                        return 0 ;
                                        break ;
+#endif
 
                        case -EIO :
                                        puts ("alsa_write_float: EIO") ;
@@ -727,7 +729,7 @@ sndio_play (int argc, char *argv [])
 **     Solaris.
 */
 
-#if (defined (sun) && defined (unix)) /* ie Solaris */
+#if (defined (sun) && defined (unix)) || defined(__NetBSD__)
 
 static void
 solaris_play (int argc, char *argv [])
@@ -764,8 +766,6 @@ solaris_play (int argc, char *argv [])
                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") ;
@@ -807,7 +807,7 @@ solaris_play (int argc, char *argv [])
        return ;
 } /* solaris_play */
 
-#endif /* Solaris */
+#endif /* Solaris or NetBSD */
 
 /*==============================================================================
 **     Main function.
@@ -845,7 +845,7 @@ main (int argc, char *argv [])
        opensoundsys_play (argc, argv) ;
 #elif HAVE_SNDIO_H
        sndio_play (argc, argv) ;
-#elif (defined (sun) && defined (unix))
+#elif (defined (sun) && defined (unix)) || defined(__NetBSD__)
        solaris_play (argc, argv) ;
 #elif (OS_IS_WIN32 == 1)
        win32_play (argc, argv) ;
index 9c21d52..1a76dc3 100644 (file)
 
 #define        NOT(x)                  (! (x))
 
+#ifndef _WIN32
+typedef off_t sf_off_t ;
+#else
+typedef long long sf_off_t ;
+#endif
+
 
 static void usage_exit (const char *progname) ;
 static void salvage_file (const char * broken_wav, const char * fixed_w64) ;
@@ -74,8 +80,8 @@ main (int argc, char *argv [])
 /*==============================================================================
 */
 
-static void lseek_or_die (int fd, off_t offset, int whence) ;
-static sf_count_t get_file_length (int fd, const char * name) ;
+static void lseek_or_die (int fd, sf_off_t offset, int whence) ;
+static sf_off_t get_file_length (int fd, const char * name) ;
 static sf_count_t find_data_offset (int fd, int format) ;
 static void copy_data (int fd, SNDFILE * sndfile, int readsize) ;
 
@@ -180,9 +186,13 @@ salvage_file (const char * broken_wav, const char * fixed_w64)
 */
 
 static void
-lseek_or_die (int fd, off_t offset, int whence)
+lseek_or_die (int fd, sf_off_t offset, int whence)
 {
+#ifndef _WIN32
        if (lseek (fd, offset, whence) < 0)
+#else
+       if (_lseeki64 (fd, offset, whence) < 0)
+#endif
        {       printf ("lseek failed : %s\n", strerror (errno)) ;
                exit (1) ;
                } ;
@@ -191,9 +201,14 @@ lseek_or_die (int fd, off_t offset, int whence)
 } /* lseek_or_die */
 
 
-static sf_count_t
+static sf_off_t
 get_file_length (int fd, const char * name)
-{      struct stat sbuf ;
+{
+#ifndef _WIN32
+       struct stat sbuf ;
+#else
+       struct _stat64 sbuf ;
+#endif
 
        if (sizeof (sbuf.st_size) != 8)
        {       puts ("Error : sizeof (sbuf.st_size) != 8. Was program compiled with\n"
@@ -201,7 +216,11 @@ get_file_length (int fd, const char * name)
                exit (1) ;
                } ;
 
+#ifndef _WIN32
        if (fstat (fd, &sbuf) != 0)
+#else
+       if (_fstat64 (fd, &sbuf) != 0)
+#endif
        {       printf ("Error : fstat ('%s') failed : %s\n", name, strerror (errno)) ;
                exit (1) ;
                } ;
@@ -233,7 +252,7 @@ find_data_offset (int fd, int format)
                        exit (1) ;
                } ;
 
-       slen = strlen (target) ;
+       slen = (int) strlen (target) ;
 
        lseek_or_die (fd, 0, SEEK_SET) ;
 
index 1048ebb..1f4c8d7 100644 (file)
@@ -267,14 +267,14 @@ db_check_all (REG_DB * db_handle)
 int
 db_list_all (REG_DB * db_handle)
 {
-       printf ("%s : %p\n", __func__, db_handle) ;
+       printf ("%s : %p\n", __func__, (void *) db_handle) ;
        return 0 ;
 } /* db_list_all */
 
 int
 db_del_entry (REG_DB * db_handle, const char * entry)
 {
-       printf ("%s : %p %s\n", __func__, db_handle, entry) ;
+       printf ("%s : %p %s\n", __func__, (void *) db_handle, entry) ;
        return 0 ;
 } /* db_del_entry */
 
@@ -428,7 +428,7 @@ static void
 get_filename_pathname (REGTEST_DB * db, const char *filepath)
 {
        const char * basename = db_basename (filepath) ;
-       int slen ;
+       size_t slen ;
 
        /* Test for a relative path
         */
index 961cf93..6b88453 100644 (file)
@@ -6,7 +6,8 @@ includedir=@includedir@
 Name: sndfile
 Description: A library for reading and writing audio files
 Requires:
-Requires.private: @EXTERNAL_XIPH_REQUIRE@
+Requires.private: @EXTERNAL_XIPH_REQUIRE@ @EXTERNAL_MPEG_REQUIRE@
 Version: @VERSION@
 Libs: -L${libdir} -lsndfile
+Libs.private: @EXTERNAL_MPEG_LIBS@
 Cflags: -I${includedir}
index e7e4c62..37671d2 100644 (file)
@@ -42,6 +42,8 @@
 
 #if __GNUC__
 #define ALWAYS_INLINE          __attribute__ ((always_inline))
+#elif defined _MSC_VER
+#define ALWAYS_INLINE          __forceinline
 #else
 #define ALWAYS_INLINE
 #endif
index 2b1df19..4737b96 100644 (file)
@@ -44,6 +44,8 @@
 
 #if __GNUC__
 #define ALWAYS_INLINE          __attribute__ ((always_inline))
+#elif defined _MSC_VER
+#define ALWAYS_INLINE          __forceinline
 #else
 #define ALWAYS_INLINE
 #endif
index c73347d..e762b27 100644 (file)
@@ -48,7 +48,7 @@ typedef struct alac_decoder_s
        {
                int32_t                 mPredictor [ALAC_FRAME_LENGTH] ;
                uint16_t                mShiftBuffer [ALAC_FRAME_LENGTH] ;
-       } ;
+       } ;
        uint32_t                        mNumChannels ;
 } ALAC_DECODER ;
 
index 6c124e6..46d3330 100644 (file)
@@ -110,7 +110,7 @@ alac_decoder_init (ALAC_DECODER *p, void * inMagicCookie, uint32_t inMagicCookie
 
                RequireAction (p->mConfig.compatibleVersion <= kALACVersion, return kALAC_IncompatibleVersion ;) ;
                RequireAction ((p->mConfig.bitDepth >= 8 && p->mConfig.bitDepth <= 32), return kALAC_BadBitWidth ;) ;
-               RequireAction ((p->mMixBufferU != NULL) && (p->mMixBufferV != NULL) && (p->mPredictor != NULL),
+               RequireAction ((p->mMixBufferU != NULL) && (p->mMixBufferV != NULL) && (p->u.mPredictor != NULL),
                                                status = kALAC_MemFullError ; goto Exit ;) ;
        }
        else
@@ -247,18 +247,18 @@ alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, int32_t * sampleBuffer, u
 
                                        // decompress
                                        set_ag_params (&agParams, p->mConfig.mb, (pb * pbFactorU) / 4, p->mConfig.kb, numSamples, numSamples, p->mConfig.maxRun) ;
-                                       status = dyn_decomp (&agParams, bits, p->mPredictor, numSamples, chanBits, &bits1) ;
+                                       status = dyn_decomp (&agParams, bits, p->u.mPredictor, numSamples, chanBits, &bits1) ;
                                        RequireNoErr (status, goto Exit ;) ;
 
                                        if (modeU == 0)
                                        {
-                                               unpc_block (p->mPredictor, p->mMixBufferU, numSamples, &coefsU [0], numU, chanBits, denShiftU) ;
+                                               unpc_block (p->u.mPredictor, p->mMixBufferU, numSamples, &coefsU [0], numU, chanBits, denShiftU) ;
                                        }
                                        else
                                        {
                                                // the special "numActive == 31" mode can be done in-place
-                                               unpc_block (p->mPredictor, p->mPredictor, numSamples, NULL, 31, chanBits, 0) ;
-                                               unpc_block (p->mPredictor, p->mMixBufferU, numSamples, &coefsU [0], numU, chanBits, denShiftU) ;
+                                               unpc_block (p->u.mPredictor, p->u.mPredictor, numSamples, NULL, 31, chanBits, 0) ;
+                                               unpc_block (p->u.mPredictor, p->mMixBufferU, numSamples, &coefsU [0], numU, chanBits, denShiftU) ;
                                        }
                                }
                                else
@@ -300,7 +300,7 @@ alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, int32_t * sampleBuffer, u
                                        //Assert (shift <= 16) ;
 
                                        for (i = 0 ; i < numSamples ; i++)
-                                               p->mShiftBuffer [i] = (uint16_t) BitBufferRead (&shiftBits, (uint8_t) shift) ;
+                                               p->u.mShiftBuffer [i] = (uint16_t) BitBufferRead (&shiftBits, (uint8_t) shift) ;
                                }
 
                                // convert 32-bit integers into output buffer
@@ -318,14 +318,14 @@ alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, int32_t * sampleBuffer, u
                                        case 24:
                                                out32 = sampleBuffer + channelIndex ;
                                                if (bytesShifted != 0)
-                                                       copyPredictorTo24Shift (p->mMixBufferU, p->mShiftBuffer, out32, numChannels, numSamples, bytesShifted) ;
+                                                       copyPredictorTo24Shift (p->mMixBufferU, p->u.mShiftBuffer, out32, numChannels, numSamples, bytesShifted) ;
                                                else
                                                        copyPredictorTo24 (p->mMixBufferU, out32, numChannels, numSamples) ;
                                                break ;
                                        case 32:
                                                out32 = sampleBuffer + channelIndex ;
                                                if (bytesShifted != 0)
-                                                       copyPredictorTo32Shift (p->mMixBufferU, p->mShiftBuffer, out32, numChannels, numSamples, bytesShifted) ;
+                                                       copyPredictorTo32Shift (p->mMixBufferU, p->u.mShiftBuffer, out32, numChannels, numSamples, bytesShifted) ;
                                                else
                                                        copyPredictorTo32 (p->mMixBufferU, out32, numChannels, numSamples) ;
                                                break ;
@@ -408,34 +408,34 @@ alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, int32_t * sampleBuffer, u
 
                                        // decompress and run predictor for "left" channel
                                        set_ag_params (&agParams, p->mConfig.mb, (pb * pbFactorU) / 4, p->mConfig.kb, numSamples, numSamples, p->mConfig.maxRun) ;
-                                       status = dyn_decomp (&agParams, bits, p->mPredictor, numSamples, chanBits, &bits1) ;
+                                       status = dyn_decomp (&agParams, bits, p->u.mPredictor, numSamples, chanBits, &bits1) ;
                                        RequireNoErr (status, goto Exit ;) ;
 
                                        if (modeU == 0)
                                        {
-                                               unpc_block (p->mPredictor, p->mMixBufferU, numSamples, &coefsU [0], numU, chanBits, denShiftU) ;
+                                               unpc_block (p->u.mPredictor, p->mMixBufferU, numSamples, &coefsU [0], numU, chanBits, denShiftU) ;
                                        }
                                        else
                                        {
                                                // the special "numActive == 31" mode can be done in-place
-                                               unpc_block (p->mPredictor, p->mPredictor, numSamples, NULL, 31, chanBits, 0) ;
-                                               unpc_block (p->mPredictor, p->mMixBufferU, numSamples, &coefsU [0], numU, chanBits, denShiftU) ;
+                                               unpc_block (p->u.mPredictor, p->u.mPredictor, numSamples, NULL, 31, chanBits, 0) ;
+                                               unpc_block (p->u.mPredictor, p->mMixBufferU, numSamples, &coefsU [0], numU, chanBits, denShiftU) ;
                                        }
 
                                        // decompress and run predictor for "right" channel
                                        set_ag_params (&agParams, p->mConfig.mb, (pb * pbFactorV) / 4, p->mConfig.kb, numSamples, numSamples, p->mConfig.maxRun) ;
-                                       status = dyn_decomp (&agParams, bits, p->mPredictor, numSamples, chanBits, &bits2) ;
+                                       status = dyn_decomp (&agParams, bits, p->u.mPredictor, numSamples, chanBits, &bits2) ;
                                        RequireNoErr (status, goto Exit ;) ;
 
                                        if (modeV == 0)
                                        {
-                                               unpc_block (p->mPredictor, p->mMixBufferV, numSamples, &coefsV [0], numV, chanBits, denShiftV) ;
+                                               unpc_block (p->u.mPredictor, p->mMixBufferV, numSamples, &coefsV [0], numV, chanBits, denShiftV) ;
                                        }
                                        else
                                        {
                                                // the special "numActive == 31" mode can be done in-place
-                                               unpc_block (p->mPredictor, p->mPredictor, numSamples, NULL, 31, chanBits, 0) ;
-                                               unpc_block (p->mPredictor, p->mMixBufferV, numSamples, &coefsV [0], numV, chanBits, denShiftV) ;
+                                               unpc_block (p->u.mPredictor, p->u.mPredictor, numSamples, NULL, 31, chanBits, 0) ;
+                                               unpc_block (p->u.mPredictor, p->mMixBufferV, numSamples, &coefsV [0], numV, chanBits, denShiftV) ;
                                        }
                                }
                                else
@@ -488,8 +488,8 @@ alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, int32_t * sampleBuffer, u
 
                                        for (i = 0 ; i < (numSamples * 2) ; i += 2)
                                        {
-                                               p->mShiftBuffer [i + 0] = (uint16_t) BitBufferRead (&shiftBits, (uint8_t) shift) ;
-                                               p->mShiftBuffer [i + 1] = (uint16_t) BitBufferRead (&shiftBits, (uint8_t) shift) ;
+                                               p->u.mShiftBuffer [i + 0] = (uint16_t) BitBufferRead (&shiftBits, (uint8_t) shift) ;
+                                               p->u.mShiftBuffer [i + 1] = (uint16_t) BitBufferRead (&shiftBits, (uint8_t) shift) ;
                                        }
                                }
 
@@ -508,12 +508,12 @@ alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, int32_t * sampleBuffer, u
                                        case 24:
                                                out32 = sampleBuffer + channelIndex ;
                                                unmix24 (p->mMixBufferU, p->mMixBufferV, out32, numChannels, numSamples,
-                                                                       mixBits, mixRes, p->mShiftBuffer, bytesShifted) ;
+                                                                       mixBits, mixRes, p->u.mShiftBuffer, bytesShifted) ;
                                                break ;
                                        case 32:
                                                out32 = sampleBuffer + channelIndex ;
                                                unmix32 (p->mMixBufferU, p->mMixBufferV, out32, numChannels, numSamples,
-                                                                       mixBits, mixRes, p->mShiftBuffer, bytesShifted) ;
+                                                                       mixBits, mixRes, p->u.mShiftBuffer, bytesShifted) ;
                                                break ;
                                }
 
@@ -554,7 +554,7 @@ alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, int32_t * sampleBuffer, u
                        }
                }
 
-#if 0 // ! DEBUG
+#if 1 // ! DEBUG
                // if we've decoded all of our channels, bail (but not in debug b/c we want to know if we're seeing bad bits)
                // - this also protects us if the config does not match the bitstream or crap data bits follow the audio bits
                if (channelIndex >= numChannels)
index 4f5bc1d..0d1c10d 100644 (file)
@@ -34,6 +34,8 @@
 
 #if __GNUC__
 #define ALWAYS_INLINE          __attribute__ ((always_inline))
+#elif defined _MSC_VER
+#define ALWAYS_INLINE          __forceinline
 #else
 #define ALWAYS_INLINE
 #endif
index ad098a4..01db8d4 100644 (file)
@@ -33,6 +33,8 @@
 
 #if __GNUC__
 #define ALWAYS_INLINE          __attribute__ ((always_inline))
+#elif defined _MSC_VER
+#define ALWAYS_INLINE          __forceinline
 #else
 #define ALWAYS_INLINE
 #endif
index 7c2d6f6..bce404d 100644 (file)
@@ -18,6 +18,8 @@
 
 #if __GNUC__
 #define ALWAYS_INLINE          __attribute__ ((always_inline))
+#elif defined _MSC_VER
+#define ALWAYS_INLINE          __forceinline
 #else
 #define ALWAYS_INLINE
 #endif
index e418fb7..6a194ec 100644 (file)
@@ -108,6 +108,8 @@ void private_init_state (G72x_STATE *state_ptr) ;
 
 #if __GNUC__
 #define ALWAYS_INLINE          __attribute__ ((always_inline))
+#elif defined _MSC_VER
+#define ALWAYS_INLINE          __forceinline
 #else
 #define ALWAYS_INLINE
 #endif
index dc95e3a..7ffaddc 100644 (file)
@@ -294,6 +294,8 @@ extern int16_t gsm_FAC [8] ;
 
 #if __GNUC__
 #define ALWAYS_INLINE          __attribute__ ((always_inline))
+#elif defined _MSC_VER
+#define ALWAYS_INLINE          __forceinline
 #else
 #define ALWAYS_INLINE
 #endif
index d872a89..7ad0312 100644 (file)
@@ -234,7 +234,7 @@ static int aiff_get_chunk_data (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * itera
 int
 aiff_open (SF_PRIVATE *psf)
 {      COMM_CHUNK comm_fmt ;
-       int error, subformat ;
+       int error = 0, subformat ;
 
        memset (&comm_fmt, 0, sizeof (comm_fmt)) ;
 
@@ -507,7 +507,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
                                        if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
                                                return SFE_MALLOC_FAILED ;
 
-                                       /* read in rest of PEAK chunk. */
+                                       /* Read in rest of PEAK chunk. */
                                        psf_binheader_readf (psf, "E44", &(psf->peak_info->version), &(psf->peak_info->timestamp)) ;
 
                                        if (psf->peak_info->version != 1)
@@ -1003,7 +1003,7 @@ aiff_read_comm_chunk (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
        ubuf.scbuf [0] = 0 ;
 
        /* The COMM chunk has an int aligned to an odd word boundary. Some
-       ** procesors are not able to deal with this (ie bus fault) so we have
+       ** processors are not able to deal with this (ie bus fault) so we have
        ** to take special care.
        */
 
index f83dd2f..a6668f3 100644 (file)
@@ -51,12 +51,12 @@ typedef struct
 
 
        /* Can't have a decoder and an encoder at the same time so stick
-       ** them in an un-named union.
+       ** them in a union.
        */
        union
        {       ALAC_DECODER decoder ;
                ALAC_ENCODER encoder ;
-       } ;
+       } ;
 
        char enctmpname [512] ;
        FILE *enctmp ;
@@ -169,7 +169,7 @@ alac_close  (SF_PRIVATE *psf)
        plac = psf->codec_data ;
 
        if (psf->file.mode == SFM_WRITE)
-       {       ALAC_ENCODER *penc = &plac->encoder ;
+       {       ALAC_ENCODER *penc = &plac->u.encoder ;
                SF_CHUNK_INFO chunk_info ;
                sf_count_t readcount ;
                uint8_t kuki_data [1024] ;
@@ -268,14 +268,14 @@ alac_reader_init (SF_PRIVATE *psf, const ALAC_DECODER_INFO * info)
        /* Read in the ALAC cookie data and pass it to the init function. */
        kuki_size = alac_kuki_read (psf, info->kuki_offset, u.kuki, sizeof (u.kuki)) ;
 
-       if ((error = alac_decoder_init (&plac->decoder, u.kuki, kuki_size)) != ALAC_noErr)
+       if ((error = alac_decoder_init (&plac->u.decoder, u.kuki, kuki_size)) != ALAC_noErr)
        {       psf_log_printf (psf, "*** alac_decoder_init() returned %s. ***\n", alac_error_string (error)) ;
                return SFE_INTERNAL ;
                } ;
 
 
-       if (plac->decoder.mNumChannels != (unsigned) psf->sf.channels)
-       {       psf_log_printf (psf, "*** Initialized decoder has %u channels, but it should be %d. ***\n", plac->decoder.mNumChannels, psf->sf.channels) ;
+       if (plac->u.decoder.mNumChannels != (unsigned) psf->sf.channels)
+       {       psf_log_printf (psf, "*** Initialized decoder has %u channels, but it should be %d. ***\n", plac->u.decoder.mNumChannels, psf->sf.channels) ;
                return SFE_INTERNAL ;
                } ;
 
@@ -357,7 +357,7 @@ alac_writer_init (SF_PRIVATE *psf)
                return SFE_ALAC_FAIL_TMPFILE ;
                } ;
 
-       alac_encoder_init (&plac->encoder, psf->sf.samplerate, psf->sf.channels, alac_format_flags, ALAC_FRAME_LENGTH) ;
+       alac_encoder_init (&plac->u.encoder, psf->sf.samplerate, psf->sf.channels, alac_format_flags, ALAC_FRAME_LENGTH) ;
 
        return 0 ;
 } /* alac_writer_init */
@@ -402,7 +402,7 @@ alac_reader_calc_frames (SF_PRIVATE *psf, ALAC_PRIVATE *plac)
 
 static int
 alac_decode_block (SF_PRIVATE *psf, ALAC_PRIVATE *plac)
-{      ALAC_DECODER *pdec = &plac->decoder ;
+{      ALAC_DECODER *pdec = &plac->u.decoder ;
        uint32_t        packet_size ;
        BitBuffer       bit_buffer ;
 
@@ -437,7 +437,7 @@ alac_decode_block (SF_PRIVATE *psf, ALAC_PRIVATE *plac)
 
 static int
 alac_encode_block (ALAC_PRIVATE *plac)
-{      ALAC_ENCODER *penc = &plac->encoder ;
+{      ALAC_ENCODER *penc = &plac->u.encoder ;
        uint32_t num_bytes = 0 ;
 
        alac_encode (penc, plac->partial_block_frames, plac->buffer, plac->byte_buffer, &num_bytes) ;
@@ -471,7 +471,7 @@ alac_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
                        break ;
 
                readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
-               readcount = readcount > len ? len : readcount ;
+               readcount = readcount > len ? (int) len : readcount ;
 
                iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
 
@@ -501,7 +501,7 @@ alac_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
                        break ;
 
                readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
-               readcount = readcount > len ? len : readcount ;
+               readcount = readcount > len ? (int) len : readcount ;
 
                iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
 
@@ -534,7 +534,7 @@ alac_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
                        break ;
 
                readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
-               readcount = readcount > len ? len : readcount ;
+               readcount = readcount > len ? (int) len : readcount ;
 
                iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
 
@@ -567,7 +567,7 @@ alac_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
                        break ;
 
                readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
-               readcount = readcount > len ? len : readcount ;
+               readcount = readcount > len ? (int) len : readcount ;
 
                iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
 
@@ -648,7 +648,7 @@ alac_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
 
        while (len > 0)
        {       writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
-               writecount = (writecount == 0 || writecount > len) ? len : writecount ;
+               writecount = (writecount == 0 || writecount > len) ? (int) len : writecount ;
 
                iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
 
@@ -679,7 +679,7 @@ alac_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
 
        while (len > 0)
        {       writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
-               writecount = (writecount == 0 || writecount > len) ? len : writecount ;
+               writecount = (writecount == 0 || writecount > len) ? (int) len : writecount ;
 
                iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
 
@@ -713,7 +713,7 @@ alac_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
 
        while (len > 0)
        {       writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
-               writecount = (writecount == 0 || writecount > len) ? len : writecount ;
+               writecount = (writecount == 0 || writecount > len) ? (int) len : writecount ;
 
                iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
 
@@ -746,7 +746,7 @@ alac_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
 
        while (len > 0)
        {       writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
-               writecount = (writecount == 0 || writecount > len) ? len : writecount ;
+               writecount = (writecount == 0 || writecount > len) ? (int) len : writecount ;
 
                iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
 
@@ -824,6 +824,8 @@ alac_pakt_read_decode (SF_PRIVATE * psf, uint32_t UNUSED (pakt_offset))
 
        pakt_size = chunk_info.datalen ;
        chunk_info.data = pakt_data = malloc (pakt_size + 5) ;
+       if (!chunk_info.data)
+               return NULL ;
 
        if ((bcount = psf->get_chunk_data (psf, chunk_iterator, &chunk_info)) != SF_ERR_NO_ERROR)
        {       while (chunk_iterator)
@@ -850,7 +852,7 @@ alac_pakt_read_decode (SF_PRIVATE * psf, uint32_t UNUSED (pakt_offset))
 
                        count ++ ;
                        if (count > 5 || bcount + count > pakt_size)
-                       {       printf ("%s %d : Ooops! count %d    bcount %d\n", __func__, __LINE__, count, bcount) ;
+                       {       printf ("%s %d : Ooops! count %" PRIi32 "    bcount %" PRIu32 "\n", __func__, __LINE__, count, bcount) ;
                                value = 0 ;
                                break ;
                                } ;
index 6e0a794..4be642e 100644 (file)
@@ -292,69 +292,69 @@ unsigned char alaw_encode [2048 + 1] =
 
 static inline void
 alaw2s_array (unsigned char *buffer, int count, short *ptr)
-{      while (--count >= 0)
-               ptr [count] = alaw_decode [(int) buffer [count]] ;
+{      for (int i = 0 ; i < count ; i++)
+               ptr [i] = alaw_decode [(int) buffer [i]] ;
 } /* alaw2s_array */
 
 static inline void
 alaw2i_array (unsigned char *buffer, int count, int *ptr)
-{      while (--count >= 0)
-               ptr [count] = ((uint32_t) alaw_decode [(int) buffer [count]]) << 16 ;
+{      for (int i = 0 ; i < count ; i++)
+               ptr [i] = ((uint32_t) alaw_decode [(int) buffer [i]]) << 16 ;
 } /* alaw2i_array */
 
 static inline void
 alaw2f_array (unsigned char *buffer, int count, float *ptr, float normfact)
-{      while (--count >= 0)
-               ptr [count] = normfact * alaw_decode [(int) buffer [count]] ;
+{      for (int i = 0 ; i < count ; i++)
+               ptr [i] = normfact * alaw_decode [(int) buffer [i]] ;
 } /* alaw2f_array */
 
 static inline void
 alaw2d_array (unsigned char *buffer, int count, double *ptr, double normfact)
-{      while (--count >= 0)
-               ptr [count] = normfact * alaw_decode [(int) buffer [count]] ;
+{      for (int i = 0 ; i < count ; i++)
+               ptr [i] = normfact * alaw_decode [(int) buffer [i]] ;
 } /* alaw2d_array */
 
 static inline void
 s2alaw_array (const short *ptr, int count, unsigned char *buffer)
-{      while (--count >= 0)
-       {       if (ptr [count] >= 0)
-                       buffer [count] = alaw_encode [ptr [count] / 16] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       if (ptr [i] >= 0)
+                       buffer [i] = alaw_encode [ptr [i] / 16] ;
                else
-                       buffer [count] = 0x7F & alaw_encode [ptr [count] / -16] ;
+                       buffer [i] = 0x7F & alaw_encode [ptr [i] / -16] ;
                } ;
 } /* s2alaw_array */
 
 static inline void
 i2alaw_array (const int *ptr, int count, unsigned char *buffer)
-{      while (--count >= 0)
-       {       if (ptr [count] == INT_MIN)
-                       buffer [count] = alaw_encode [INT_MAX >> (16 + 4)] ;
-               else if (ptr [count] >= 0)
-                       buffer [count] = alaw_encode [ptr [count] >> (16 + 4)] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       if (ptr [i] == INT_MIN)
+                       buffer [i] = alaw_encode [INT_MAX >> (16 + 4)] ;
+               else if (ptr [i] >= 0)
+                       buffer [i] = alaw_encode [ptr [i] >> (16 + 4)] ;
                else
-                       buffer [count] = 0x7F & alaw_encode [- ptr [count] >> (16 + 4)] ;
+                       buffer [i] = 0x7F & alaw_encode [- ptr [i] >> (16 + 4)] ;
                } ;
 } /* i2alaw_array */
 
 static inline void
 f2alaw_array (const float *ptr, int count, unsigned char *buffer, float normfact)
-{      while (--count >= 0)
-       {       if (ptr [count] >= 0)
-                       buffer [count] = alaw_encode [psf_lrintf (normfact * ptr [count])] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       if (ptr [i] >= 0)
+                       buffer [i] = alaw_encode [psf_lrintf (normfact * ptr [i])] ;
                else
-                       buffer [count] = 0x7F & alaw_encode [- psf_lrintf (normfact * ptr [count])] ;
+                       buffer [i] = 0x7F & alaw_encode [- psf_lrintf (normfact * ptr [i])] ;
                } ;
 } /* f2alaw_array */
 
 static inline void
 d2alaw_array (const double *ptr, int count, unsigned char *buffer, double normfact)
-{      while (--count >= 0)
-       {       if (!isfinite (ptr [count]))
-                       buffer [count] = 0 ;
-               else if (ptr [count] >= 0)
-                       buffer [count] = alaw_encode [psf_lrint (normfact * ptr [count])] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       if (!isfinite (ptr [i]))
+                       buffer [i] = 0 ;
+               else if (ptr [i] >= 0)
+                       buffer [i] = alaw_encode [psf_lrint (normfact * ptr [i])] ;
                else
-                       buffer [count] = 0x7F & alaw_encode [- psf_lrint (normfact * ptr [count])] ;
+                       buffer [i] = 0x7F & alaw_encode [- psf_lrint (normfact * ptr [i])] ;
                } ;
 } /* d2alaw_array */
 
@@ -372,7 +372,7 @@ alaw_read_alaw2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
                alaw2s_array (ubuf.ucbuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -394,7 +394,7 @@ alaw_read_alaw2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
                alaw2i_array (ubuf.ucbuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -419,7 +419,7 @@ alaw_read_alaw2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
                alaw2f_array (ubuf.ucbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -443,7 +443,7 @@ alaw_read_alaw2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
                alaw2d_array (ubuf.ucbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -469,7 +469,7 @@ alaw_write_s2alaw   (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                s2alaw_array (ptr + total, bufferlen, ubuf.ucbuf) ;
-               writecount = psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -491,7 +491,7 @@ alaw_write_i2alaw   (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                i2alaw_array (ptr + total, bufferlen, ubuf.ucbuf) ;
-               writecount = psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -516,7 +516,7 @@ alaw_write_f2alaw   (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                f2alaw_array (ptr + total, bufferlen, ubuf.ucbuf, normfact) ;
-               writecount = psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -541,7 +541,7 @@ alaw_write_d2alaw   (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                d2alaw_array (ptr + total, bufferlen, ubuf.ucbuf, normfact) ;
-               writecount = psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
index bd6b00f..6c78ff6 100644 (file)
--- a/src/avr.c
+++ b/src/avr.c
@@ -28,8 +28,6 @@
 #define TWOBIT_MARKER  (MAKE_MARKER ('2', 'B', 'I', 'T'))
 #define        AVR_HDR_SIZE    128
 
-#define        SFE_AVR_X       666
-
 /*
 ** From: hyc@hanauma.Jpl.Nasa.Gov (Howard Chu)
 **
@@ -116,7 +114,7 @@ avr_read_header (SF_PRIVATE *psf)
        psf_log_printf (psf, "%M\n", hdr.marker) ;
 
        if (hdr.marker != TWOBIT_MARKER)
-               return SFE_AVR_X ;
+               return SFE_AVR_NOT_AVR ;
 
        psf_log_printf (psf, "  Name        : %s\n", hdr.name) ;
 
@@ -145,7 +143,7 @@ avr_read_header (SF_PRIVATE *psf)
 
                default :
                        psf_log_printf (psf, "Error : bad rez/sign combination.\n") ;
-                       return SFE_AVR_X ;
+                       return SFE_AVR_BAD_REZ_SIGN ;
                } ;
 
        psf_binheader_readf (psf, "E4444", &hdr.srate, &hdr.frames, &hdr.lbeg, &hdr.lend) ;
index 16575bb..aad5f88 100644 (file)
@@ -84,7 +84,7 @@ broadcast_var_set (SF_PRIVATE *psf, const SF_BROADCAST_INFO * info, size_t datas
        /* Force coding_history_size to be even. */
        len = strlen (psf->broadcast_16k->coding_history) ;
        len += (len & 1) ? 1 : 0 ;
-       psf->broadcast_16k->coding_history_size = len ;
+       psf->broadcast_16k->coding_history_size = (uint32_t) len ;
 
        /* Currently writing this version. */
        psf->broadcast_16k->version = 2 ;
@@ -146,7 +146,7 @@ gen_coding_history (char * added_history, int added_history_max, const SF_INFO *
                        break ;
 
                default :
-                       snprintf (chnstr, sizeof (chnstr), "%uchn", psfinfo->channels) ;
+                       snprintf (chnstr, sizeof (chnstr), "%dchn", psfinfo->channels) ;
                        break ;
                } ;
 
@@ -180,7 +180,7 @@ gen_coding_history (char * added_history, int added_history_max, const SF_INFO *
                } ;
 
        count = snprintf (added_history, added_history_max,
-                                                       "A=PCM,F=%u,W=%d,M=%s,T=%s-%s\r\n",
+                                                       "A=PCM,F=%d,W=%d,M=%s,T=%s-%s\r\n",
                                                        psfinfo->samplerate, width, chnstr, PACKAGE_NAME, PACKAGE_VERSION) ;
 
        if (count >= added_history_max)
index 45b1dba..a886bf5 100644 (file)
--- a/src/caf.c
+++ b/src/caf.c
 
 #define CAF_PEAK_CHUNK_SIZE(ch)        ((int) (sizeof (int) + ch * (sizeof (float) + 8)))
 
-#define SFE_CAF_NOT_CAF        666
-#define SFE_CAF_NO_DESC        667
-#define SFE_CAF_BAD_PEAK 668
-
 /*------------------------------------------------------------------------------
 ** Typedefs.
 */
@@ -411,11 +407,16 @@ caf_read_header (SF_PRIVATE *psf)
                {       case peak_MARKER :
                                psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
                                if (chunk_size != CAF_PEAK_CHUNK_SIZE (psf->sf.channels))
-                               {       psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ;
+                               {       psf_binheader_readf (psf, "j", (size_t) chunk_size) ;
                                        psf_log_printf (psf, "*** File PEAK chunk %D should be %d.\n", chunk_size, CAF_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
                                        return SFE_CAF_BAD_PEAK ;
                                        } ;
 
+                               if (psf->peak_info)
+                               {       psf_log_printf (psf, "*** Found existing peak info, using last one.\n") ;
+                                       free (psf->peak_info) ;
+                                       psf->peak_info = NULL ;
+                                       } ;
                                if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
                                        return SFE_MALLOC_FAILED ;
 
@@ -442,7 +443,7 @@ caf_read_header (SF_PRIVATE *psf)
                        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", make_size_t (chunk_size)) ;
+                                       psf_binheader_readf (psf, "j", (size_t) chunk_size) ;
                                        break ;
                                        }
 
@@ -454,7 +455,7 @@ caf_read_header (SF_PRIVATE *psf)
 
                        case free_MARKER :
                                psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
-                               psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ;
+                               psf_binheader_readf (psf, "j", (size_t) chunk_size) ;
                                break ;
 
                        case data_MARKER :
@@ -479,14 +480,14 @@ caf_read_header (SF_PRIVATE *psf)
                                if (psf->datalength + psf->dataoffset < psf->filelength)
                                        psf->dataend = psf->datalength + psf->dataoffset ;
 
-                               psf_binheader_readf (psf, "j", make_size_t (psf->datalength)) ;
+                               psf_binheader_readf (psf, "j", (size_t) psf->datalength) ;
                                have_data = 1 ;
                                break ;
 
                        case kuki_MARKER :
                                psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
                                pcaf->alac.kuki_offset = psf_ftell (psf) - 12 ;
-                               psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ;
+                               psf_binheader_readf (psf, "j", (size_t) chunk_size) ;
                                break ;
 
                        case pakt_MARKER :
@@ -518,7 +519,7 @@ caf_read_header (SF_PRIVATE *psf)
                                        psf_log_printf (psf, "*** 'pakt' chunk header is all zero.\n") ;
 
                                pcaf->alac.pakt_offset = psf_ftell (psf) - 12 ;
-                               psf_binheader_readf (psf, "j", make_size_t (chunk_size) - 24) ;
+                               psf_binheader_readf (psf, "j", (size_t) chunk_size - 24) ;
                                break ;
 
                        case info_MARKER :
@@ -537,7 +538,7 @@ caf_read_header (SF_PRIVATE *psf)
 
                        default :
                                psf_log_printf (psf, "%M : %D (skipped)\n", marker, chunk_size) ;
-                               psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ;
+                               psf_binheader_readf (psf, "j", (size_t) chunk_size) ;
                                break ;
                        } ;
 
@@ -845,7 +846,7 @@ caf_read_strings (SF_PRIVATE * psf, sf_count_t chunk_size)
        if ((buf = malloc (chunk_size + 1)) == NULL)
                return (psf->error = SFE_MALLOC_FAILED) ;
 
-       psf_binheader_readf (psf, "E4b", &count, buf, make_size_t (chunk_size)) ;
+       psf_binheader_readf (psf, "E4b", &count, buf, (size_t) chunk_size) ;
        psf_log_printf (psf, " count: %u\n", count) ;
 
        /* Force terminate `buf` to make sure. */
index a56ed60..8b00eab 100644 (file)
@@ -79,7 +79,7 @@ cart_var_set (SF_PRIVATE *psf, const SF_CART_INFO * info, size_t datasize)
        len = strlen (psf->cart_16k->tag_text) ;
        len += (len & 1) ? 1 : 2 ;
 
-       psf->cart_16k->tag_text_size = len ;
+       psf->cart_16k->tag_text_size = (uint32_t) len ;
 
        return SF_TRUE ;
 } /* cart_var_set */
index 471c5a4..08411d3 100644 (file)
@@ -75,7 +75,7 @@ psf_get_chunk_iterator (SF_PRIVATE * psf, const char * marker_str)
                hash = marker_len > 4 ? hash_of_str (marker_str) : u.marker ;
 
                memcpy (psf->iterator->id, marker_str, marker_len) ;
-               psf->iterator->id_size = marker_len ;
+               psf->iterator->id_size = (unsigned) marker_len ;
                psf->iterator->hash = hash ;
                }
 
@@ -112,6 +112,9 @@ psf_store_read_chunk (READ_CHUNKS * pchk, const READ_CHUNK * rchunk)
        {       pchk->used = 0 ;
                pchk->count = 20 ;
                pchk->chunks = calloc (pchk->count, sizeof (READ_CHUNK)) ;
+               if (!pchk->chunks)
+               {       return SFE_MALLOC_FAILED ;
+                       } ;
                }
        else if (pchk->used > pchk->count)
                return SFE_INTERNAL ;
@@ -208,7 +211,7 @@ psf_store_read_chunk_str (READ_CHUNKS * pchk, const char * marker_str, sf_count_
        rchunk.offset = offset ;
        rchunk.len = len ;
 
-       rchunk.id_size = marker_len > 64 ? 64 : marker_len ;
+       rchunk.id_size = marker_len > 64 ? 64 : (unsigned) marker_len ;
        memcpy (rchunk.id, marker_str, rchunk.id_size) ;
 
        return psf_store_read_chunk (pchk, &rchunk) ;
@@ -227,6 +230,9 @@ psf_save_write_chunk (WRITE_CHUNKS * pchk, const SF_CHUNK_INFO * chunk_info)
        {       pchk->used = 0 ;
                pchk->count = 20 ;
                pchk->chunks = calloc (pchk->count, sizeof (WRITE_CHUNK)) ;
+               if (!pchk->chunks)
+               {       return SFE_MALLOC_FAILED ;
+                       } ;
                }
        else if (pchk->used >= pchk->count)
        {       WRITE_CHUNK * old_ptr = pchk->chunks ;
index 15037ab..d4837da 100644 (file)
@@ -61,6 +61,12 @@ static SF_FORMAT_INFO const simple_formats [] =
                },
 #endif
 
+#if HAVE_MPEG
+       {       SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III,
+               "MPEG Layer 3", "mp3"
+               },
+#endif
+
        {       SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM,
                "OKI Dialogic VOX ADPCM", "vox"
                },
@@ -133,6 +139,9 @@ static SF_FORMAT_INFO const major_formats [] =
        {       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_MPEG
+       {       SF_FORMAT_MPEG,         "MPEG-1/2 Audio",                                               "m1a"   },
+#endif
 #if HAVE_EXTERNAL_XIPH_LIBS
        {       SF_FORMAT_OGG,          "OGG (OGG Container format)",                   "oga"   },
 #endif
@@ -215,6 +224,12 @@ static SF_FORMAT_INFO subtype_formats [] =
        {       SF_FORMAT_OPUS,                 "Opus",                                 NULL    },
 #endif
 
+#if HAVE_MPEG
+       {       SF_FORMAT_MPEG_LAYER_I,         "MPEG Layer I",         "mp1"   },
+       {       SF_FORMAT_MPEG_LAYER_II,        "MPEG Layer II",        "mp2"   },
+       {       SF_FORMAT_MPEG_LAYER_III,       "MPEG Layer III",       "mp3"   },
+#endif
+
        {       SF_FORMAT_ALAC_16,              "16 bit ALAC",                  NULL    },
        {       SF_FORMAT_ALAC_20,              "20 bit ALAC",                  NULL    },
        {       SF_FORMAT_ALAC_24,              "24 bit ALAC",                  NULL    },
@@ -309,7 +324,7 @@ psf_calc_signal_max (SF_PRIVATE *psf, int normalize)
        len = ARRAY_LEN (ubuf.dbuf) - (ARRAY_LEN (ubuf.dbuf) % psf->sf.channels) ;
 
        for (readcount = 1, max_val = 0.0 ; readcount > 0 ; /* nothing */)
-       {       readcount = sf_read_double ((SNDFILE*) psf, data, len) ;
+       {       readcount = (int) sf_read_double ((SNDFILE*) psf, data, len) ;
                for (k = 0 ; k < readcount ; k++)
                {       temp = fabs (data [k]) ;
                        max_val = temp > max_val ? temp : max_val ;
@@ -354,7 +369,7 @@ psf_calc_max_all_channels (SF_PRIVATE *psf, double *peaks, int normalize)
        chan = 0 ;
        readcount = len ;
        while (readcount > 0)
-       {       readcount = sf_read_double ((SNDFILE*) psf, data, len) ;
+       {       readcount = (int) sf_read_double ((SNDFILE*) psf, data, len) ;
                for (k = 0 ; k < readcount ; k++)
                {       temp = fabs (data [k]) ;
                        peaks [chan] = temp > peaks [chan] ? temp : peaks [chan] ;
index c9737a9..c4ef4a6 100644 (file)
@@ -103,8 +103,8 @@ log_putchar (SF_PRIVATE *psf, char ch)
 void
 psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
 {      va_list         ap ;
-       uint32_t        u ;
-       int                     d, tens, shift, width, width_specifier, left_align, slen ;
+       uint32_t        u, tens ;
+       int                     d, shift, width, width_specifier, left_align, slen, precision ;
        char            c, *strptr, istr [5], lead_char, sign_char ;
 
        va_start (ap, format) ;
@@ -153,6 +153,12 @@ psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
                while ((c = *format++) && isdigit (c))
                        width_specifier = width_specifier * 10 + (c - '0') ;
 
+               precision = 0 ;
+               if (c == '.')
+               {       while ((c = *format++) && isdigit (c))
+                               precision = precision * 10 + (c - '0') ;
+                       } ;
+
                switch (c)
                {       case 0 : /* NULL character. */
                                        va_end (ap) ;
@@ -162,12 +168,15 @@ psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
                                        strptr = va_arg (ap, char *) ;
                                        if (strptr == NULL)
                                                break ;
-                                       slen = strlen (strptr) ;
+                                       if (precision > 0)
+                                               slen = strnlen (strptr, precision) ;
+                                       else
+                                               slen = strlen (strptr) ;
                                        width_specifier = width_specifier >= slen ? width_specifier - slen : 0 ;
                                        if (left_align == SF_FALSE)
                                                while (width_specifier -- > 0)
                                                        log_putchar (psf, ' ') ;
-                                       while (*strptr)
+                                       while (slen--)
                                                log_putchar (psf, *strptr++) ;
                                        while (width_specifier -- > 0)
                                                log_putchar (psf, ' ') ;
@@ -177,15 +186,19 @@ psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
                                        d = va_arg (ap, int) ;
 
                                        if (d < 0)
-                                       {       d = -d ;
-                                               sign_char = '-' ;
+                                       {       sign_char = '-' ;
                                                if (lead_char != '0' && left_align == SF_FALSE)
                                                        width_specifier -- ;
-                                               } ;
+
+                                               u = - ((unsigned) d) ;
+                                               }
+                                       else
+                                       {       u = (unsigned) d ;
+                                               }
 
                                        tens = 1 ;
                                        width = 1 ;
-                                       while (d / tens >= 10)
+                                       while (u / tens >= 10)
                                        {       tens *= 10 ;
                                                width ++ ;
                                                } ;
@@ -215,8 +228,8 @@ psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
                                                        log_putchar (psf, lead_char) ;
 
                                        while (tens > 0)
-                                       {       log_putchar (psf, '0' + d / tens) ;
-                                               d %= tens ;
+                                       {       log_putchar (psf, '0' + u / tens) ;
+                                               u %= tens ;
                                                tens /= 10 ;
                                                } ;
 
@@ -225,7 +238,8 @@ psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
                                        break ;
 
                        case 'D': /* sf_count_t */
-                                       {       sf_count_t              D, Tens ;
+                                       {       sf_count_t      D ;
+                                               uint64_t        U, Tens ;
 
                                                D = va_arg (ap, sf_count_t) ;
 
@@ -235,13 +249,19 @@ psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
                                                        log_putchar (psf, '0') ;
                                                        break ;
                                                        }
-                                               if (D < 0)
-                                               {       log_putchar (psf, '-') ;
-                                                       D = -D ;
-                                                       } ;
+                                               else
+                                               {       if (D < 0)
+                                                       {       log_putchar (psf, '-') ;
+                                                               U = -((uint64_t) D) ;
+                                                               }
+                                                       else
+                                                       {       U = (uint64_t) D;
+                                                               }
+                                                       }
+
                                                Tens = 1 ;
                                                width = 1 ;
-                                               while (D / Tens >= 10)
+                                               while (U / Tens >= 10)
                                                {       Tens *= 10 ;
                                                        width ++ ;
                                                        } ;
@@ -252,8 +272,8 @@ psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
                                                        } ;
 
                                                while (Tens > 0)
-                                               {       log_putchar (psf, '0' + D / Tens) ;
-                                                       D %= Tens ;
+                                               {       log_putchar (psf, '0' + U / Tens) ;
+                                                       U %= Tens ;
                                                        Tens /= 10 ;
                                                        } ;
                                                } ;
@@ -525,24 +545,24 @@ header_put_le_int (SF_PRIVATE *psf, int x)
 static inline void
 header_put_be_8byte (SF_PRIVATE *psf, sf_count_t x)
 {      psf->header.ptr [psf->header.indx++] = (x >> 56) ;
-       psf->header.ptr [psf->header.indx++] = (x >> 48) ;
-       psf->header.ptr [psf->header.indx++] = (x >> 40) ;
-       psf->header.ptr [psf->header.indx++] = (x >> 32) ;
-       psf->header.ptr [psf->header.indx++] = (x >> 24) ;
-       psf->header.ptr [psf->header.indx++] = (x >> 16) ;
-       psf->header.ptr [psf->header.indx++] = (x >> 8) ;
-       psf->header.ptr [psf->header.indx++] = x ;
+       psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 48) ;
+       psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 40) ;
+       psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 32) ;
+       psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 24) ;
+       psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 16) ;
+       psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 8) ;
+       psf->header.ptr [psf->header.indx++] = (unsigned char) x ;
 } /* header_put_be_8byte */
 
 static inline void
 header_put_le_8byte (SF_PRIVATE *psf, sf_count_t x)
-{      psf->header.ptr [psf->header.indx++] = x ;
-       psf->header.ptr [psf->header.indx++] = (x >> 8) ;
-       psf->header.ptr [psf->header.indx++] = (x >> 16) ;
-       psf->header.ptr [psf->header.indx++] = (x >> 24) ;
-       psf->header.ptr [psf->header.indx++] = (x >> 32) ;
-       psf->header.ptr [psf->header.indx++] = (x >> 40) ;
-       psf->header.ptr [psf->header.indx++] = (x >> 48) ;
+{      psf->header.ptr [psf->header.indx++] = (unsigned char) x ;
+       psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 8) ;
+       psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 16) ;
+       psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 24) ;
+       psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 32) ;
+       psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 40) ;
+       psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 48) ;
        psf->header.ptr [psf->header.indx++] = (x >> 56) ;
 } /* header_put_le_8byte */
 
@@ -571,7 +591,7 @@ psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
        while ((c = *format++))
        {
                if (psf->header.indx + 16 >= psf->header.len && psf_bump_header_allocation (psf, 16))
-                       return count ;
+                       break ;
 
                switch (c)
                {       case ' ' : /* Do nothing. Just used to space out format string. */
@@ -687,7 +707,7 @@ psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
                                        size = strlen (strptr) + 1 ;
 
                                        if (psf->header.indx + 4 + (sf_count_t) size + (sf_count_t) (size & 1) > psf->header.len && psf_bump_header_allocation (psf, 4 + size + (size & 1)))
-                                               return count ;
+                                               break ;
 
                                        if (psf->rwf_endian == SF_ENDIAN_BIG)
                                                header_put_be_int (psf, size + (size & 1)) ;
@@ -708,7 +728,7 @@ psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
                                        strptr = va_arg (argptr, char *) ;
                                        size = strlen (strptr) ;
                                        if (psf->header.indx + 4 + (sf_count_t) size + (sf_count_t) (size & 1) > psf->header.len && psf_bump_header_allocation (psf, 4 + size + (size & 1)))
-                                               return count ;
+                                               break ;
                                        if (psf->rwf_endian == SF_ENDIAN_BIG)
                                                header_put_be_int (psf, size) ;
                                        else
@@ -728,7 +748,7 @@ psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
                                        size = (size > 254) ? 254 : size ;
 
                                        if (psf->header.indx + 1 + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, 1 + size))
-                                               return count ;
+                                               break ;
 
                                        header_put_byte (psf, size) ;
                                        memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size) ;
@@ -741,7 +761,7 @@ psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
                                        size    = va_arg (argptr, size_t) ;
 
                                        if (psf->header.indx + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, size))
-                                               return count ;
+                                               break ;
 
                                        memcpy (&(psf->header.ptr [psf->header.indx]), bindata, size) ;
                                        psf->header.indx += size ;
@@ -752,7 +772,7 @@ psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
                                        size = va_arg (argptr, size_t) ;
 
                                        if (psf->header.indx + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, size))
-                                               return count ;
+                                               break ;
 
                                        count += size ;
                                        while (size)
@@ -773,7 +793,7 @@ psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
                                        size = va_arg (argptr, size_t) ;
 
                                        if (psf->header.indx + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, size))
-                                               return count ;
+                                               break ;
 
                                        psf->header.indx += size ;
                                        count += size ;
@@ -783,7 +803,7 @@ psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
                                        size = va_arg (argptr, size_t) ;
 
                                        if ((sf_count_t) size >= psf->header.len && psf_bump_header_allocation (psf, size))
-                                               return count ;
+                                               break ;
 
                                        psf->header.indx = size ;
                                        break ;
@@ -877,7 +897,7 @@ header_seek (SF_PRIVATE *psf, sf_count_t position, int whence)
                                psf_bump_header_allocation (psf, position) ;
                        if (position > psf->header.len)
                        {       /* Too much header to cache so just seek instead. */
-                               psf->header.indx = psf->header.end ;
+                               psf->header.indx = psf->header.end = 0 ;
                                psf_fseek (psf, position, whence) ;
                                return ;
                                } ;
@@ -954,7 +974,7 @@ int
 psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...)
 {      va_list                 argptr ;
        sf_count_t              *countptr, countdata ;
-       unsigned char   *ucptr, sixteen_bytes [16] ;
+       unsigned char   *ucptr, sixteen_bytes [16] = { 0 } ;
        unsigned int    *intptr, intdata ;
        unsigned short  *shortptr ;
        char                    *charptr ;
@@ -971,7 +991,7 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...)
        while ((c = *format++))
        {
                if (psf->header.indx + 16 >= psf->header.len && psf_bump_header_allocation (psf, 16))
-                       return count ;
+                       break ;
 
                switch (c)
                {       case 'e' : /* All conversions are now from LE to host. */
@@ -1098,7 +1118,7 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...)
                                        memset (charptr, 0, count) ;
 
                                        if (psf->header.indx + count >= psf->header.len && psf_bump_header_allocation (psf, count))
-                                               return 0 ;
+                                               break ;
 
                                        byte_count += header_gets (psf, charptr, count) ;
                                        break ;
@@ -1127,6 +1147,10 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...)
                                        byte_count += count ;
                                        break ;
 
+                       case '!' : /* Clear buffer, forcing re-read. */
+                                       psf->header.end = psf->header.indx = 0 ;
+                                       break ;
+
                        default :
                                psf_log_printf (psf, "*** Invalid format specifier `%c'\n", c) ;
                                psf->error = SFE_INTERNAL ;
@@ -1221,6 +1245,37 @@ psf_log_SF_INFO (SF_PRIVATE *psf)
 /*========================================================================================
 */
 
+int
+psf_isprint (int ch)
+{      return (ch >= ' ' && ch <= '~') ;
+} /* psf_isprint */
+
+void
+psf_strlcat (char *dest, size_t n, const char *src)
+{      strncat (dest, src, n - strlen (dest) - 1) ;
+       dest [n - 1] = 0 ;
+} /* psf_strlcat */
+
+void
+psf_strlcpy (char *dest, size_t n, const char *src)
+{      strncpy (dest, src, n - 1) ;
+       dest [n - 1] = 0 ;
+} /* psf_strlcpy */
+
+/*========================================================================================
+*/
+
+void *
+psf_memdup (const void *src, size_t n)
+{      if (src == NULL)
+               return NULL ;
+
+       void * mem = calloc (1, n & 3 ? n + 4 - (n & 3) : n) ;
+       if (mem != NULL)
+               memcpy (mem, src, n) ;
+       return mem ;
+} /* psf_memdup */
+
 void*
 psf_memset (void *s, int c, sf_count_t len)
 {      char    *ptr ;
@@ -1246,7 +1301,11 @@ psf_memset (void *s, int c, sf_count_t len)
 ** bodgy something up instead.
 */
 
+#ifdef _MSC_VER
 typedef SF_CUES_VAR (0) SF_CUES_0 ;
+#else
+typedef SF_CUES_VAR () SF_CUES_0 ;
+#endif
 
 /* calculate size of SF_CUES struct given number of cues */
 #define SF_CUES_VAR_SIZE(count)        (sizeof (SF_CUES_0) + count * sizeof (SF_CUE_POINT))
@@ -1257,8 +1316,9 @@ typedef SF_CUES_VAR (0) SF_CUES_0 ;
 SF_CUES *
 psf_cues_alloc (uint32_t cue_count)
 {      SF_CUES *pcues = calloc (1, SF_CUES_VAR_SIZE (cue_count)) ;
-
-       pcues->cue_count = cue_count ;
+       if (pcues)
+       {       pcues->cue_count = cue_count ;
+               } ;
        return pcues ;
 } /* psf_cues_alloc */
 
@@ -1527,6 +1587,7 @@ str_of_major_format (int format)
                CASE_NAME (SF_FORMAT_CAF) ;
                CASE_NAME (SF_FORMAT_WVE) ;
                CASE_NAME (SF_FORMAT_OGG) ;
+               CASE_NAME (SF_FORMAT_MPEG) ;
                default :
                        break ;
                } ;
@@ -1563,6 +1624,9 @@ str_of_minor_format (int format)
                CASE_NAME (SF_FORMAT_DPCM_8) ;
                CASE_NAME (SF_FORMAT_DPCM_16) ;
                CASE_NAME (SF_FORMAT_VORBIS) ;
+               CASE_NAME (SF_FORMAT_MPEG_LAYER_I) ;
+               CASE_NAME (SF_FORMAT_MPEG_LAYER_II) ;
+               CASE_NAME (SF_FORMAT_MPEG_LAYER_III) ;
                default :
                        break ;
                } ;
@@ -1606,8 +1670,8 @@ psf_f2s_array (const float *src, short *dest, int count, int normalize)
 {      float                   normfact ;
 
        normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
-       while (--count >= 0)
-               dest [count] = psf_lrintf (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+               dest [i] = psf_lrintf (src [i] * normfact) ;
 
        return ;
 } /* psf_f2s_array */
@@ -1618,18 +1682,22 @@ psf_f2s_clip_array (const float *src, short *dest, int count, int normalize)
 
        normfact = normalize ? (1.0 * 0x8000) : 1.0 ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFF))
-               {       dest [count] = 0x7FFF ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFF))
+               {       dest [i] = 0x7FFF ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x1000))
-               {       dest [count] = 0x8000 ;
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x1000))
+               {       dest [i] = -0x7FFF - 1 ;
                        continue ;
                        } ;
+#endif
 
-               dest [count] = psf_lrintf (scaled_value) ;
+               dest [i] = psf_lrintf (scaled_value) ;
                } ;
 
        return ;
@@ -1640,8 +1708,8 @@ psf_d2s_array (const double *src, short *dest, int count, int normalize)
 {      double                  normfact ;
 
        normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
-       while (--count >= 0)
-               dest [count] = psf_lrint (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+               dest [i] = psf_lrint (src [i] * normfact) ;
 
        return ;
 } /* psf_f2s_array */
@@ -1652,18 +1720,22 @@ psf_d2s_clip_array (const double *src, short *dest, int count, int normalize)
 
        normfact = normalize ? (1.0 * 0x8000) : 1.0 ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFF))
-               {       dest [count] = 0x7FFF ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFF))
+               {       dest [i] = 0x7FFF ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x1000))
-               {       dest [count] = 0x8000 ;
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x1000))
+               {       dest [i] = -0x7FFF - 1 ;
                        continue ;
                        } ;
+#endif
 
-               dest [count] = psf_lrint (scaled_value) ;
+               dest [i] = psf_lrint (scaled_value) ;
                } ;
 
        return ;
@@ -1675,8 +1747,8 @@ psf_f2i_array (const float *src, int *dest, int count, int normalize)
 {      float                   normfact ;
 
        normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
-       while (--count >= 0)
-               dest [count] = psf_lrintf (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+               dest [i] = psf_lrintf (src [i] * normfact) ;
 
        return ;
 } /* psf_f2i_array */
@@ -1687,18 +1759,22 @@ psf_f2i_clip_array (const float *src, int *dest, int count, int normalize)
 
        normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
-               {       dest [count] = 0x7FFFFFFF ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       dest [i] = 0x7FFFFFFF ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
-               {       dest [count] = 0x80000000 ;
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
+               {       dest [i] = 0x80000000 ;
                        continue ;
                        } ;
+#endif
 
-               dest [count] = psf_lrintf (scaled_value) ;
+               dest [i] = psf_lrintf (scaled_value) ;
                } ;
 
        return ;
@@ -1709,8 +1785,8 @@ psf_d2i_array (const double *src, int *dest, int count, int normalize)
 {      double                  normfact ;
 
        normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
-       while (--count >= 0)
-               dest [count] = psf_lrint (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+               dest [i] = psf_lrint (src [i] * normfact) ;
 
        return ;
 } /* psf_f2i_array */
@@ -1721,18 +1797,22 @@ psf_d2i_clip_array (const double *src, int *dest, int count, int normalize)
 
        normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
-               {       dest [count] = 0x7FFFFFFF ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       dest [i] = 0x7FFFFFFF ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
-               {       dest [count] = 0x80000000 ;
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
+               {       dest [i] = 0x80000000 ;
                        continue ;
                        } ;
+#endif
 
-               dest [count] = psf_lrint (scaled_value) ;
+               dest [i] = psf_lrint (scaled_value) ;
                } ;
 
        return ;
index 08360d0..6ca0648 100644 (file)
@@ -23,6 +23,9 @@
 
 #include <stdlib.h>
 #include <string.h>
+#if HAVE_STDBOOL_H
+#include <stdbool.h>
+#endif
 
 #if HAVE_INTTYPES_H
 #include <inttypes.h>
 
 #define                ARRAY_LEN(x)    ((int) (sizeof (x) / sizeof ((x) [0])))
 
-#define                NOT(x)                  (! (x))
-
-#if COMPILER_IS_GCC
-#define                SF_MAX(x, y)    ({ \
-                                                               typeof (x) sf_max_x1 = (x) ; \
-                                                               typeof (y) sf_max_y1 = (y) ; \
-                                                               (void) (&sf_max_x1 == &sf_max_y1) ; \
-                                                               sf_max_x1 > sf_max_y1 ? sf_max_x1 : sf_max_y1 ; })
-
-#define                SF_MIN(x, y)    ({ \
-                                                               typeof (x) sf_min_x2 = (x) ; \
-                                                               typeof (y) sf_min_y2 = (y) ; \
-                                                               (void) (&sf_min_x2 == &sf_min_y2) ; \
-                                                               sf_min_x2 < sf_min_y2 ? sf_min_x2 : sf_min_y2 ; })
-#else
 #define                SF_MAX(a, b)    ((a) > (b) ? (a) : (b))
 #define                SF_MIN(a, b)    ((a) < (b) ? (a) : (b))
-#endif
 
 
 #define                COMPILE_TIME_ASSERT(e)  (sizeof (struct { int : - !! (e) ; }))
 
 
 #define                SF_MAX_CHANNELS         1024
+/* Max FLAC sample rate : https://xiph.org/flac/format.html */
+#define                SF_MAX_SAMPLERATE       655350
 
 
 /*
@@ -307,6 +296,12 @@ typedef SF_BROADCAST_INFO_VAR (16 * 1024) SF_BROADCAST_INFO_16K ;
 
 typedef SF_CART_INFO_VAR (16 * 1024) SF_CART_INFO_16K ;
 
+typedef struct
+{      sf_count_t      offset ;
+       sf_count_t      len ;
+       unsigned        minor_version ;
+} ID3V2_HEADER_INFO ;
+
 #if SIZEOF_WCHAR_T == 2
 typedef wchar_t        sfwchar_t ;
 #else
@@ -314,20 +309,13 @@ typedef int16_t sfwchar_t ;
 #endif
 
 
-static inline void *
-psf_memdup (const void *src, size_t n)
-{      void * mem = calloc (1, n & 3 ? n + 4 - (n & 3) : n) ;
-       return memcpy (mem, src, n) ;
-} /* psf_memdup */
+void *psf_memdup (const void *src, size_t n) ;
 
 /*
 **     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 */
+int psf_isprint (int ch) ;
 
 /*=======================================================================================
 **     SF_PRIVATE stuct - a pointer to this struct is passed back to the caller of the
@@ -337,36 +325,23 @@ psf_isprint (int ch)
 
 typedef struct
 {
-       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 ;
+       char    path [SF_FILENAME_LEN] ;
+       char    dir [SF_FILENAME_LEN] ;
+       char    name [SF_FILENAME_LEN / 4] ;
 
 #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 ;
+       void    *handle, *hsaved ;
 #else
        /* These fields can only be used in src/file_io.c. */
-       int                     filedes, savedes ;
+       int     filedes, savedes ;
 #endif
 
-       int                             do_not_close_descriptor ;
-       int                             mode ;                  /* Open mode : SFM_READ, SFM_WRITE or SFM_RDWR. */
+       int             do_not_close_descriptor ;
+       int             mode ;                  /* Open mode : SFM_READ, SFM_WRITE or SFM_RDWR. */
 } PSF_FILE ;
 
 
@@ -390,13 +365,6 @@ typedef union
 
 typedef struct sf_private_tag
 {
-       /* Canary in a coal mine. */
-       union
-       {       /* Place a double here to encourage double alignment. */
-               double d [2] ;
-               char c [16] ;
-               } canary ;
-
        PSF_FILE                file, rsrc ;
 
        char                    syserr          [SF_SYSERR_LEN] ;
@@ -554,6 +522,8 @@ typedef struct sf_private_tag
        int                                     (*get_chunk_data)       (struct sf_private_tag*, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) ;
 
        int cpu_flags ;
+
+       ID3V2_HEADER_INFO       id3_header ;
 } SF_PRIVATE ;
 
 
@@ -768,6 +738,17 @@ enum
 
        SFE_OPUS_BAD_SAMPLERATE,
 
+       SFE_CAF_NOT_CAF,
+       SFE_CAF_NO_DESC,
+       SFE_CAF_BAD_PEAK,
+
+       SFE_AVR_NOT_AVR,
+       SFE_AVR_BAD_REZ_SIGN,
+
+       SFE_MPC_NO_MARKER,
+
+       SFE_MPEG_BAD_SAMPLERATE,
+
        SFE_MAX_ERROR                   /* This must be last in list. */
 } ;
 
@@ -883,6 +864,8 @@ int psf_fclose (SF_PRIVATE *psf) ;
 int psf_open_rsrc (SF_PRIVATE *psf) ;
 int psf_close_rsrc (SF_PRIVATE *psf) ;
 
+int    psf_copy_filename (SF_PRIVATE *psf, const char *path) ;
+
 /*
 void psf_fclearerr (SF_PRIVATE *psf) ;
 int psf_ferror (SF_PRIVATE *psf) ;
@@ -921,10 +904,10 @@ int               ogg_pcm_open    (SF_PRIVATE *psf) ;
 int            ogg_opus_open   (SF_PRIVATE *psf) ;
 int            ogg_open        (SF_PRIVATE *psf) ;
 
+int            mpeg_open       (SF_PRIVATE *psf) ;
 
 /* In progress. Do not currently work. */
 
-int            mpeg_open       (SF_PRIVATE *psf) ;
 int            rx2_open        (SF_PRIVATE *psf) ;
 int            txw_open        (SF_PRIVATE *psf) ;
 int            wve_open        (SF_PRIVATE *psf) ;
@@ -946,6 +929,7 @@ int         vox_adpcm_init  (SF_PRIVATE *psf) ;
 int            flac_init               (SF_PRIVATE *psf) ;
 int            g72x_init               (SF_PRIVATE * psf) ;
 int            alac_init               (SF_PRIVATE *psf, const ALAC_DECODER_INFO * info) ;
+int            mpeg_init               (SF_PRIVATE *psf, int bitrate_mode, int write_metadata) ;
 
 int    dither_init             (SF_PRIVATE *psf, int mode) ;
 
@@ -971,17 +955,6 @@ int                psf_find_read_chunk_iterator (const READ_CHUNKS * pchk, const SF_CHUNK_ITER
 
 int            psf_find_write_chunk (WRITE_CHUNKS * pchk, const char * marker) ;
 
-static inline int
-fourcc_to_marker (const SF_CHUNK_INFO * chunk_info)
-{      const unsigned char * cptr ;
-
-       if (chunk_info->id_size != 4)
-               return 0 ;
-
-       cptr = (const unsigned char *) chunk_info->id ;
-       return (cptr [3] << 24) + (cptr [2] << 16) + (cptr [1] << 8) + cptr [0] ;
-} /* fourcc_to_marker */
-
 /*------------------------------------------------------------------------------------
 ** Functions that work like OpenBSD's strlcpy/strlcat to replace strncpy/strncat.
 **
@@ -994,17 +967,8 @@ fourcc_to_marker (const SF_CHUNK_INFO * chunk_info)
 ** 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 */
+void psf_strlcat (char *dest, size_t n, const char *src) ;
+void psf_strlcpy (char *dest, size_t n, const char *src) ;
 
 /*------------------------------------------------------------------------------------
 ** SIMD optimized math functions.
@@ -1061,6 +1025,7 @@ typedef struct
 
 int audio_detect (SF_PRIVATE * psf, AUDIO_DETECT *ad, const unsigned char * data, int datalen) ;
 int id3_skip (SF_PRIVATE * psf) ;
+const char *id3_lookup_v1_genre (int number) ;
 
 void   alac_get_desc_chunk_items (int subformat, uint32_t *fmt_flags, uint32_t *frames_per_packet) ;
 
index c33bcbc..2872e7d 100644 (file)
@@ -43,6 +43,9 @@
 /* Will be set to 1 if flac, ogg and vorbis are available. */
 #cmakedefine01 HAVE_EXTERNAL_XIPH_LIBS
 
+/* Will be set to 1 if lame and mpg123 are available. */
+#cmakedefine01 HAVE_MPEG
+
 /* Define to 1 if you have the `floor' function. */
 #cmakedefine01 HAVE_FLOOR
 
 /* Define to 1 if you have the <immintrin.h> header file. */
 #cmakedefine01 HAVE_IMMINTRIN_H
 
+/* Define to 1 if you have the <stdbool.h> header file. */
+#cmakedefine01 HAVE_STDBOOL_H
+
 /* Define to 1 if you have the `vsnprintf' function. */
 #cmakedefine01 HAVE_VSNPRINTF
 
index a36705e..b0ef731 100644 (file)
@@ -242,7 +242,7 @@ dither_write_short  (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
 
                dither_short (ptr, (short*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
 
-               thiswrite = pdither->write_short (psf, (short*) pdither->buffer, writecount) ;
+               thiswrite = (int) pdither->write_short (psf, (short*) pdither->buffer, writecount) ;
                total += thiswrite ;
                len -= thiswrite ;
                if (thiswrite < writecount)
@@ -288,7 +288,7 @@ dither_write_int    (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
 
                dither_int (ptr, (int*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
 
-               thiswrite = pdither->write_int (psf, (int*) pdither->buffer, writecount) ;
+               thiswrite = (int) pdither->write_int (psf, (int*) pdither->buffer, writecount) ;
                total += thiswrite ;
                len -= thiswrite ;
                if (thiswrite < writecount)
@@ -327,13 +327,13 @@ dither_write_float        (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        bufferlen = sizeof (pdither->buffer) / (sizeof (float)) ;
 
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : (float) len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                writecount /= psf->sf.channels ;
                writecount *= psf->sf.channels ;
 
                dither_float (ptr, (float*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
 
-               thiswrite = pdither->write_float (psf, (float*) pdither->buffer, writecount) ;
+               thiswrite = (int) pdither->write_float (psf, (float*) pdither->buffer, writecount) ;
                total += thiswrite ;
                len -= thiswrite ;
                if (thiswrite < writecount)
@@ -373,13 +373,13 @@ dither_write_double       (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        bufferlen = sizeof (pdither->buffer) / sizeof (double) ;
 
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : (double) len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                writecount /= psf->sf.channels ;
                writecount *= psf->sf.channels ;
 
                dither_double (ptr, (double*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
 
-               thiswrite = pdither->write_double (psf, (double*) pdither->buffer, writecount) ;
+               thiswrite = (int) pdither->write_double (psf, (double*) pdither->buffer, writecount) ;
                total += thiswrite ;
                len -= thiswrite ;
                if (thiswrite < writecount)
index fb6d468..df49a8f 100644 (file)
@@ -486,71 +486,71 @@ double64_get_capability   (SF_PRIVATE *psf)
 
 static void
 d2s_array (const double *src, int count, short *dest, double scale)
-{      while (--count >= 0)
-       {       dest [count] = psf_lrint (scale * src [count]) ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = psf_lrint (scale * src [i]) ;
                } ;
 } /* d2s_array */
 
 static void
 d2s_clip_array (const double *src, int count, short *dest, double scale)
-{      while (--count >= 0)
-       {       double tmp = scale * src [count] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       double tmp = scale * src [i] ;
 
                if (CPU_CLIPS_POSITIVE == 0 && tmp > 32767.0)
-                       dest [count] = SHRT_MAX ;
+                       dest [i] = SHRT_MAX ;
                else if (CPU_CLIPS_NEGATIVE == 0 && tmp < -32768.0)
-                       dest [count] = SHRT_MIN ;
+                       dest [i] = SHRT_MIN ;
                else
-                       dest [count] = psf_lrint (tmp) ;
+                       dest [i] = psf_lrint (tmp) ;
                } ;
 } /* d2s_clip_array */
 
 static void
 d2i_array (const double *src, int count, int *dest, double scale)
-{      while (--count >= 0)
-       {       dest [count] = psf_lrint (scale * src [count]) ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = psf_lrint (scale * src [i]) ;
                } ;
 } /* d2i_array */
 
 static void
 d2i_clip_array (const double *src, int count, int *dest, double scale)
-{      while (--count >= 0)
-       {       float tmp = scale * src [count] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       float tmp = scale * src [i] ;
 
                if (CPU_CLIPS_POSITIVE == 0 && tmp > (1.0 * INT_MAX))
-                       dest [count] = INT_MAX ;
+                       dest [i] = INT_MAX ;
                else if (CPU_CLIPS_NEGATIVE == 0 && tmp < (-1.0 * INT_MAX))
-                       dest [count] = INT_MIN ;
+                       dest [i] = INT_MIN ;
                else
-                       dest [count] = psf_lrint (tmp) ;
+                       dest [i] = psf_lrint (tmp) ;
                } ;
 } /* d2i_clip_array */
 
 static inline void
 d2f_array (const double *src, int count, float *dest)
-{      while (--count >= 0)
-       {       dest [count] = src [count] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = src [i] ;
                } ;
 } /* d2f_array */
 
 static inline void
 s2d_array (const short *src, double *dest, int count, double scale)
-{      while (--count >= 0)
-       {       dest [count] = scale * src [count] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = scale * src [i] ;
                } ;
 } /* s2d_array */
 
 static inline void
 i2d_array (const int *src, double *dest, int count, double scale)
-{      while (--count >= 0)
-       {       dest [count] = scale * src [count] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = scale * src [i] ;
                } ;
 } /* i2d_array */
 
 static inline void
 f2d_array (const float *src, double *dest, int count)
-{      while (--count >= 0)
-       {       dest [count] = src [count] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = src [i] ;
                } ;
 } /* f2d_array */
 
@@ -572,7 +572,7 @@ host_read_d2s       (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
 
                if (psf->data_endswap == SF_TRUE)
                        endswap_double_array (ubuf.dbuf, readcount) ;
@@ -602,7 +602,7 @@ host_read_d2i       (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
 
                if (psf->data_endswap == SF_TRUE)
                        endswap_double_array (ubuf.dbuf, bufferlen) ;
@@ -628,7 +628,7 @@ host_read_d2f       (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
 
                if (psf->data_endswap == SF_TRUE)
                        endswap_double_array (ubuf.dbuf, readcount) ;
@@ -695,7 +695,7 @@ host_write_s2d      (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
                if (psf->data_endswap == SF_TRUE)
                        endswap_double_array (ubuf.dbuf, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -726,7 +726,7 @@ host_write_i2d      (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
                if (psf->data_endswap == SF_TRUE)
                        endswap_double_array (ubuf.dbuf, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -755,7 +755,7 @@ host_write_f2d      (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
                if (psf->data_endswap == SF_TRUE)
                        endswap_double_array (ubuf.dbuf, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -785,7 +785,7 @@ host_write_d        (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
 
                endswap_double_copy (ubuf.dbuf, ptr + total, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -811,7 +811,7 @@ replace_read_d2s    (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
 
                if (psf->data_endswap == SF_TRUE)
                        endswap_double_array (ubuf.dbuf, bufferlen) ;
@@ -841,7 +841,7 @@ replace_read_d2i    (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
 
                if (psf->data_endswap == SF_TRUE)
                        endswap_double_array (ubuf.dbuf, bufferlen) ;
@@ -869,7 +869,7 @@ replace_read_d2f    (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
 
                if (psf->data_endswap == SF_TRUE)
                        endswap_double_array (ubuf.dbuf, bufferlen) ;
@@ -899,7 +899,7 @@ replace_read_d      (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
 
                if (psf->data_endswap == SF_TRUE)
                        endswap_double_array (ubuf.dbuf, readcount) ;
@@ -940,7 +940,7 @@ replace_write_s2d   (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
                if (psf->data_endswap == SF_TRUE)
                        endswap_double_array (ubuf.dbuf, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -973,7 +973,7 @@ replace_write_i2d   (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
                if (psf->data_endswap == SF_TRUE)
                        endswap_double_array (ubuf.dbuf, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1001,7 +1001,7 @@ replace_write_f2d (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
                if (psf->data_endswap == SF_TRUE)
                        endswap_double_array (ubuf.dbuf, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1034,7 +1034,7 @@ replace_write_d   (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
                if (psf->data_endswap == SF_TRUE)
                        endswap_double_array (ubuf.dbuf, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1049,15 +1049,15 @@ replace_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
 
 static void
 d2bd_read (double *buffer, int count)
-{      while (--count >= 0)
-       {       buffer [count] = DOUBLE64_READ ((unsigned char *) (buffer + count)) ;
+{      for (int i = 0 ; i < count ; i++)
+       {       buffer [i] = DOUBLE64_READ ((unsigned char *) &buffer [i]) ;
                } ;
 } /* d2bd_read */
 
 static void
 bd2d_write (double *buffer, int count)
-{      while (--count >= 0)
-       {       DOUBLE64_WRITE (buffer [count], (unsigned char*) (buffer + count)) ;
+{      for (int i = 0 ; i < count ; i++)
+       {       DOUBLE64_WRITE (buffer [i], (unsigned char*) &buffer [i]) ;
                } ;
 } /* bd2d_write */
 
index af4d9f0..a15750d 100644 (file)
--- a/src/dwd.c
+++ b/src/dwd.c
@@ -115,9 +115,9 @@ dwd_close   (SF_PRIVATE * UNUSED (psf))
 ** No assumptions are made about the packing of this struct.
 */
 typedef struct
-{      unsigned char major, minor, compression, channels, bitwidth ;
-       unsigned short srate, maxval ;
-       unsigned int id, datalen, frames, offset ;
+{      uint8_t major, minor, compression, channels, bitwidth ;
+       uint16_t srate, maxval ;
+       uint32_t id, datalen, frames, offset ;
 } DWD_HEADER ;
 
 static int
@@ -173,7 +173,7 @@ dwd_read_header (SF_PRIVATE *psf)
 
        if (psf->filelength != dwdh.offset + dwdh.datalen)
        {       psf_log_printf (psf, "  Data Length   : %d (should be %D)\n", dwdh.datalen, psf->filelength - dwdh.offset) ;
-               dwdh.datalen = (unsigned int) (psf->filelength - dwdh.offset) ;
+               dwdh.datalen = (uint32_t) (psf->filelength - dwdh.offset) ;
                }
        else
                psf_log_printf (psf, "  Data Length   : %d\n", dwdh.datalen) ;
index 13985ad..a015fce 100644 (file)
@@ -198,7 +198,7 @@ dwvw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = iptr [k] >> 16 ;
@@ -255,7 +255,7 @@ dwvw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = normfact * (float) (iptr [k]) ;
@@ -287,7 +287,7 @@ dwvw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = normfact * (double) (iptr [k]) ;
@@ -377,7 +377,7 @@ dwvw_decode_load_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int bit_count)
        /* Load bits in bit reseviour. */
        while (pdwvw->bit_count < bit_count)
        {       if (pdwvw->b.index >= pdwvw->b.end)
-               {       pdwvw->b.end = psf_fread (pdwvw->b.buffer, 1, sizeof (pdwvw->b.buffer), psf) ;
+               {       pdwvw->b.end = (int) psf_fread (pdwvw->b.buffer, 1, sizeof (pdwvw->b.buffer), psf) ;
                        pdwvw->b.index = 0 ;
                        } ;
 
@@ -569,7 +569,7 @@ dwvw_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        iptr [k] = arith_shift_left (ptr [total + k], 16) ;
                count = dwvw_encode_data (psf, pdwvw, iptr, writecount) ;
@@ -626,7 +626,7 @@ dwvw_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        iptr [k] = psf_lrintf (normfact * ptr [total + k]) ;
                count = dwvw_encode_data (psf, pdwvw, iptr, writecount) ;
@@ -658,7 +658,7 @@ dwvw_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        iptr [k] = psf_lrint (normfact * ptr [total + k]) ;
                count = dwvw_encode_data (psf, pdwvw, iptr, writecount) ;
index 9cd9379..334ba2a 100644 (file)
 
 static void psf_log_syserr (SF_PRIVATE *psf, int error) ;
 
+int
+psf_copy_filename (SF_PRIVATE *psf, const char *path)
+{      const char *ccptr ;
+       char *cptr ;
+
+       if (strlen (path) > 1 && strlen (path) - 1 >= sizeof (psf->file.path))
+       {       psf->error = SFE_FILENAME_TOO_LONG ;
+               return psf->error ;
+               } ;
+
+       snprintf (psf->file.path, sizeof (psf->file.path), "%s", path) ;
+       if ((ccptr = strrchr (path, '/')) || (ccptr = strrchr (path, '\\')))
+               ccptr ++ ;
+       else
+               ccptr = path ;
+
+       snprintf (psf->file.name, sizeof (psf->file.name), "%s", ccptr) ;
+
+       /* Now grab the directory. */
+       snprintf (psf->file.dir, sizeof (psf->file.dir), "%s", path) ;
+       if ((cptr = strrchr (psf->file.dir, '/')) || (cptr = strrchr (psf->file.dir, '\\')))
+               cptr [1] = 0 ;
+       else
+               psf->file.dir [0] = 0 ;
+
+       return 0 ;
+} /* psf_copy_filename */
+
 #if (USE_WINDOWS_API == 0)
 
 /*------------------------------------------------------------------------------
@@ -132,9 +160,9 @@ psf_open_rsrc (SF_PRIVATE *psf)
                return 0 ;
 
        /* Test for MacOSX style resource fork on HPFS or HPFS+ filesystems. */
-       count = snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s/..namedfork/rsrc", psf->file.path.c) ;
+       count = snprintf (psf->rsrc.path, sizeof (psf->rsrc.path), "%s/..namedfork/rsrc", psf->file.path) ;
        psf->error = SFE_NO_ERROR ;
-       if (count < sizeof (psf->rsrc.path.c))
+       if (count < sizeof (psf->rsrc.path))
        {       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))
@@ -153,9 +181,9 @@ psf_open_rsrc (SF_PRIVATE *psf)
        ** Now try for a resource fork stored as a separate file in the same
        ** directory, but preceded with a dot underscore.
        */
-       count = snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s._%s", psf->file.dir.c, psf->file.name.c) ;
+       count = snprintf (psf->rsrc.path, sizeof (psf->rsrc.path), "%s._%s", psf->file.dir, psf->file.name) ;
        psf->error = SFE_NO_ERROR ;
-       if (count < sizeof (psf->rsrc.path.c) && (psf->rsrc.filedes = psf_open_fd (&psf->rsrc)) >= 0)
+       if (count < sizeof (psf->rsrc.path) && (psf->rsrc.filedes = psf_open_fd (&psf->rsrc)) >= 0)
        {       psf->rsrclength = psf_get_filelen_fd (psf->rsrc.filedes) ;
                return SFE_NO_ERROR ;
                } ;
@@ -164,9 +192,9 @@ psf_open_rsrc (SF_PRIVATE *psf)
        ** Now try for a resource fork stored in a separate file in the
        ** .AppleDouble/ directory.
        */
-       count = snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s.AppleDouble/%s", psf->file.dir.c, psf->file.name.c) ;
+       count = snprintf (psf->rsrc.path, sizeof (psf->rsrc.path), "%s.AppleDouble/%s", psf->file.dir, psf->file.name) ;
        psf->error = SFE_NO_ERROR ;
-       if (count < sizeof (psf->rsrc.path.c))
+       if (count < sizeof (psf->rsrc.path))
        {       if ((psf->rsrc.filedes = psf_open_fd (&psf->rsrc)) >= 0)
                {       psf->rsrclength = psf_get_filelen_fd (psf->rsrc.filedes) ;
                        return SFE_NO_ERROR ;
@@ -572,9 +600,9 @@ psf_open_fd (PSF_FILE * pfile)
                } ;
 
        if (mode == 0)
-               fd = open (pfile->path.c, oflag) ;
+               fd = open (pfile->path, oflag) ;
        else
-               fd = open (pfile->path.c, oflag, mode) ;
+               fd = open (pfile->path, oflag, mode) ;
 
        return fd ;
 } /* psf_open_fd */
@@ -602,7 +630,7 @@ psf_fsync (SF_PRIVATE *psf)
 #endif
 } /* psf_fsync */
 
-#elif  USE_WINDOWS_API
+#else
 
 /* Win32 file i/o functions implemented using native Win32 API */
 
@@ -620,7 +648,7 @@ psf_fopen (SF_PRIVATE *psf)
        psf->error = 0 ;
        psf->file.handle = psf_open_handle (&psf->file) ;
 
-       if (psf->file.handle == NULL)
+       if (psf->file.handle == INVALID_HANDLE_VALUE)
                psf_log_syserr (psf, GetLastError ()) ;
 
        return psf->error ;
@@ -634,14 +662,14 @@ psf_fclose (SF_PRIVATE *psf)
                return 0 ;
 
        if (psf->file.do_not_close_descriptor)
-       {       psf->file.handle = NULL ;
+       {       psf->file.handle = INVALID_HANDLE_VALUE ;
                return 0 ;
                } ;
 
        if ((retval = psf_close_handle (psf->file.handle)) == -1)
                psf_log_syserr (psf, GetLastError ()) ;
 
-       psf->file.handle = NULL ;
+       psf->file.handle = INVALID_HANDLE_VALUE ;
 
        return retval ;
 } /* psf_fclose */
@@ -649,13 +677,13 @@ psf_fclose (SF_PRIVATE *psf)
 /* USE_WINDOWS_API */ int
 psf_open_rsrc (SF_PRIVATE *psf)
 {
-       if (psf->rsrc.handle != NULL)
+       if (psf->rsrc.handle != INVALID_HANDLE_VALUE)
                return 0 ;
 
        /* Test for MacOSX style resource fork on HPFS or HPFS+ filesystems. */
-       snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s/rsrc", psf->file.path.c) ;
+       snprintf (psf->rsrc.path, sizeof (psf->rsrc.path), "%s/rsrc", psf->file.path) ;
        psf->error = SFE_NO_ERROR ;
-       if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != NULL)
+       if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != INVALID_HANDLE_VALUE)
        {       psf->rsrclength = psf_get_filelen_handle (psf->rsrc.handle) ;
                return SFE_NO_ERROR ;
                } ;
@@ -664,9 +692,9 @@ psf_open_rsrc (SF_PRIVATE *psf)
        ** Now try for a resource fork stored as a separate file in the same
        ** directory, but preceded with a dot underscore.
        */
-       snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s._%s", psf->file.dir.c, psf->file.name.c) ;
+       snprintf (psf->rsrc.path, sizeof (psf->rsrc.path), "%s._%s", psf->file.dir, psf->file.name) ;
        psf->error = SFE_NO_ERROR ;
-       if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != NULL)
+       if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != INVALID_HANDLE_VALUE)
        {       psf->rsrclength = psf_get_filelen_handle (psf->rsrc.handle) ;
                return SFE_NO_ERROR ;
                } ;
@@ -675,19 +703,17 @@ psf_open_rsrc (SF_PRIVATE *psf)
        ** Now try for a resource fork stored in a separate file in the
        ** .AppleDouble/ directory.
        */
-       snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s.AppleDouble/%s", psf->file.dir.c, psf->file.name.c) ;
+       snprintf (psf->rsrc.path, sizeof (psf->rsrc.path), "%s.AppleDouble/%s", psf->file.dir, psf->file.name) ;
        psf->error = SFE_NO_ERROR ;
-       if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != NULL)
+       if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != INVALID_HANDLE_VALUE)
        {       psf->rsrclength = psf_get_filelen_handle (psf->rsrc.handle) ;
                return SFE_NO_ERROR ;
                } ;
 
        /* No resource file found. */
-       if (psf->rsrc.handle == NULL)
+       if (psf->rsrc.handle == INVALID_HANDLE_VALUE)
                psf_log_syserr (psf, GetLastError ()) ;
 
-       psf->rsrc.handle = NULL ;
-
        return psf->error ;
 } /* psf_open_rsrc */
 
@@ -738,9 +764,9 @@ psf_get_filelen (SF_PRIVATE *psf)
 
 /* USE_WINDOWS_API */ void
 psf_init_files (SF_PRIVATE *psf)
-{      psf->file.handle = NULL ;
-       psf->rsrc.handle = NULL ;
-       psf->file.hsaved = NULL ;
+{      psf->file.handle = INVALID_HANDLE_VALUE ;
+       psf->rsrc.handle = INVALID_HANDLE_VALUE ;
+       psf->file.hsaved = INVALID_HANDLE_VALUE ;
 } /* psf_init_files */
 
 /* USE_WINDOWS_API */ void
@@ -764,6 +790,7 @@ psf_open_handle (PSF_FILE * pfile)
        DWORD dwShareMode ;
        DWORD dwCreationDistribution ;
        HANDLE handle ;
+       LPWSTR pwszPath = NULL ;
 
        switch (pfile->mode)
        {       case SFM_READ :
@@ -785,50 +812,43 @@ psf_open_handle (PSF_FILE * pfile)
                                break ;
 
                default :
-                               return NULL ;
+                               return INVALID_HANDLE_VALUE ;
+               } ;
+
+       int nResult = MultiByteToWideChar (CP_UTF8, 0, pfile->path, -1, NULL, 0) ;
+       pwszPath = malloc (nResult * sizeof (WCHAR)) ;
+       if (!pwszPath)
+               return INVALID_HANDLE_VALUE ;
+       
+       int nResult2 = MultiByteToWideChar (CP_UTF8, 0, pfile->path, -1, pwszPath, nResult) ;
+       if (nResult != nResult2)
+       {       free (pwszPath) ;
+               return INVALID_HANDLE_VALUE ;
                } ;
 
 #if defined (WINAPI_FAMILY_PARTITION) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM)
        if (!pfile->use_wchar)
-               return NULL ;
+               return INVALID_HANDLE_VALUE ;
 
        CREATEFILE2_EXTENDED_PARAMETERS cfParams = { 0 } ;
        cfParams.dwSize = sizeof (CREATEFILE2_EXTENDED_PARAMETERS) ;
        cfParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL ;
 
-       handle = CreateFile2 (pfile->path.wc, dwDesiredAccess, dwShareMode, dwCreationDistribution, &cfParams) ;
-
-       if (handle == INVALID_HANDLE_VALUE)
-               return NULL ;
-
-       return handle ;
+       handle = CreateFile2 (pwszPath, dwDesiredAccess, dwShareMode, dwCreationDistribution, &cfParams) ;
 #else
-       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 = CreateFileA (
-                                       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 ;
+       handle = CreateFileW (
+                               pwszPath,                                       /* 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 */
+                               ) ;
+#endif
+       free (pwszPath) ;
 
        return handle ;
-#endif
 } /* psf_open_handle */
 
 /* USE_WINDOWS_API */ static void
@@ -860,14 +880,14 @@ psf_log_syserr (SF_PRIVATE *psf, int error)
 /* USE_WINDOWS_API */ int
 psf_close_rsrc (SF_PRIVATE *psf)
 {      psf_close_handle (psf->rsrc.handle) ;
-       psf->rsrc.handle = NULL ;
+       psf->rsrc.handle = INVALID_HANDLE_VALUE ;
        return 0 ;
 } /* psf_close_rsrc */
 
 
 /* USE_WINDOWS_API */ int
 psf_set_stdio (SF_PRIVATE *psf)
-{      HANDLE  handle = NULL ;
+{      HANDLE  handle = INVALID_HANDLE_VALUE ;
        int     error = 0 ;
 
        switch (psf->file.mode)
@@ -909,9 +929,7 @@ psf_set_file (SF_PRIVATE *psf, int fd)
 
 /* USE_WINDOWS_API */ int
 psf_file_valid (SF_PRIVATE *psf)
-{      if (psf->file.handle == NULL)
-               return SF_FALSE ;
-       if (psf->file.handle == INVALID_HANDLE_VALUE)
+{      if (psf->file.handle == INVALID_HANDLE_VALUE)
                return SF_FALSE ;
        return SF_TRUE ;
 } /* psf_set_file */
@@ -1073,7 +1091,7 @@ psf_ftell (SF_PRIVATE *psf)
 
 /* USE_WINDOWS_API */ static int
 psf_close_handle (HANDLE handle)
-{      if (handle == NULL)
+{      if (handle == INVALID_HANDLE_VALUE)
                return 0 ;
 
        if (CloseHandle (handle) == 0)
@@ -1187,386 +1205,5 @@ psf_ftruncate (SF_PRIVATE *psf, sf_count_t len)
        return retval ;
 } /* psf_ftruncate */
 
-
-#else
-/* Win32 file i/o functions implemented using Unix-style file i/o API */
-
-/* Win32 has a 64 file offset seek function:
-**
-**             __int64 _lseeki64 (int handle, __int64 offset, int origin) ;
-**
-** It also has a 64 bit fstat function:
-**
-**             int fstati64 (int, struct _stati64) ;
-**
-** but the fscking thing doesn't work!!!!! The file size parameter returned
-** by this function is only valid up until more data is written at the end of
-** the file. That makes this function completely 100% useless.
-*/
-
-#include <io.h>
-#include <direct.h>
-
-/* Win32 */ int
-psf_fopen (SF_PRIVATE *psf, const char *pathname, int open_mode)
-{      int oflag, mode ;
-
-       switch (open_mode)
-       {       case SFM_READ :
-                               oflag = O_RDONLY | O_BINARY ;
-                               mode = 0 ;
-                               break ;
-
-               case SFM_WRITE :
-                               oflag = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ;
-                               mode = S_IRUSR | S_IWUSR | S_IRGRP ;
-                               break ;
-
-               case SFM_RDWR :
-                               oflag = O_RDWR | O_CREAT | O_BINARY ;
-                               mode = S_IRUSR | S_IWUSR | S_IRGRP ;
-                               break ;
-
-               default :
-                               psf->error = SFE_BAD_OPEN_MODE ;
-                               return -1 ;
-                               break ;
-               } ;
-
-       if (mode == 0)
-               psf->file.filedes = open (pathname, oflag) ;
-       else
-               psf->file.filedes = open (pathname, oflag, mode) ;
-
-       if (psf->file.filedes == -1)
-               psf_log_syserr (psf, errno) ;
-
-       return psf->file.filedes ;
-} /* psf_fopen */
-
-/* Win32 */ sf_count_t
-psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence)
-{      sf_count_t      new_position ;
-
-       if (psf->virtual_io)
-               return psf->vio.seek (offset, whence, psf->vio_user_data) ;
-
-       switch (whence)
-       {       case SEEK_SET :
-                               offset += psf->fileoffset ;
-                               break ;
-
-               case SEEK_END :
-                               if (psf->file.mode == SFM_WRITE)
-                               {       new_position = _lseeki64 (psf->file.filedes, offset, whence) ;
-
-                                       if (new_position < 0)
-                                               psf_log_syserr (psf, errno) ;
-
-                                       return new_position - psf->fileoffset ;
-                                       } ;
-
-                               /* Transform SEEK_END into a SEEK_SET, ie find the file
-                               ** length add the requested offset (should be <= 0) to
-                               ** get the offset wrt the start of file.
-                               */
-                               whence = SEEK_SET ;
-                               offset = _lseeki64 (psf->file.filedes, 0, SEEK_END) + offset ;
-                               break ;
-
-               default :
-                               /* No need to do anything about SEEK_CUR. */
-                               break ;
-               } ;
-
-       /*
-       ** Bypass weird Win32-ism if necessary.
-       ** _lseeki64() returns an "invalid parameter" error if called with the
-       ** offset == 0 and whence == SEEK_CUR.
-       *** Use the _telli64() function instead.
-       */
-       if (offset == 0 && whence == SEEK_CUR)
-               new_position = _telli64 (psf->file.filedes) ;
-       else
-               new_position = _lseeki64 (psf->file.filedes, offset, whence) ;
-
-       if (new_position < 0)
-               psf_log_syserr (psf, errno) ;
-
-       new_position -= psf->fileoffset ;
-
-       return new_position ;
-} /* psf_fseek */
-
-/* Win32 */ sf_count_t
-psf_fread (void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
-{      sf_count_t total = 0 ;
-       ssize_t count ;
-
-       if (psf->virtual_io)
-               return psf->vio.read (ptr, bytes*items, psf->vio_user_data) / bytes ;
-
-       items *= bytes ;
-
-       /* Do this check after the multiplication above. */
-       if (items <= 0)
-               return 0 ;
-
-       while (items > 0)
-       {       /* Break the writes down to a sensible size. */
-               count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ;
-
-               count = read (psf->file.filedes, ((char*) ptr) + total, (size_t) count) ;
-
-               if (count == -1)
-               {       if (errno == EINTR)
-                               continue ;
-
-                       psf_log_syserr (psf, errno) ;
-                       break ;
-                       } ;
-
-               if (count == 0)
-                       break ;
-
-               total += count ;
-               items -= count ;
-               } ;
-
-       return total / bytes ;
-} /* psf_fread */
-
-/* Win32 */ sf_count_t
-psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
-{      sf_count_t total = 0 ;
-       ssize_t count ;
-
-       if (psf->virtual_io)
-               return psf->vio.write (ptr, bytes*items, psf->vio_user_data) / bytes ;
-
-       items *= bytes ;
-
-       /* Do this check after the multiplication above. */
-       if (items <= 0)
-               return 0 ;
-
-       while (items > 0)
-       {       /* Break the writes down to a sensible size. */
-               count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : items ;
-
-               count = write (psf->file.filedes, ((const char*) ptr) + total, count) ;
-
-               if (count == -1)
-               {       if (errno == EINTR)
-                               continue ;
-
-                       psf_log_syserr (psf, errno) ;
-                       break ;
-                       } ;
-
-               if (count == 0)
-                       break ;
-
-               total += count ;
-               items -= count ;
-               } ;
-
-       return total / bytes ;
-} /* psf_fwrite */
-
-/* Win32 */ sf_count_t
-psf_ftell (SF_PRIVATE *psf)
-{      sf_count_t pos ;
-
-       if (psf->virtual_io)
-               return psf->vio.tell (psf->vio_user_data) ;
-
-       pos = _telli64 (psf->file.filedes) ;
-
-       if (pos == ((sf_count_t) -1))
-       {       psf_log_syserr (psf, errno) ;
-               return -1 ;
-               } ;
-
-       return pos - psf->fileoffset ;
-} /* psf_ftell */
-
-/* Win32 */ int
-psf_fclose (SF_PRIVATE *psf)
-{      int retval ;
-
-       while ((retval = close (psf->file.filedes)) == -1 && errno == EINTR)
-               /* Do nothing. */ ;
-
-       if (retval == -1)
-               psf_log_syserr (psf, errno) ;
-
-       psf->file.filedes = -1 ;
-
-       return retval ;
-} /* psf_fclose */
-
-/* Win32 */ sf_count_t
-psf_fgets (char *buffer, sf_count_t bufsize, SF_PRIVATE *psf)
-{      sf_count_t      k = 0 ;
-       sf_count_t      count ;
-
-       while (k < bufsize - 1)
-       {       count = read (psf->file.filedes, &(buffer [k]), 1) ;
-
-               if (count == -1)
-               {       if (errno == EINTR)
-                               continue ;
-
-                       psf_log_syserr (psf, errno) ;
-                       break ;
-                       } ;
-
-               if (count == 0 || buffer [k++] == '\n')
-                       break ;
-               } ;
-
-       buffer [k] = 0 ;
-
-       return k ;
-} /* psf_fgets */
-
-/* Win32 */ int
-psf_is_pipe (SF_PRIVATE *psf)
-{      struct stat statbuf ;
-
-       if (psf->virtual_io)
-               return SF_FALSE ;
-
-       /* Not sure if this works. */
-       if (fstat (psf->file.filedes, &statbuf) == -1)
-       {       psf_log_syserr (psf, errno) ;
-               /* Default to maximum safety. */
-               return SF_TRUE ;
-               } ;
-
-       /* These macros are defined in Win32/unistd.h. */
-       if (S_ISFIFO (statbuf.st_mode) || S_ISSOCK (statbuf.st_mode))
-               return SF_TRUE ;
-
-       return SF_FALSE ;
-} /* psf_checkpipe */
-
-/* Win32 */ sf_count_t
-psf_get_filelen (SF_PRIVATE *psf)
-{
-#if 0
-       /*
-       ** Windoze is SOOOOO FUCKED!!!!!!!
-       ** This code should work but doesn't. Why?
-       ** Code below does work.
-       */
-       struct _stati64 statbuf ;
-
-       if (_fstati64 (psf->file.filedes, &statbuf))
-       {       psf_log_syserr (psf, errno) ;
-               return (sf_count_t) -1 ;
-               } ;
-
-       return statbuf.st_size ;
-#else
-       sf_count_t current, filelen ;
-
-       if (psf->virtual_io)
-               return psf->vio.get_filelen (psf->vio_user_data) ;
-
-       if ((current = _telli64 (psf->file.filedes)) < 0)
-       {       psf_log_syserr (psf, errno) ;
-               return (sf_count_t) -1 ;
-               } ;
-
-       /*
-       ** Lets face it, windoze if FUBAR!!!
-       **
-       ** For some reason, I have to call _lseeki64() TWICE to get to the
-       ** end of the file.
-       **
-       ** This might have been avoided if windows had implemented the POSIX
-       ** standard function fsync() but NO, that would have been too easy.
-       **
-       ** I am VERY close to saying that windoze will no longer be supported
-       ** by libsndfile and changing the license to GPL at the same time.
-       */
-
-       _lseeki64 (psf->file.filedes, 0, SEEK_END) ;
-
-       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->file.filedes, current, SEEK_SET) ;
-
-       switch (psf->file.mode)
-       {       case SFM_WRITE :
-                       filelen = filelen - psf->fileoffset ;
-                       break ;
-
-               case SFM_READ :
-                       if (psf->fileoffset > 0 && psf->filelength > 0)
-                               filelen = psf->filelength ;
-                       break ;
-
-               case SFM_RDWR :
-                       /*
-                       ** Cannot open embedded files SFM_RDWR so we don't need to
-                       ** subtract psf->fileoffset. We already have the answer we
-                       ** need.
-                       */
-                       break ;
-
-               default :
-                       filelen = 0 ;
-               } ;
-
-       return filelen ;
-#endif
-} /* psf_get_filelen */
-
-/* Win32 */ int
-psf_ftruncate (SF_PRIVATE *psf, sf_count_t len)
-{      int retval ;
-
-       /* Returns 0 on success, non-zero on failure. */
-       if (len < 0)
-               return 1 ;
-
-       /* The global village idiots at micorsoft decided to implement
-       ** nearly all the required 64 bit file offset functions except
-       ** for one, truncate. The fscking morons!
-       **
-       ** This is not 64 bit file offset clean. Somone needs to clean
-       ** this up.
-       */
-       if (len > 0x7FFFFFFF)
-               return -1 ;
-
-       retval = chsize (psf->file.filedes, len) ;
-
-       if (retval == -1)
-               psf_log_syserr (psf, errno) ;
-
-       return retval ;
-} /* psf_ftruncate */
-
-
-static void
-psf_log_syserr (SF_PRIVATE *psf, int error)
-{
-       /* Only log an error if no error has been set yet. */
-       if (psf->error == 0)
-       {       psf->error = SFE_SYSTEM ;
-               snprintf (psf->syserr, sizeof (psf->syserr), "System error : %s", strerror (error)) ;
-               } ;
-
-       return ;
-} /* psf_log_syserr */
-
 #endif
 
index 64d0172..8caf4fa 100644 (file)
@@ -127,39 +127,39 @@ static FLAC__StreamEncoderWriteStatus sf_flac_enc_write_callback (const FLAC__St
 
 static void
 s2flac8_array (const short *src, int32_t *dest, int count)
-{      while (--count >= 0)
-               dest [count] = src [count] >> 8 ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = src [i] >> 8 ;
 } /* s2flac8_array */
 
 static void
 s2flac16_array (const short *src, int32_t *dest, int count)
-{      while (--count >= 0)
-               dest [count] = src [count] ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = src [i] ;
 } /* s2flac16_array */
 
 static void
 s2flac24_array (const short *src, int32_t *dest, int count)
-{      while (--count >= 0)
-               dest [count] = src [count] << 8 ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = src [i] << 8 ;
 } /* s2flac24_array */
 
 static void
 i2flac8_array (const int *src, int32_t *dest, int count)
-{      while (--count >= 0)
-               dest [count] = src [count] >> 24 ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = src [i] >> 24 ;
 } /* i2flac8_array */
 
 static void
 i2flac16_array (const int *src, int32_t *dest, int count)
 {
-       while (--count >= 0)
-               dest [count] = src [count] >> 16 ;
+       for (int i = 0 ; i < count ; i++)
+               dest [i] = src [i] >> 16 ;
 } /* i2flac16_array */
 
 static void
 i2flac24_array (const int *src, int32_t *dest, int count)
-{      while (--count >= 0)
-               dest [count] = src [count] >> 8 ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = src [i] >> 8 ;
 } /* i2flac24_array */
 
 static sf_count_t
@@ -948,7 +948,11 @@ flac_read_loop (SF_PRIVATE *psf, unsigned len)
        /* Decode some more. */
        while (pflac->pos < pflac->len)
        {       if (FLAC__stream_decoder_process_single (pflac->fsd) == 0)
+               {       psf_log_printf (psf, "FLAC__stream_decoder_process_single returned false\n") ;
+                       /* Current frame is busted, so NULL the pointer. */
+                       pflac->frame = NULL ;
                        break ;
+                       } ;
                state = FLAC__stream_decoder_get_state (pflac->fsd) ;
                if (state >= FLAC__STREAM_DECODER_END_OF_STREAM)
                {       psf_log_printf (psf, "FLAC__stream_decoder_get_state returned %s\n", FLAC__StreamDecoderStateString [state]) ;
@@ -1176,17 +1180,17 @@ f2flac8_clip_array (const float *src, int32_t *dest, int count, int normalize)
 
        normfact = normalize ? (8.0 * 0x10) : 1.0 ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
                if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7F))
-               {       dest [count] = 0x7F ;
+               {       dest [i] = 0x7F ;
                        continue ;
                        } ;
                if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10))
-               {       dest [count] = -0x80 ;
+               {       dest [i] = -0x80 ;
                        continue ;
                        } ;
-               dest [count] = psf_lrintf (scaled_value) ;
+               dest [i] = psf_lrintf (scaled_value) ;
                } ;
 
        return ;
@@ -1198,17 +1202,17 @@ f2flac16_clip_array (const float *src, int32_t *dest, int count, int normalize)
 
        normfact = normalize ? (8.0 * 0x1000) : 1.0 ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
                if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFF))
-               {       dest [count] = 0x7FFF ;
+               {       dest [i] = 0x7FFF ;
                        continue ;
                        } ;
                if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x1000))
-               {       dest [count] = -0x8000 ;
+               {       dest [i] = -0x8000 ;
                        continue ;
                        } ;
-               dest [count] = psf_lrintf (scaled_value) ;
+               dest [i] = psf_lrintf (scaled_value) ;
                } ;
 } /* f2flac16_clip_array */
 
@@ -1218,18 +1222,18 @@ f2flac24_clip_array (const float *src, int32_t *dest, int count, int normalize)
 
        normfact = normalize ? (8.0 * 0x100000) : 1.0 ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
                if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFF))
-               {       dest [count] = 0x7FFFFF ;
+               {       dest [i] = 0x7FFFFF ;
                        continue ;
                        } ;
 
                if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x100000))
-               {       dest [count] = -0x800000 ;
+               {       dest [i] = -0x800000 ;
                        continue ;
                        }
-               dest [count] = psf_lrintf (scaled_value) ;
+               dest [i] = psf_lrintf (scaled_value) ;
                } ;
 
        return ;
@@ -1239,24 +1243,24 @@ static void
 f2flac8_array (const float *src, int32_t *dest, int count, int normalize)
 {      float normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
 
-       while (--count >= 0)
-               dest [count] = psf_lrintf (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+               dest [i] = psf_lrintf (src [i] * normfact) ;
 } /* f2flac8_array */
 
 static void
 f2flac16_array (const float *src, int32_t *dest, int count, int normalize)
 {      float normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
 
-       while (--count >= 0)
-               dest [count] = psf_lrintf (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+               dest [i] = psf_lrintf (src [i] * normfact) ;
 } /* f2flac16_array */
 
 static void
 f2flac24_array (const float *src, int32_t *dest, int count, int normalize)
 {      float normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
 
-       while (--count >= 0)
-               dest [count] = psf_lrintf (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+               dest [i] = psf_lrintf (src [i] * normfact) ;
 } /* f2flac24_array */
 
 static sf_count_t
@@ -1307,17 +1311,17 @@ d2flac8_clip_array (const double *src, int32_t *dest, int count, int normalize)
 
        normfact = normalize ? (8.0 * 0x10) : 1.0 ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
                if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7F))
-               {       dest [count] = 0x7F ;
+               {       dest [i] = 0x7F ;
                        continue ;
                        } ;
                if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10))
-               {       dest [count] = -0x80 ;
+               {       dest [i] = -0x80 ;
                        continue ;
                        } ;
-               dest [count] = psf_lrint (scaled_value) ;
+               dest [i] = psf_lrint (scaled_value) ;
                } ;
 
        return ;
@@ -1329,17 +1333,17 @@ d2flac16_clip_array (const double *src, int32_t *dest, int count, int normalize)
 
        normfact = normalize ? (8.0 * 0x1000) : 1.0 ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
                if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFF))
-               {       dest [count] = 0x7FFF ;
+               {       dest [i] = 0x7FFF ;
                        continue ;
                        } ;
                if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x1000))
-               {       dest [count] = -0x8000 ;
+               {       dest [i] = -0x8000 ;
                        continue ;
                        } ;
-               dest [count] = psf_lrint (scaled_value) ;
+               dest [i] = psf_lrint (scaled_value) ;
                } ;
 
        return ;
@@ -1351,17 +1355,17 @@ d2flac24_clip_array (const double *src, int32_t *dest, int count, int normalize)
 
        normfact = normalize ? (8.0 * 0x100000) : 1.0 ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
                if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFF))
-               {       dest [count] = 0x7FFFFF ;
+               {       dest [i] = 0x7FFFFF ;
                        continue ;
                        } ;
                if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x100000))
-               {       dest [count] = -0x800000 ;
+               {       dest [i] = -0x800000 ;
                        continue ;
                        } ;
-               dest [count] = psf_lrint (scaled_value) ;
+               dest [i] = psf_lrint (scaled_value) ;
                } ;
 
        return ;
@@ -1371,24 +1375,24 @@ static void
 d2flac8_array (const double *src, int32_t *dest, int count, int normalize)
 {      double normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
 
-       while (--count >= 0)
-               dest [count] = psf_lrint (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+               dest [i] = psf_lrint (src [i] * normfact) ;
 } /* d2flac8_array */
 
 static void
 d2flac16_array (const double *src, int32_t *dest, int count, int normalize)
 {      double normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
 
-       while (--count >= 0)
-               dest [count] = psf_lrint (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+               dest [i] = psf_lrint (src [i] * normfact) ;
 } /* d2flac16_array */
 
 static void
 d2flac24_array (const double *src, int32_t *dest, int count, int normalize)
 {      double normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
 
-       while (--count >= 0)
-               dest [count] = psf_lrint (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+               dest [i] = psf_lrint (src [i] * normfact) ;
 } /* d2flac24_array */
 
 static sf_count_t
index a63413d..2e4d444 100644 (file)
@@ -437,71 +437,71 @@ float32_get_capability    (SF_PRIVATE *psf)
 static void
 f2s_array (const float *src, int count, short *dest, float scale)
 {
-       while (--count >= 0)
-       {       dest [count] = psf_lrintf (scale * src [count]) ;
+       for (int i = 0 ; i < count ; i++)
+       {       dest [i] = psf_lrintf (scale * src [i]) ;
                } ;
 } /* f2s_array */
 
 static void
 f2s_clip_array (const float *src, int count, short *dest, float scale)
-{      while (--count >= 0)
-       {       float tmp = scale * src [count] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       float tmp = scale * src [i] ;
 
                if (CPU_CLIPS_POSITIVE == 0 && tmp > 32767.0)
-                       dest [count] = SHRT_MAX ;
+                       dest [i] = SHRT_MAX ;
                else if (CPU_CLIPS_NEGATIVE == 0 && tmp < -32768.0)
-                       dest [count] = SHRT_MIN ;
+                       dest [i] = SHRT_MIN ;
                else
-                       dest [count] = psf_lrintf (tmp) ;
+                       dest [i] = psf_lrintf (tmp) ;
                } ;
 } /* f2s_clip_array */
 
 static inline void
 f2i_array (const float *src, int count, int *dest, float scale)
-{      while (--count >= 0)
-       {       dest [count] = psf_lrintf (scale * src [count]) ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = psf_lrintf (scale * src [i]) ;
                } ;
 } /* f2i_array */
 
 static inline void
 f2i_clip_array (const float *src, int count, int *dest, float scale)
-{      while (--count >= 0)
-       {       float tmp = scale * src [count] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       float tmp = scale * src [i] ;
 
                if (CPU_CLIPS_POSITIVE == 0 && tmp > (1.0 * INT_MAX))
-                       dest [count] = INT_MAX ;
+                       dest [i] = INT_MAX ;
                else if (CPU_CLIPS_NEGATIVE == 0 && tmp < (-1.0 * INT_MAX))
-                       dest [count] = INT_MIN ;
+                       dest [i] = INT_MIN ;
                else
-                       dest [count] = psf_lrintf (tmp) ;
+                       dest [i] = psf_lrintf (tmp) ;
                } ;
 } /* f2i_clip_array */
 
 static inline void
 f2d_array (const float *src, int count, double *dest)
-{      while (--count >= 0)
-       {       dest [count] = src [count] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = src [i] ;
                } ;
 } /* f2d_array */
 
 static inline void
 s2f_array (const short *src, float *dest, int count, float scale)
-{      while (--count >= 0)
-       {       dest [count] = scale * src [count] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = scale * src [i] ;
                } ;
 } /* s2f_array */
 
 static inline void
 i2f_array (const int *src, float *dest, int count, float scale)
-{      while (--count >= 0)
-       {       dest [count] = scale * src [count] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = scale * src [i] ;
                } ;
 } /* i2f_array */
 
 static inline void
 d2f_array (const double *src, float *dest, int count)
-{      while (--count >= 0)
-       {       dest [count] = src [count] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = src [i] ;
                } ;
 } /* d2f_array */
 
@@ -523,7 +523,7 @@ host_read_f2s       (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
 
 /* Fix me : Need lef2s_array */
                if (psf->data_endswap == SF_TRUE)
@@ -554,7 +554,7 @@ host_read_f2i       (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
 
                if (psf->data_endswap == SF_TRUE)
                        endswap_int_array (ubuf.ibuf, bufferlen) ;
@@ -583,7 +583,7 @@ host_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
 
                endswap_int_copy ((int*) (ptr + total), ubuf.ibuf, readcount) ;
 
@@ -607,7 +607,7 @@ host_read_f2d       (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
 
                if (psf->data_endswap == SF_TRUE)
                        endswap_int_array (ubuf.ibuf, bufferlen) ;
@@ -645,7 +645,7 @@ host_write_s2f      (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
                if (psf->data_endswap == SF_TRUE)
                        endswap_int_array (ubuf.ibuf, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -676,7 +676,7 @@ host_write_i2f      (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
                if (psf->data_endswap == SF_TRUE)
                        endswap_int_array (ubuf.ibuf, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.fbuf, sizeof (float) , bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float) , bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -706,7 +706,7 @@ host_write_f        (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
 
                endswap_int_copy (ubuf.ibuf, (const int*) (ptr + total), bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -736,7 +736,7 @@ host_write_d2f      (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
                if (psf->data_endswap == SF_TRUE)
                        endswap_int_array (ubuf.ibuf, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -762,7 +762,7 @@ replace_read_f2s    (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
 
                if (psf->data_endswap == SF_TRUE)
                        endswap_int_array (ubuf.ibuf, bufferlen) ;
@@ -787,12 +787,12 @@ replace_read_f2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        float           scale ;
 
        bufferlen = ARRAY_LEN (ubuf.fbuf) ;
-       scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
+       scale = (psf->float_int_mult == 0) ? 1.0 : 2147483648.0f / psf->float_max ;
 
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
 
                if (psf->data_endswap == SF_TRUE)
                        endswap_int_array (ubuf.ibuf, bufferlen) ;
@@ -822,7 +822,7 @@ replace_read_f      (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
 
                if (psf->data_endswap == SF_TRUE)
                        endswap_int_array (ubuf.ibuf, bufferlen) ;
@@ -851,7 +851,7 @@ replace_read_f2d    (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
 
                if (psf->data_endswap == SF_TRUE)
                        endswap_int_array (ubuf.ibuf, bufferlen) ;
@@ -891,7 +891,7 @@ replace_write_s2f   (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
                if (psf->data_endswap == SF_TRUE)
                        endswap_int_array (ubuf.ibuf, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -924,7 +924,7 @@ replace_write_i2f   (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
                if (psf->data_endswap == SF_TRUE)
                        endswap_int_array (ubuf.ibuf, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -957,7 +957,7 @@ replace_write_f     (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
                if (psf->data_endswap == SF_TRUE)
                        endswap_int_array (ubuf.ibuf, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.fbuf, sizeof (float) , bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float) , bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -988,7 +988,7 @@ replace_write_d2f   (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
                if (psf->data_endswap == SF_TRUE)
                        endswap_int_array (ubuf.ibuf, bufferlen) ;
 
-               writecount = psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1003,15 +1003,15 @@ replace_write_d2f       (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
 
 static void
 bf2f_array (float *buffer, int count)
-{      while (--count >= 0)
-       {       buffer [count] = FLOAT32_READ ((unsigned char *) (buffer + count)) ;
+{      for (int i = 0 ; i < count ; i++)
+       {       buffer [i] = FLOAT32_READ ((unsigned char *) &buffer [i]) ;
                } ;
 } /* bf2f_array */
 
 static void
 f2bf_array (float *buffer, int count)
-{      while (--count >= 0)
-       {       FLOAT32_WRITE (buffer [count], (unsigned char*) (buffer + count)) ;
+{      for (int i = 0 ; i < count ; i++)
+       {       FLOAT32_WRITE (buffer [i], (unsigned char*) &buffer [i]) ;
                } ;
 } /* f2bf_array */
 
index 563a909..8698ebf 100644 (file)
@@ -264,7 +264,7 @@ g72x_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = SF_BUFFER_LEN / sizeof (short) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = g72x_read_block (psf, pg72x, sptr, readcount) ;
 
                for (k = 0 ; k < readcount ; k++)
@@ -297,7 +297,7 @@ g72x_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = SF_BUFFER_LEN / sizeof (short) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = g72x_read_block (psf, pg72x, sptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = normfact * sptr [k] ;
@@ -329,7 +329,7 @@ g72x_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = SF_BUFFER_LEN / sizeof (short) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = g72x_read_block (psf, pg72x, sptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = normfact * (double) (sptr [k]) ;
@@ -505,7 +505,7 @@ g72x_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = SF_BUFFER_LEN / sizeof (short) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        sptr [k] = ptr [total + k] >> 16 ;
                count = g72x_write_block (psf, pg72x, sptr, writecount) ;
@@ -536,7 +536,7 @@ g72x_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = SF_BUFFER_LEN / sizeof (short) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        sptr [k] = psf_lrintf (normfact * ptr [total + k]) ;
                count = g72x_write_block (psf, pg72x, sptr, writecount) ;
@@ -568,7 +568,7 @@ g72x_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = SF_BUFFER_LEN / sizeof (short) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        sptr [k] = psf_lrint (normfact * ptr [total + k]) ;
                count = g72x_write_block (psf, pg72x, sptr, writecount) ;
index 06519bc..77d4f1f 100644 (file)
@@ -198,7 +198,7 @@ gsm610_wav_decode_block     (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
                return 1 ;
                } ;
 
-       if ((k = psf_fread (pgsm610->block, 1, WAVLIKE_GSM610_BLOCKSIZE, psf)) != WAVLIKE_GSM610_BLOCKSIZE)
+       if ((k = (int) psf_fread (pgsm610->block, 1, WAVLIKE_GSM610_BLOCKSIZE, psf)) != WAVLIKE_GSM610_BLOCKSIZE)
                psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, WAVLIKE_GSM610_BLOCKSIZE) ;
 
        if (gsm_decode (pgsm610->gsm_data, pgsm610->block, pgsm610->samples) < 0)
@@ -226,7 +226,7 @@ gsm610_decode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
                return 1 ;
                } ;
 
-       if ((k = psf_fread (pgsm610->block, 1, GSM610_BLOCKSIZE, psf)) != GSM610_BLOCKSIZE)
+       if ((k = (int) psf_fread (pgsm610->block, 1, GSM610_BLOCKSIZE, psf)) != GSM610_BLOCKSIZE)
                psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, GSM610_BLOCKSIZE) ;
 
        if (gsm_decode (pgsm610->gsm_data, pgsm610->block, pgsm610->samples) < 0)
@@ -302,7 +302,7 @@ gsm610_read_i       (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = ARRAY_LEN (ubuf.sbuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = arith_shift_left (sptr [k], 16) ;
@@ -331,7 +331,7 @@ gsm610_read_f       (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = ARRAY_LEN (ubuf.sbuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = normfact * sptr [k] ;
@@ -360,7 +360,7 @@ gsm610_read_d       (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = ARRAY_LEN (ubuf.sbuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = normfact * sptr [k] ;
@@ -437,7 +437,7 @@ gsm610_encode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
        gsm_encode (pgsm610->gsm_data, pgsm610->samples, pgsm610->block) ;
 
        /* Write the block to disk. */
-       if ((k = psf_fwrite (pgsm610->block, 1, GSM610_BLOCKSIZE, psf)) != GSM610_BLOCKSIZE)
+       if ((k = (int) psf_fwrite (pgsm610->block, 1, GSM610_BLOCKSIZE, psf)) != GSM610_BLOCKSIZE)
                psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, GSM610_BLOCKSIZE) ;
 
        pgsm610->samplecount = 0 ;
@@ -458,7 +458,7 @@ gsm610_wav_encode_block     (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
        gsm_encode (pgsm610->gsm_data, pgsm610->samples+WAVLIKE_GSM610_SAMPLES / 2, pgsm610->block+WAVLIKE_GSM610_BLOCKSIZE / 2) ;
 
        /* Write the block to disk. */
-       if ((k = psf_fwrite (pgsm610->block, 1, WAVLIKE_GSM610_BLOCKSIZE, psf)) != WAVLIKE_GSM610_BLOCKSIZE)
+       if ((k = (int) psf_fwrite (pgsm610->block, 1, WAVLIKE_GSM610_BLOCKSIZE, psf)) != WAVLIKE_GSM610_BLOCKSIZE)
                psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, WAVLIKE_GSM610_BLOCKSIZE) ;
 
        pgsm610->samplecount = 0 ;
@@ -532,7 +532,7 @@ gsm610_write_i      (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = ARRAY_LEN (ubuf.sbuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        sptr [k] = ptr [total + k] >> 16 ;
                count = gsm610_write_block (psf, pgsm610, sptr, writecount) ;
@@ -561,7 +561,7 @@ gsm610_write_f      (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = ARRAY_LEN (ubuf.sbuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        sptr [k] = psf_lrintf (normfact * ptr [total + k]) ;
                count = gsm610_write_block (psf, pgsm610, sptr, writecount) ;
@@ -592,7 +592,7 @@ gsm610_write_d      (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = ARRAY_LEN (ubuf.sbuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        sptr [k] = psf_lrint (normfact * ptr [total + k]) ;
                count = gsm610_write_block (psf, pgsm610, sptr, writecount) ;
index 2b82d0f..1516ee3 100644 (file)
--- a/src/id3.c
+++ b/src/id3.c
 #include       "sndfile.h"
 #include       "sfendian.h"
 #include       "common.h"
+#include       "id3.h"
+
+#if HAVE_MPEG
+#include       <lame/lame.h>
+
+struct id3v1_genre_handler_userdata
+{      int number ;
+       const char *ret ;
+} ;
+
+static void
+id3v1_genre_handler (int number, const char *description, void *userdata)
+{      struct id3v1_genre_handler_userdata *data = (struct id3v1_genre_handler_userdata *) userdata ;
+       if (data->number == number)
+               data->ret = description ;
+}
+
+const char *
+id3_lookup_v1_genre (int number)
+{      struct id3v1_genre_handler_userdata data ;
+
+       data.number = number ;
+       data.ret = NULL ;
+       id3tag_genre_list (id3v1_genre_handler, &data) ;
+
+       return data.ret ;
+}
+
+#else /* HAVE_MPEG */
+
+const char *
+id3_lookup_v1_genre (int UNUSED (number))
+{      return NULL ;
+       }
+
+#endif
 
 int
 id3_skip (SF_PRIVATE * psf)
 {      unsigned char   buf [10] ;
+       int     offset ;
 
        memset (buf, 0, sizeof (buf)) ;
        psf_binheader_readf (psf, "pb", 0, buf, 10) ;
 
        if (buf [0] == 'I' && buf [1] == 'D' && buf [2] == '3')
-       {       int     offset = buf [6] & 0x7f ;
+       {       psf->id3_header.minor_version = buf [3] ;
+               offset = buf [6] & 0x7f ;
                offset = (offset << 7) | (buf [7] & 0x7f) ;
                offset = (offset << 7) | (buf [8] & 0x7f) ;
                offset = (offset << 7) | (buf [9] & 0x7f) ;
 
-               psf_log_printf (psf, "ID3 length : %d\n--------------------\n", offset) ;
+               /*
+               ** ID3 count field is how many bytes of ID3v2 header FOLLOW the ten
+               ** bytes of header magic and offset, NOT the total ID3v2 header len.
+               */
+               psf->id3_header.len = offset + 10 ;
+               psf->id3_header.offset = psf->fileoffset ;
+
+               psf_log_printf (psf, "  ID3v2.%d header length :        %d\n----------------------------------------\n",
+                       psf->id3_header.minor_version, psf->id3_header.len) ;
 
                /* Never want to jump backwards in a file. */
                if (offset < 0)
                        return 0 ;
 
-               /* Calculate new file offset and position ourselves there. */
-               offset += 10 ;
-               if (psf->fileoffset + offset < psf->filelength)
-               {       psf_binheader_readf (psf, "p", offset) ;
-                       psf->fileoffset += offset ;
+               /* Position ourselves at the new file offset. */
+               if (psf->fileoffset + psf->id3_header.len < psf->filelength)
+               {       psf_binheader_readf (psf, "p!", psf->id3_header.len) ;
+                       psf->fileoffset += psf->id3_header.len ;
                        return 1 ;
                        } ;
                } ;
 
        return 0 ;
 } /* id3_skip */
+
+const char *
+id3_process_v2_genre (const char *genre)
+{      int num = 0 ;
+       char c ;
+       const char *ptr ;
+
+       if (!genre)
+               return NULL ;
+
+       /*
+       ** Genre may require more processing.
+       **
+       ** It is allowed to have numeric references to the genre table from ID3v1.
+       ** We'll just convert the simple case here, strings of the format "(nnn)".
+       */
+       ptr = genre ;
+       if (ptr [0] == '(' && (c = *++ ptr) && isdigit (c))
+       {       num = c - '0' ;
+               while ((c == *++ ptr) && isdigit (c))
+                       num = num * 10 + (c - '0') ;
+               if (c == ')' && (c = *++ ptr) == '\0' && num < 256)
+                       if ((ptr = id3_lookup_v1_genre (num)))
+                               return ptr ;
+               } ;
+
+       return genre ;
+} /* id3_process_v2_genre */
diff --git a/src/id3.h b/src/id3.h
new file mode 100644 (file)
index 0000000..4f54c4f
--- /dev/null
+++ b/src/id3.h
@@ -0,0 +1,29 @@
+/*
+** Copyright (C) 2008-2019 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2019 Arthur Taylor <art@ified.ca>
+**
+** 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.
+*/
+
+#ifndef SF_SRC_ID3_H
+#define SF_SRC_ID3_H
+
+int id3_skip (SF_PRIVATE * psf) ;
+
+const char *id3_lookup_v1_genre (int number) ;
+
+const char *id3_process_v2_genre (const char *genre) ;
+
+#endif /* SF_SRC_ID3_H */
index 8c9bbff..bc61f4e 100644 (file)
@@ -182,7 +182,12 @@ ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
        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 ;
+       /*
+       **      Allocate enough space for 1 more than a multiple of 8 samples
+       **      to avoid having to branch when pulling apart the nibbles.
+       */
+       count = ((samplesperblock - 2) | 7) + 2 ;
+       pimasize = sizeof (IMA_ADPCM_PRIVATE) + psf->sf.channels * (blockalign + samplesperblock + sizeof(short) * count) ;
 
        if (! (pima = calloc (1, pimasize)))
                return SFE_MALLOC_FAILED ;
@@ -268,7 +273,7 @@ count ++ ;
                return 1 ;
                } ;
 
-       if ((k = psf_fread (pima->block, 1, pima->blocksize * pima->channels, psf)) != pima->blocksize * pima->channels)
+       if ((k = (int) psf_fread (pima->block, 1, pima->blocksize * pima->channels, psf)) != pima->blocksize * pima->channels)
                psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pima->blocksize) ;
 
        /* Read and check the block header. */
@@ -373,7 +378,7 @@ aiff_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
                } ;
 
        /* Write the block to disk. */
-       if ((k = psf_fwrite (pima->block, 1, pima->channels * pima->blocksize, psf)) != pima->channels * pima->blocksize)
+       if ((k = (int) psf_fwrite (pima->block, 1, pima->channels * pima->blocksize, psf)) != pima->channels * pima->blocksize)
                psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pima->channels * pima->blocksize) ;
 
        memset (pima->block, 0, pima->channels * pima->blocksize) ;
@@ -386,7 +391,7 @@ aiff_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
 static int
 wavlike_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
 {      int             chan, k, predictor, blockindx, indx, indxstart, diff ;
-       short   step, bytecode, stepindx [2] ;
+       short   step, bytecode, stepindx [2] = { 0 };
 
        pima->blockcount ++ ;
        pima->samplecount = 0 ;
@@ -396,7 +401,7 @@ wavlike_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
                return 1 ;
                } ;
 
-       if ((k = psf_fread (pima->block, 1, pima->blocksize, psf)) != pima->blocksize)
+       if ((k = (int) psf_fread (pima->block, 1, pima->blocksize, psf)) != pima->blocksize)
                psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pima->blocksize) ;
 
        /* Read and check the block header. */
@@ -552,7 +557,7 @@ wavlike_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
 
        /* Write the block to disk. */
 
-       if ((k = psf_fwrite (pima->block, 1, pima->blocksize, psf)) != pima->blocksize)
+       if ((k = (int) psf_fwrite (pima->block, 1, pima->blocksize, psf)) != pima->blocksize)
                psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pima->blocksize) ;
 
        memset (pima->samples, 0, pima->samplesperblock * sizeof (short)) ;
index aef21ad..733f1f4 100644 (file)
@@ -46,8 +46,6 @@
 #define HEADER_LENGTH          42      /* Sum of above data fields. */
 #define HEADER_NAME_LEN                17      /* Length of name string. */
 
-#define        SFE_MPC_NO_MARKER       666
-
 /*------------------------------------------------------------------------------
 ** Private static functions.
 */
@@ -131,7 +129,7 @@ mpc2k_write_header (SF_PRIVATE *psf, int calc_length)
        if (psf->is_pipe == SF_FALSE)
                psf_fseek (psf, 0, SEEK_SET) ;
 
-       snprintf (sample_name, sizeof (sample_name), "%-*.*s", HEADER_NAME_LEN, HEADER_NAME_LEN, psf->file.name.c) ;
+       snprintf (sample_name, sizeof (sample_name), "%-*.*s", HEADER_NAME_LEN, HEADER_NAME_LEN, psf->file.name) ;
 
        psf_binheader_writef (psf, "e11b", BHW1 (1), BHW1 (4), BHWv (sample_name), BHWz (HEADER_NAME_LEN)) ;
        psf_binheader_writef (psf, "e111", BHW1 (100), BHW1 (0), BHW1 ((psf->sf.channels - 1) & 1)) ;
diff --git a/src/mpeg.c b/src/mpeg.c
new file mode 100644 (file)
index 0000000..44db0ad
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+** Copyright (C) 2019 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2021 Arthur Taylor <art@ified.ca>
+**
+** This program is free software ; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation ; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY ; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program ; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       "sndfile.h"
+#include       "common.h"
+
+#if HAVE_MPEG
+
+#include "mpeg.h"
+
+static int     mpeg_write_header (SF_PRIVATE *psf, int calc_length) ;
+static int     mpeg_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
+
+/*------------------------------------------------------------------------------
+ * Private functions
+ */
+
+static int
+mpeg_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
+{
+       if (psf->have_written)
+               return 0 ;
+
+       return mpeg_l3_encoder_write_id3tag (psf) ;
+}
+
+static int
+mpeg_command (SF_PRIVATE *psf, int command, void *data, int datasize)
+{      int bitrate_mode ;
+
+       switch (command)
+       {       case SFC_SET_COMPRESSION_LEVEL :
+                       if (data == NULL || datasize != sizeof (double))
+                       {       psf->error = SFE_BAD_COMMAND_PARAM ;
+                               return SF_FALSE ;
+                               } ;
+                       if (psf->file.mode != SFM_WRITE)
+                       {       psf->error = SFE_NOT_WRITEMODE ;
+                               return SF_FALSE ;
+                               } ;
+                       return mpeg_l3_encoder_set_quality (psf, *(double *) data) ;
+
+               case SFC_SET_BITRATE_MODE :
+                       if (psf->file.mode != SFM_WRITE)
+                       {       psf->error = SFE_NOT_WRITEMODE ;
+                               return SF_FALSE ;
+                               } ;
+                       if (data == NULL || datasize != sizeof (int))
+                       {       psf->error = SFE_BAD_COMMAND_PARAM ;
+                               return SF_FALSE ;
+                               } ;
+                       bitrate_mode = *(int *) data ;
+                       return mpeg_l3_encoder_set_bitrate_mode (psf, bitrate_mode) ;
+
+               case SFC_GET_BITRATE_MODE :
+                       if (psf->file.mode == SFM_READ)
+                               return mpeg_decoder_get_bitrate_mode (psf) ;
+                       else
+                               return mpeg_l3_encoder_get_bitrate_mode (psf) ;
+
+               default :
+                       return SF_FALSE ;
+               } ;
+
+       return SF_FALSE ;
+} /* mpeg_command */
+
+/*------------------------------------------------------------------------------
+ * Public functions
+ */
+
+int
+mpeg_init (SF_PRIVATE *psf, int bitrate_mode, int write_metadata)
+{      int error ;
+
+       if (psf->file.mode == SFM_RDWR)
+               return SFE_BAD_MODE_RW ;
+
+       if (psf->file.mode == SFM_WRITE)
+       {       switch (SF_CODEC (psf->sf.format))
+               {       case SF_FORMAT_MPEG_LAYER_III :
+                               if ((error = mpeg_l3_encoder_init (psf, write_metadata)))
+                                       return error ;
+                               mpeg_l3_encoder_set_bitrate_mode (psf, bitrate_mode) ;
+                               if (write_metadata)
+                               {       /* ID3 support */
+                                       psf->strings.flags = SF_STR_ALLOW_START ;
+                                       psf->write_header = mpeg_write_header ;
+                                       } ;
+                               break ;
+
+                       case SF_FORMAT_MPEG_LAYER_I :
+                       case SF_FORMAT_MPEG_LAYER_II :
+                               psf_log_printf (psf, "MPEG Layer I and II encoding is not yet supported.\n") ;
+                               return SFE_UNIMPLEMENTED ;
+
+                       default:
+                               psf_log_printf (psf, "%s: bad psf->sf.format 0x%x.\n", __func__, psf->sf.format) ;
+                               return SFE_INTERNAL ;
+                       } ;
+               } ;
+
+       if (psf->file.mode == SFM_READ)
+       {       if ((error = mpeg_decoder_init (psf)))
+                       return error ;
+               } ;
+
+       return 0 ;
+} /* mpeg_init */
+
+int
+mpeg_open (SF_PRIVATE *psf)
+{      int error ;
+
+       /* Choose variable bitrate mode by default for standalone files.*/
+       if ((error = mpeg_init (psf, SF_BITRATE_MODE_VARIABLE, SF_TRUE)))
+               return error ;
+
+       psf->dataoffset = 0 ;
+       psf->command = mpeg_command ;
+
+       if (psf->filelength != SF_COUNT_MAX)
+               psf->datalength = psf->filelength - psf->dataoffset ;
+       else
+               psf->datalength = SF_COUNT_MAX ;
+
+
+       return 0 ;
+} /* mpeg_open */
+
+#else /* HAVE_MPEG */
+
+int
+mpeg_init (SF_PRIVATE *psf, int UNUSED (bitrate_mode) , int UNUSED (write_metadata))
+{
+       psf_log_printf (psf, "This version of libsndfile was compiled without MPEG support.\n") ;
+       return SFE_UNIMPLEMENTED ;
+} /* mpeg_init */
+
+int
+mpeg_open (SF_PRIVATE *psf)
+{
+       psf_log_printf (psf, "This version of libsndfile was compiled without MP3 support.\n") ;
+       return SFE_UNIMPLEMENTED ;
+} /* mpeg_open */
+
+#endif
diff --git a/src/mpeg.h b/src/mpeg.h
new file mode 100644 (file)
index 0000000..f335745
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+** Copyright (C) 2019 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2019 Arthur Taylor <art@ified.ca>
+**
+** 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.
+*/
+
+#ifndef SNDFILE_MPEG_H
+#define SNDFILE_MPEG_H
+
+#include       "common.h"
+
+int mpeg_decoder_init (SF_PRIVATE *psf) ;
+
+/*
+** Get the file bitrate mode, returning one of the SF_BITRATE_MODE_ enum
+** values. Purely informative, 'Frankenstein' files and VBR files without an
+** Xing/LAME/Info header may not be detected properly.
+*/
+int mpeg_decoder_get_bitrate_mode (SF_PRIVATE *psf) ;
+
+
+/*
+** Initialize an encoder instance for writing. If parameter info_tag is
+** SF_TRUE, a Xing/LAME/Info header is written at the beginning of the file,
+** (unless the file cannot seek.)
+*/
+int mpeg_l3_encoder_init (SF_PRIVATE *psf, int info_tag) ;
+
+
+/*
+** Write an ID3v2 header from the sndfile string metadata. Must be called
+** before any audio data is written. Writing an ID3v2 header will also cause
+** a ID3v1 trailer to be written on close automatically.
+*/
+int mpeg_l3_encoder_write_id3tag (SF_PRIVATE *psf) ;
+
+/*
+** Set the encoder quality setting. Argument to compression should be identical
+** to that for SFC_SET_COMPRESSION_LEVEL; It should be in the range [0-1],
+** with 0 being highest quality, least compression, and 1 being the opposite.
+** Returns SF_TRUE on success, SF_FALSE otherwise.
+*/
+int mpeg_l3_encoder_set_quality (SF_PRIVATE *psf, double compression) ;
+
+/*
+** Set the encoder bitrate mode. Can only be called before any data has been
+** written. Argument mode should be one of the SF_BITRATE_MODE_ enum values.
+** Returns SF_TRUE on success, SF_FALSE otherwise. The SF_BITRATE_MODE_FILE
+** enum value should not be passed here but rather intercepted at the container
+** level and translated according to the container.
+*/
+int mpeg_l3_encoder_set_bitrate_mode (SF_PRIVATE *psf, int mode) ;
+
+/*
+** Get the encoder bitrate mode in use. Returns a SF_BITRATE_MODE_ enum value.
+** Will not return SF_BITRATE_MODE_FILE.
+*/
+int mpeg_l3_encoder_get_bitrate_mode (SF_PRIVATE *psf) ;
+
+
+#endif /* SNDFILE_MPEG_H */
diff --git a/src/mpeg_decode.c b/src/mpeg_decode.c
new file mode 100644 (file)
index 0000000..20fac4f
--- /dev/null
@@ -0,0 +1,641 @@
+/*
+** Copyright (C) 2019 - 2021 Arthur Taylor <art@ified.ca>
+** Copyright (C) 2019 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software ; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation ; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY ; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program ; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <math.h>
+
+#include       "sndfile.h"
+#include       "common.h"
+#include       "mpeg.h"
+
+#if HAVE_MPEG
+
+#include       "sfendian.h"
+#include       "id3.h"
+
+#include <mpg123.h>
+
+typedef struct
+{      mpg123_handle *pmh ;
+       size_t header_remaining ;
+} MPEG_DEC_PRIVATE ;
+
+static int mpeg_dec_close (SF_PRIVATE *psf) ;
+static sf_count_t mpeg_dec_seek (SF_PRIVATE *psf, int whence, sf_count_t count) ;
+
+static ssize_t mpeg_dec_io_read (void *priv, void *buffer, size_t nbytes) ;
+static off_t mpeg_dec_io_lseek (void *priv, off_t offset, int whence) ;
+
+static ssize_t
+mpeg_dec_io_read (void *priv, void *buffer, size_t nbytes)
+{      SF_PRIVATE *psf = (SF_PRIVATE *) priv ;
+       MPEG_DEC_PRIVATE *pmp3d = (MPEG_DEC_PRIVATE *) psf->codec_data ;
+
+       if (pmp3d->header_remaining)
+       {       if (pmp3d->header_remaining < nbytes)
+                       nbytes = pmp3d->header_remaining ;
+               psf_binheader_readf (psf, "b", buffer, nbytes) ;
+               pmp3d->header_remaining -= nbytes ;
+               return nbytes ;
+               } ;
+
+       return psf_fread (buffer, 1, nbytes, psf) ;
+} /* mpeg_dec_io_read */
+
+static off_t
+mpeg_dec_io_lseek (void *priv, off_t offset, int whence)
+{      SF_PRIVATE *psf = (SF_PRIVATE *) priv ;
+
+       return psf_fseek (psf, offset, whence) ;
+} /* mpeg_dec_io_lseek */
+
+static int
+mpeg_dec_close (SF_PRIVATE *psf)
+{      MPEG_DEC_PRIVATE *pmp3d = (MPEG_DEC_PRIVATE *) psf->codec_data ;
+
+       if (pmp3d)
+       {       if (pmp3d->pmh)
+               {       mpg123_close (pmp3d->pmh) ;
+                       mpg123_delete (pmp3d->pmh) ;
+                       pmp3d->pmh = NULL ;
+                       }
+               free (psf->codec_data) ;
+               psf->codec_data = NULL ;
+               } ;
+
+       return 0 ;
+} /* mpeg_dec_close */
+
+static sf_count_t
+mpeg_dec_decode (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      MPEG_DEC_PRIVATE *pmp3d = (MPEG_DEC_PRIVATE *) psf->codec_data ;
+       size_t done ;
+       int error ;
+
+       error = mpg123_read (pmp3d->pmh, (unsigned char *) ptr, len * sizeof (float), &done) ;
+
+       if (error == MPG123_OK)
+               return done / sizeof (float) ;
+
+       if (error == MPG123_DONE)
+               return 0 ;
+
+       if (error == MPG123_NEW_FORMAT)
+       {       psf->error = SFE_MALFORMED_FILE ;
+               return -1 ;
+               } ;
+
+       psf->error = SFE_INTERNAL ;
+       return -1 ;
+} /* mpeg_dec_decode */
+
+static sf_count_t
+mpeg_dec_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      BUF_UNION ubuf ;
+       sf_count_t total, readlen ;
+       void (*convert) (const float *, short *, int, int) ;
+       const sf_count_t buflen = ARRAY_LEN (ubuf.fbuf) ;
+
+       convert = (psf->add_clipping) ? psf_f2s_clip_array : psf_f2s_array ;
+       for (total = 0 ; total < len ; total += readlen)
+       {       readlen = mpeg_dec_decode (psf, ubuf.fbuf, SF_MIN (buflen, len - total)) ;
+               if (readlen <= 0)
+                       break ;
+
+               convert (ubuf.fbuf, ptr + total, readlen, SF_TRUE) ;
+               } ;
+
+       return total ;
+} /*mpeg_dec_read_s */
+
+static sf_count_t
+mpeg_dec_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      BUF_UNION ubuf ;
+       sf_count_t total, readlen ;
+       void (*convert) (const float *, int *, int, int) ;
+       const sf_count_t buflen = ARRAY_LEN (ubuf.fbuf) ;
+
+       convert = (psf->add_clipping) ? psf_f2i_clip_array : psf_f2i_array ;
+       for (total = 0 ; total < len ; total += readlen)
+       {       readlen = mpeg_dec_decode (psf, ubuf.fbuf, SF_MIN (buflen, len - total)) ;
+               if (readlen <= 0)
+                       break ;
+
+               convert (ubuf.fbuf, ptr + total, readlen, SF_TRUE) ;
+               } ;
+
+       return total ;
+} /* mpeg_dec_read_i */
+
+static sf_count_t
+mpeg_dec_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      sf_count_t readlen ;
+
+       readlen = mpeg_dec_decode (psf, ptr, len) ;
+       if (readlen <= 0)
+               return 0 ;
+
+       if (psf->norm_float == SF_FALSE)
+               for (int i = 0 ; i < readlen ; i++)
+               {       ptr [i] *= (1.0f * 0x8000) ;
+                       } ;
+
+       return readlen ;
+} /* mpeg_dec_read_f */
+
+static inline void
+f2d_array (const float *src, int count, double *dest, double normfact)
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = src [i] * normfact ;
+               }
+} /* f2d_array */
+
+static sf_count_t
+mpeg_dec_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      BUF_UNION ubuf ;
+       sf_count_t total, readlen ;
+       double normfact ;
+       const sf_count_t buflen = ARRAY_LEN (ubuf.fbuf) ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 : (1.0 * 0x8000) ;
+
+       for (total = 0 ; total < len ; total += readlen)
+       {       readlen = mpeg_dec_decode (psf, ubuf.fbuf, SF_MIN (buflen, len - total)) ;
+               if (readlen <= 0)
+                       break ;
+
+               f2d_array (ubuf.fbuf, readlen, ptr + total, normfact) ;
+               } ;
+
+       return total ;
+} /* mpeg_dec_read_d */
+
+static sf_count_t
+mpeg_dec_seek (SF_PRIVATE *psf, int mode, sf_count_t count)
+{      MPEG_DEC_PRIVATE *pmp3d = (MPEG_DEC_PRIVATE *) psf->codec_data ;
+       off_t ret ;
+
+       if (mode != SFM_READ || psf->file.mode != SFM_READ)
+       {       psf->error = SFE_BAD_SEEK ;
+               return PSF_SEEK_ERROR ;
+               } ;
+
+       ret = mpg123_seek (pmp3d->pmh, count, SEEK_SET) ;
+
+       if (ret < 0)
+               return PSF_SEEK_ERROR ;
+
+       return (sf_count_t) ret ;
+} /* mpeg_dec_seek */
+
+static int
+mpeg_dec_fill_sfinfo (mpg123_handle *mh, SF_INFO *info)
+{      int error ;
+       int channels ;
+       int encoding ;
+       long rate ;
+       off_t length ;
+
+       error = mpg123_getformat (mh, &rate, &channels, &encoding) ;
+       if (error != MPG123_OK)
+               return error ;
+
+       info->samplerate = rate ;
+       info->channels = channels ;
+
+       length = mpg123_length (mh) ;
+       if (length >= 0)
+       {       info->frames = length ;
+               info->seekable = SF_TRUE ;
+               }
+       else
+       {       info->frames = SF_COUNT_MAX ;
+               info->seekable = SF_FALSE ;
+               }
+
+       /* Force 32-bit float samples. */
+       if (encoding != MPG123_ENC_FLOAT_32)
+       {       error = mpg123_format (mh, rate, channels, MPG123_ENC_FLOAT_32) ;
+               } ;
+
+       return error ;
+} /* mpeg_dec_fill_sfinfo */
+
+static void
+mpeg_dec_print_frameinfo (SF_PRIVATE *psf, const struct mpg123_frameinfo *fi)
+{      psf_log_printf (psf, "MPEG-1/2 Audio\n----------------------------------------\n") ;
+       psf_log_printf (psf, "  MPEG version   : %s\n",
+               fi->version == MPG123_1_0 ? "MPEG 1.0" :
+               fi->version == MPG123_2_0 ? "MPEG 2.0" :
+               fi->version == MPG123_2_5 ? "MPEG 2.5" : "???") ;
+       psf_log_printf (psf, "  layer          : %d\n", fi->layer) ;
+       psf_log_printf (psf, "  rate           : %d\n", fi->rate) ;
+       psf_log_printf (psf, "  mode           : %s\n",
+               fi->mode == MPG123_M_STEREO ? "stereo" :
+               fi->mode == MPG123_M_JOINT ? "joint stereo" :
+               fi->mode == MPG123_M_DUAL ? "dual channel" :
+               fi->mode == MPG123_M_MONO ? "mono" : "???") ;
+       psf_log_printf (psf, "  mode ext       : %d\n", fi->mode_ext) ;
+       psf_log_printf (psf, "  framesize      : %d\n", fi->framesize) ;
+       psf_log_printf (psf, "  crc            : %d\n", !! (fi->flags & MPG123_CRC)) ;
+       psf_log_printf (psf, "  copyright flag : %d\n", !! (fi->flags & MPG123_COPYRIGHT)) ;
+       psf_log_printf (psf, "  private flag   : %d\n", !! (fi->flags & MPG123_PRIVATE)) ;
+       psf_log_printf (psf, "  original flag  : %d\n", !! (fi->flags & MPG123_ORIGINAL)) ;
+       psf_log_printf (psf, "  emphasis       : %d\n", fi->emphasis) ;
+       psf_log_printf (psf, "  bitrate mode   : ") ;
+       switch (fi->vbr)
+       {       case MPG123_CBR :
+                       psf_log_printf (psf, "constant\n") ;
+                       psf_log_printf (psf, "  bitrate        : %d kbps\n", fi->bitrate) ;
+                       break ;
+               case MPG123_VBR :
+                       psf_log_printf (psf, "variable\n") ;
+                       break ;
+
+               case MPG123_ABR :
+                       psf_log_printf (psf, "average\n") ;
+                       psf_log_printf (psf, "  ABR target     : %d\n", fi->abr_rate) ;
+                       break ;
+
+               default :
+                       psf_log_printf (psf, "(%d) ???\n", fi->vbr) ;
+                       break ;
+               } ;
+} /* mpeg_dec_print_frameinfo */
+
+/*
+ * Like strlcpy, except the size argument is the maximum size of the input,
+ * always null terminates the output string. Thus, up to size + 1 bytes may be
+ * written.
+ *
+ * Returns the length of the copied string.
+ */
+static int
+strcpy_inbounded (char *dest, size_t size, const char *src)
+{      char *c = memccpy (dest, src, '\0', size) ;
+       if (!c)
+               c = dest + size ;
+       *c = '\0' ;
+       return c - dest ;
+} /* strcpy_inbounded */
+
+static void
+mpeg_decoder_read_strings_id3v1 (SF_PRIVATE *psf, mpg123_id3v1 *tags)
+{      const char *genre ;
+       char buf [31] ;
+
+       psf_log_printf (psf, "ID3v1 Tags\n") ;
+
+       if (strcpy_inbounded (buf, ARRAY_LEN (tags->title), tags->title))
+       {       psf_log_printf (psf, "  Title       : %s\n", buf) ;
+               psf_store_string (psf, SF_STR_TITLE, buf) ;
+               } ;
+
+       if (strcpy_inbounded (buf, ARRAY_LEN (tags->artist), tags->artist))
+       {       psf_log_printf (psf, "  Artist      : %s\n", buf) ;
+               psf_store_string (psf, SF_STR_ARTIST, buf) ;
+               } ;
+
+       if (strcpy_inbounded (buf, ARRAY_LEN (tags->album), tags->album))
+       {       psf_log_printf (psf, "  Album       : %s\n", buf) ;
+               psf_store_string (psf, SF_STR_ALBUM, buf) ;
+               } ;
+
+       if (strcpy_inbounded (buf, ARRAY_LEN (tags->year), tags->year))
+       {       psf_log_printf (psf, "  Year        : %s\n", buf) ;
+               psf_store_string (psf, SF_STR_DATE, buf) ;
+               } ;
+
+       if (strcpy_inbounded (buf, ARRAY_LEN (tags->comment), tags->comment))
+       {       psf_log_printf (psf, "  Comment     : %s\n", buf) ;
+               psf_store_string (psf, SF_STR_COMMENT, buf) ;
+               } ;
+
+       /* ID3v1.1 Tracknumber */
+       if (tags->comment [28] == '\0' && tags->comment [29] != '\0')
+       {       snprintf (buf, ARRAY_LEN (buf), "%hhu", (unsigned char) tags->comment [29]) ;
+               psf_log_printf (psf, "  Tracknumber : %s\n", buf) ;
+               psf_store_string (psf, SF_STR_TRACKNUMBER, buf) ;
+               } ;
+
+       if ((genre = id3_lookup_v1_genre (tags->genre)) != NULL)
+       {       psf_log_printf (psf, "  Genre       : %s\n", genre) ;
+               psf_store_string (psf, SF_STR_GENRE, genre) ;
+               } ;
+} /* mpeg_decoder_read_strings_id3v1 */
+
+static void
+mpeg_decoder_read_strings_id3v2 (SF_PRIVATE *psf, mpg123_id3v2 *tags)
+{      mpg123_text *text_frame ;
+       size_t i ;
+       uint32_t marker ;
+       const char *title               = NULL ;
+       const char *copyright   = NULL ;
+       const char *software    = NULL ;
+       const char *artist              = NULL ;
+       const char *comment             = NULL ;
+       const char *date                = NULL ;
+       const char *album               = NULL ;
+       const char *license             = NULL ;
+       const char *tracknumber = NULL ;
+       const char *genre               = NULL ;
+       const char *tlen                = NULL ;
+
+       psf_log_printf (psf, "ID3v2 Tags\n") ;
+
+       // Read the parsed text tags
+       for (i = 0 ; i < tags->texts ; i++)
+       {       text_frame = &tags->text [i] ;
+               psf_log_printf (psf, "  %.4s        : %s\n", text_frame->id, text_frame->text.p) ;
+
+               // Thankfully mpg123 translates v2.2 3-byte frames to v2.3 4-byte for us.
+               marker = MAKE_MARKER (text_frame->id [0], text_frame->id [1],
+                       text_frame->id [2], text_frame->id [3]) ;
+
+               /* Use our own map of frame types to metadata for text frames */
+               switch (marker)
+               {       case MAKE_MARKER ('T', 'I', 'T', '2') :
+                               title = text_frame->text.p ;
+                               break ;
+
+                       case MAKE_MARKER ('T', 'C', 'O', 'P') :
+                               copyright = text_frame->text.p ;
+                               break ;
+
+                       case MAKE_MARKER ('T', 'E', 'N', 'C') :
+                       case MAKE_MARKER ('T', 'S', 'S', 'E') :
+                               software = text_frame->text.p ;
+                               break ;
+
+                       case MAKE_MARKER ('T', 'P', 'E', '1') :
+                               artist = text_frame->text.p ;
+                               break ;
+
+                       case MAKE_MARKER ('T', 'A', 'L', 'B') :
+                               album = text_frame->text.p ;
+                               break ;
+
+                       case MAKE_MARKER ('T', 'R', 'C', 'K') :
+                               tracknumber = text_frame->text.p ;
+                               break ;
+
+                       case MAKE_MARKER ('T', 'Y', 'E', 'R') :
+                       case MAKE_MARKER ('T', 'D', 'R', 'C') :
+                       /* TODO (maybe)
+                       case MAKE_MARKER ('T', 'D', 'A', 'T') :
+                       case MAKE_MARKER ('T', 'I', 'M', 'E') :
+                       case MAKE_MARKER ('T', 'D', 'R', 'A') :
+                       */
+                               date = text_frame->text.p ;
+                               break ;
+
+                       case MAKE_MARKER ('T', 'O', 'W', 'N') :
+                               tracknumber = text_frame->text.p ;
+                               break ;
+
+                       case MAKE_MARKER ('T', 'C', 'O', 'N') :
+                               genre = text_frame->text.p ;
+                               break ;
+
+                       case MAKE_MARKER ('T', 'L', 'E', 'N') :
+                               tlen = text_frame->text.p ;
+                               break ;
+                       } ;
+               } ;
+
+       /* Use mpg123's handling of comment headers, but print all the comment headers anyways. */
+       if (tags->comment)
+               comment = tags->comment->p ;
+       for (i = 0 ; i < tags->comments ; i++)
+       {       text_frame = &tags->comment_list [i] ;
+               psf_log_printf (psf, "  %.4s        : (%s)[%s] %s\n", text_frame->id,
+                       text_frame->description. p, text_frame->lang, text_frame->text.p) ;
+               } ;
+
+       /* Print extra headers */
+       for (i = 0 ; i < tags->extras ; i++)
+       {       text_frame = &tags->extra [i] ;
+               psf_log_printf (psf, "  %.4s        : (%s) %s\n", text_frame->id,
+                       text_frame->description.p, text_frame->text.p) ;
+               } ;
+
+       if (title != NULL)
+               psf_store_string (psf, SF_STR_TITLE, title) ;
+       if (copyright != NULL)
+               psf_store_string (psf, SF_STR_COPYRIGHT, copyright) ;
+       if (software != NULL)
+               psf_store_string (psf, SF_STR_SOFTWARE, software) ;
+       if (artist != NULL)
+               psf_store_string (psf, SF_STR_ARTIST, artist) ;
+       if (comment != NULL)
+               psf_store_string (psf, SF_STR_COMMENT, comment) ;
+       if (date != NULL)
+               psf_store_string (psf, SF_STR_DATE, date) ;
+       if (album != NULL)
+               psf_store_string (psf, SF_STR_ALBUM, album) ;
+       if (license != NULL)
+               psf_store_string (psf, SF_STR_LICENSE, license) ;
+       if (tracknumber != NULL)
+               psf_store_string (psf, SF_STR_TRACKNUMBER, tracknumber) ;
+       if (genre != NULL)
+               psf_store_string (psf, SF_STR_GENRE, id3_process_v2_genre (genre)) ;
+       if (tlen != NULL)
+       {       /* If non-seekable, set framecount? Can we trust it? */
+               } ;
+} /* mpeg_decoder_read_strings_id3v2 */
+
+static void
+mpeg_decoder_read_strings (SF_PRIVATE *psf)
+{      MPEG_DEC_PRIVATE *pmp3d = (MPEG_DEC_PRIVATE *) psf->codec_data ;
+       mpg123_id3v1 *v1_tags ;
+       mpg123_id3v2 *v2_tags ;
+
+       if (mpg123_id3 (pmp3d->pmh, &v1_tags, &v2_tags) != MPG123_OK)
+               return ;
+
+       if (v1_tags != NULL)
+               mpeg_decoder_read_strings_id3v1 (psf, v1_tags) ;
+
+       if (v2_tags != NULL)
+               mpeg_decoder_read_strings_id3v2 (psf, v2_tags) ;
+} /* mpeg_decoder_read_strings */
+
+static int
+mpeg_dec_byterate (SF_PRIVATE *psf)
+{      MPEG_DEC_PRIVATE *pmp3d = (MPEG_DEC_PRIVATE *) psf->codec_data ;
+       struct mpg123_frameinfo fi ;
+
+       if (mpg123_info (pmp3d->pmh, &fi) == MPG123_OK)
+               return (fi.bitrate + 7) / 8 ;
+
+       return -1 ;
+
+} /* mpeg_dec_byterate */
+
+/*==============================================================================
+** exported functions
+*/
+
+int
+mpeg_decoder_init (SF_PRIVATE *psf)
+{      MPEG_DEC_PRIVATE *pmp3d ;
+       struct mpg123_frameinfo fi ;
+       int error ;
+
+       if (! (psf->file.mode & SFM_READ))
+               return SFE_INTERNAL ;
+
+       /*
+       ** *** FIXME - Threading issues ***
+       **
+       ** mpg123_init() is a global call that should only be called once, and
+       ** should be paried with mpg123_exit() when done. libsndfile does not
+       ** provide for these requirements.
+       **
+       ** Currently this is a moot issue as mpg123_init() non-conditionally writes
+       ** static areas with calculated data, and mpg123_exit() is a NOP, but this
+       ** could change in a future version of it!
+       **
+       ** From mpg123.h:
+       ** > This should be called once in a non-parallel context. It is not explicitly
+       ** > thread-safe, but repeated/concurrent calls still _should_ be safe as static
+       ** > tables are filled with the same values anyway.
+       **
+       ** Note that calling mpg123_init() after it has already completed is a NOP.
+       **
+       ** Update 2021-07-04
+       ** mpg123 upstream has confirmed that mpg132_init() will become a NOP in future,
+       ** so this is moot.
+       */
+       if (mpg123_init () != MPG123_OK)
+               return SFE_INTERNAL ;
+
+       psf->codec_data = pmp3d = calloc (1, sizeof (MPEG_DEC_PRIVATE)) ;
+       if (!psf->codec_data)
+               return SFE_MALLOC_FAILED ;
+
+       pmp3d->pmh = mpg123_new (NULL, &error) ;
+       if (!pmp3d->pmh)
+       { psf_log_printf (psf, "Could not obtain a mpg123 handle: %s\n", mpg123_plain_strerror (error)) ;
+               return SFE_INTERNAL ;
+               } ;
+
+       psf->codec_close = mpeg_dec_close ;
+
+       mpg123_replace_reader_handle (pmp3d->pmh,
+               mpeg_dec_io_read, mpeg_dec_io_lseek, NULL) ;
+
+       mpg123_param (pmp3d->pmh, MPG123_REMOVE_FLAGS, MPG123_AUTO_RESAMPLE, 1.0) ;
+       mpg123_param (pmp3d->pmh, MPG123_ADD_FLAGS, MPG123_FORCE_FLOAT | MPG123_GAPLESS, 1.0) ;
+#if MPG123_API_VERSION >= 45
+       mpg123_param (pmp3d->pmh, MPG123_ADD_FLAGS, MPG123_NO_FRANKENSTEIN, 1.0) ;
+#endif
+
+       /*
+       ** Need to pass the first MPEG frame to libmpg123, but that frame was read
+       ** into psf->binheader in order that we could identify the stream.
+       */
+       if (psf->is_pipe)
+       {       /*
+               ** Can't seek, so setup our libmpg123 io callbacks to read the binheader
+               ** buffer first.
+               */
+               psf_binheader_readf (psf, "p", psf->dataoffset) ;
+               pmp3d->header_remaining = psf_binheader_readf (psf, NULL) - psf->dataoffset ;
+
+               /* Tell libmpg123 we can't seek the file. */
+               mpg123_param (pmp3d->pmh, MPG123_ADD_FLAGS, MPG123_NO_PEEK_END, 1.0) ;
+               }
+       else
+       {       /*
+               ** libmpg123 can parse the ID3v2 header. Undo the embedded file offset if the
+               ** enclosing file data is the ID3v2 header.
+               */
+               if (psf->id3_header.len > 0 && psf->id3_header.len + psf->id3_header.offset == psf->fileoffset)
+                       psf->fileoffset = psf->id3_header.offset ;
+
+               psf_fseek (psf, 0, SEEK_SET) ;
+               } ;
+
+       error = mpg123_open_handle (pmp3d->pmh, psf) ;
+       if (error != MPG123_OK)
+       {       psf_log_printf (psf, "mpg123 could not open the file: %s\n", mpg123_plain_strerror (error)) ;
+               return SFE_BAD_FILE ;
+               } ;
+
+       if (mpeg_dec_fill_sfinfo (pmp3d->pmh, &psf->sf) != MPG123_OK)
+       {       psf_log_printf (psf, "Cannot get MPEG decoder configuration: %s\n", mpg123_plain_strerror (error)) ;
+               return SFE_BAD_FILE ;
+               } ;
+
+       error = mpg123_info (pmp3d->pmh, &fi) ;
+       if (error != MPG123_OK)
+       {       psf_log_printf (psf, "Cannot get MPEG frame info: %s\n", mpg123_plain_strerror (error)) ;
+               return SFE_INTERNAL ;
+               }
+
+       switch (fi.layer)
+       {       case 1 : psf->sf.format |= SF_FORMAT_MPEG_LAYER_I ; break ;
+               case 2 : psf->sf.format |= SF_FORMAT_MPEG_LAYER_II ; break ;
+               case 3 : psf->sf.format |= SF_FORMAT_MPEG_LAYER_III ; break ;
+               default :
+                       return SFE_BAD_FILE ;
+               } ;
+       mpeg_dec_print_frameinfo (psf, &fi) ;
+
+       psf->read_short = mpeg_dec_read_s ;
+       psf->read_int   = mpeg_dec_read_i ;
+       psf->read_float = mpeg_dec_read_f ;
+       psf->read_double = mpeg_dec_read_d ;
+       psf->seek               = mpeg_dec_seek ;
+       psf->byterate   = mpeg_dec_byterate ;
+
+       mpeg_decoder_read_strings (psf) ;
+
+       return 0 ;
+} /* mpeg_decoder_init */
+
+int
+mpeg_decoder_get_bitrate_mode (SF_PRIVATE *psf)
+{      MPEG_DEC_PRIVATE *pmp3d = (MPEG_DEC_PRIVATE *) psf->codec_data ;
+       struct mpg123_frameinfo fi ;
+
+       if (mpg123_info (pmp3d->pmh, &fi) == MPG123_OK)
+       {
+               switch (fi.vbr)
+               {       case MPG123_CBR : return SF_BITRATE_MODE_CONSTANT ;
+                       case MPG123_ABR : return SF_BITRATE_MODE_AVERAGE ;
+                       case MPG123_VBR : return SF_BITRATE_MODE_VARIABLE ;
+                       default : break ;
+                       } ;
+               } ;
+
+       psf_log_printf (psf, "Cannot determine MPEG bitrate mode.\n") ;
+       return -1 ;
+} /* mpeg_decoder_get_bitrate_mode */
+
+#else /* HAVE_MPEG */
+
+int mpeg_decoder_init (SF_PRIVATE *psf)
+{      psf_log_printf (psf, "This version of libsndfile was compiled without MPEG decode support.\n") ;
+       return SFE_UNIMPLEMENTED ;
+} /* mpeg_decoder_init */
+
+#endif /* HAVE_MPEG */
diff --git a/src/mpeg_l3_encode.c b/src/mpeg_l3_encode.c
new file mode 100644 (file)
index 0000000..97324f7
--- /dev/null
@@ -0,0 +1,784 @@
+/*
+** Copyright (C) 2020 Arthur Taylor <art@ified.ca>
+** Copyright (C) 2019 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software ; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation ; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY ; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program ; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+#include       "sndfile.h"
+#include       "common.h"
+#include       "mpeg.h"
+
+
+#if HAVE_MPEG
+
+#include <lame/lame.h>
+
+/*
+ * RANT RANT RANT
+ *
+ * Lame has 11 functions for inputing sample data of various types and
+ * configurations, but due to bad definitions, or missing combinations, they
+ * aren't really of much help to us.
+ *
+ */
+
+typedef struct
+{      lame_t lamef ;
+       unsigned char *block ;
+       size_t block_len ;
+       int frame_samples ;
+       double compression ;
+       int initialized ;
+} MPEG_L3_ENC_PRIVATE ;
+
+
+/*-----------------------------------------------------------------------------------------------
+** Private function prototypes.
+*/
+
+static int mpeg_l3_encoder_close (SF_PRIVATE *psf) ;
+static int mpeg_l3_encoder_construct (SF_PRIVATE *psf) ;
+static int mpeg_l3_encoder_byterate (SF_PRIVATE *psf) ;
+
+static sf_count_t mpeg_l3_encode_write_short_stereo (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t mpeg_l3_encode_write_int_stereo (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t mpeg_l3_encode_write_float_stereo (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t mpeg_l3_encode_write_double_stereo (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+static sf_count_t mpeg_l3_encode_write_short_mono (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t mpeg_l3_encode_write_int_mono (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t mpeg_l3_encode_write_float_mono (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t mpeg_l3_encode_write_double_mono (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+/*-----------------------------------------------------------------------------------------------
+** Exported functions.
+*/
+
+int
+mpeg_l3_encoder_init (SF_PRIVATE *psf, int info_tag)
+{      MPEG_L3_ENC_PRIVATE* pmpeg = NULL ;
+
+       if (psf->file.mode == SFM_RDWR)
+               return SFE_BAD_MODE_RW ;
+
+       if (psf->file.mode != SFM_WRITE)
+               return SFE_INTERNAL ;
+
+       psf->codec_data = pmpeg = calloc (1, sizeof (MPEG_L3_ENC_PRIVATE)) ;
+       if (!pmpeg)
+               return SFE_MALLOC_FAILED ;
+
+       if (psf->sf.channels < 1 || psf->sf.channels > 2)
+               return SFE_BAD_OPEN_FORMAT ;
+
+       if (! (pmpeg->lamef = lame_init ()))
+               return SFE_MALLOC_FAILED ;
+
+       pmpeg->compression = -1.0 ; /* Unset */
+
+       lame_set_in_samplerate (pmpeg->lamef, psf->sf.samplerate) ;
+       lame_set_num_channels (pmpeg->lamef, psf->sf.channels) ;
+       if (lame_set_out_samplerate (pmpeg->lamef, psf->sf.samplerate) < 0)
+               return SFE_MPEG_BAD_SAMPLERATE ;
+
+       lame_set_write_id3tag_automatic (pmpeg->lamef, 0) ;
+
+       if (!info_tag || psf->is_pipe)
+       {       /* Can't seek back, so force disable Xing/Lame/Info header. */
+               lame_set_bWriteVbrTag (pmpeg->lamef, 0) ;
+               } ;
+
+       if (psf->sf.channels == 2)
+       {       psf->write_short        = mpeg_l3_encode_write_short_stereo ;
+               psf->write_int          = mpeg_l3_encode_write_int_stereo ;
+               psf->write_float        = mpeg_l3_encode_write_float_stereo ;
+               psf->write_double       = mpeg_l3_encode_write_double_stereo ;
+               }
+       else
+       {       psf->write_short        = mpeg_l3_encode_write_short_mono ;
+               psf->write_int          = mpeg_l3_encode_write_int_mono ;
+               psf->write_float        = mpeg_l3_encode_write_float_mono ;
+               psf->write_double       = mpeg_l3_encode_write_double_mono ;
+               }
+
+       psf->sf.seekable        = 0 ;
+       psf->codec_close        = mpeg_l3_encoder_close ;
+       psf->byterate           = mpeg_l3_encoder_byterate ;
+       psf->datalength         = 0 ;
+
+       return 0 ;
+} /* mpeg_l3_encoder_init */
+
+int
+mpeg_l3_encoder_write_id3tag (SF_PRIVATE *psf)
+{      MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE *) psf->codec_data ;
+       unsigned char *id3v2_buffer ;
+       int i, id3v2_size ;
+
+       if (psf->have_written)
+               return 0 ;
+
+       if ((i = mpeg_l3_encoder_construct (psf)))
+               return i ;
+
+       if (psf_fseek (psf, 0, SEEK_SET) != 0)
+               return SFE_NOT_SEEKABLE ;
+
+       /* Safe to call multiple times. */
+       id3tag_init (pmpeg->lamef) ;
+
+       for (i = 0 ; i < SF_MAX_STRINGS ; i++)
+       {       switch (psf->strings.data [i].type)
+               {       case SF_STR_TITLE :
+                               id3tag_set_title (pmpeg->lamef, psf->strings.storage + psf->strings.data [i].offset) ;
+                               break ;
+
+                       case SF_STR_ARTIST :
+                               id3tag_set_artist (pmpeg->lamef, psf->strings.storage + psf->strings.data [i].offset) ;
+                               break ;
+
+                       case SF_STR_ALBUM :
+                               id3tag_set_album (pmpeg->lamef, psf->strings.storage + psf->strings.data [i].offset) ;
+                               break ;
+
+                       case SF_STR_DATE :
+                               id3tag_set_year (pmpeg->lamef, psf->strings.storage + psf->strings.data [i].offset) ;
+                               break ;
+
+                       case SF_STR_COMMENT :
+                               id3tag_set_comment (pmpeg->lamef, psf->strings.storage + psf->strings.data [i].offset) ;
+                               break ;
+
+                       case SF_STR_GENRE :
+                               id3tag_set_genre (pmpeg->lamef, psf->strings.storage + psf->strings.data [i].offset) ;
+                               break ;
+
+                       case SF_STR_TRACKNUMBER :
+                               id3tag_set_track (pmpeg->lamef, psf->strings.storage + psf->strings.data [i].offset) ;
+                               break ;
+
+                       default:
+                               break ;
+                       } ;
+               } ;
+
+       /* The header in this case is the ID3v2 tag header. */
+       id3v2_size = lame_get_id3v2_tag (pmpeg->lamef, 0, 0) ;
+       if (id3v2_size > 0)
+       {       psf_log_printf (psf, "Writing ID3v2 header.\n") ;
+               if (! (id3v2_buffer = malloc (id3v2_size)))
+                       return SFE_MALLOC_FAILED ;
+               lame_get_id3v2_tag (pmpeg->lamef, id3v2_buffer, id3v2_size) ;
+               psf_fwrite (id3v2_buffer, 1, id3v2_size, psf) ;
+               psf->dataoffset = id3v2_size ;
+               free (id3v2_buffer) ;
+               } ;
+
+       return 0 ;
+}
+
+int
+mpeg_l3_encoder_set_quality (SF_PRIVATE *psf, double compression)
+{      MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE *) psf->codec_data ;
+       int bitrate_mode ;
+       int bitrate ;
+       int ret ;
+
+       if (compression < 0.0 || compression > 1.0)
+               return SF_FALSE ;
+
+       /*
+       ** Save the compression setting, as we may have to re-interpret it if
+       ** the bitrate mode changes.
+       */
+       pmpeg->compression = compression ;
+
+       bitrate_mode = mpeg_l3_encoder_get_bitrate_mode (psf) ;
+       if (bitrate_mode == SF_BITRATE_MODE_VARIABLE)
+       {       ret = lame_set_VBR_quality (pmpeg->lamef, compression * 10.0) ;
+               }
+       else
+       {       /* Choose a bitrate. */
+               if (psf->sf.samplerate >= 32000)
+               {       /* MPEG-1.0, bitrates are [32,320] kbps */
+                       bitrate = (320.0 - (compression * (320.0 - 32.0))) ;
+                       }
+               else if (psf->sf.samplerate >= 16000)
+               {       /* MPEG-2.0, bitrates are [8,160] */
+                       bitrate = (160.0 - (compression * (160.0 - 8.0))) ;
+                       }
+               else
+               {       /* MPEG-2.5, bitrates are [8,64] */
+                       bitrate = (64.0 - (compression * (64.0 - 8.0))) ;
+                       }
+
+               if (bitrate_mode == SF_BITRATE_MODE_AVERAGE)
+                       ret = lame_set_VBR_mean_bitrate_kbps (pmpeg->lamef, bitrate) ;
+               else
+                       ret = lame_set_brate (pmpeg->lamef, bitrate) ;
+               } ;
+
+       if (ret == LAME_OKAY)
+               return SF_TRUE ;
+
+       psf_log_printf (psf, "Failed to set lame encoder quality.\n") ;
+       return SF_FALSE ;
+} /* mpeg_l3_encoder_set_quality */
+
+int
+mpeg_l3_encoder_set_bitrate_mode (SF_PRIVATE *psf, int mode)
+{      MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE *) psf->codec_data ;
+       enum vbr_mode_e vbr_mode ;
+
+       if (pmpeg->initialized)
+       {       psf->error = SFE_CMD_HAS_DATA ;
+               return SF_FALSE ;
+               } ;
+
+       switch (mode)
+       {       case SF_BITRATE_MODE_CONSTANT : vbr_mode = vbr_off ; break ;
+               case SF_BITRATE_MODE_AVERAGE : vbr_mode = vbr_abr ; break ;
+               case SF_BITRATE_MODE_VARIABLE : vbr_mode = vbr_default ; break ;
+               default :
+                       psf->error = SFE_BAD_COMMAND_PARAM ;
+                       return SF_FALSE ;
+               } ;
+
+       if (lame_set_VBR (pmpeg->lamef, vbr_mode) == LAME_OKAY)
+       {       /* Re-evaluate the compression setting. */
+               return mpeg_l3_encoder_set_quality (psf, pmpeg->compression) ;
+               } ;
+
+       psf_log_printf (psf, "Failed to set LAME vbr mode to %d.\n", vbr_mode) ;
+       return SF_FALSE ;
+} /* mpeg_l3_encoder_set_bitrate_mode */
+
+int
+mpeg_l3_encoder_get_bitrate_mode (SF_PRIVATE *psf)
+{      MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE *) psf->codec_data ;
+       enum vbr_mode_e vbr_mode ;
+
+       vbr_mode = lame_get_VBR (pmpeg->lamef) ;
+
+       if (vbr_mode == vbr_off)
+               return SF_BITRATE_MODE_CONSTANT ;
+       if (vbr_mode == vbr_abr)
+               return SF_BITRATE_MODE_AVERAGE ;
+       if (vbr_mode == vbr_default || vbr_mode < vbr_max_indicator)
+               return SF_BITRATE_MODE_VARIABLE ;
+
+       /* Something is wrong. */
+       psf->error = SFE_INTERNAL ;
+       return -1 ;
+} /* mpeg_l3_encoder_get_bitrate_mode */
+
+
+/*-----------------------------------------------------------------------------------------------
+** Private functions.
+*/
+
+static int
+mpeg_l3_encoder_close (SF_PRIVATE *psf)
+{      MPEG_L3_ENC_PRIVATE* pmpeg = (MPEG_L3_ENC_PRIVATE *) psf->codec_data ;
+       int ret, len ;
+       sf_count_t pos ;
+       unsigned char *buffer ;
+
+       /* Magic number 7200 comes from a comment in lame.h */
+       len = 7200 ;
+       if (! (buffer = malloc (len)))
+               return SFE_MALLOC_FAILED ;
+       ret = lame_encode_flush (pmpeg->lamef, buffer, len) ;
+       if (ret > 0)
+               psf_fwrite (buffer, 1, ret, psf) ;
+
+       /*
+       ** Write an IDv1 trailer. The whole tag structure is always 128 bytes, so is
+       ** guaranteed to fit in the buffer allocated above.
+       */
+       ret = lame_get_id3v1_tag (pmpeg->lamef, buffer, len) ;
+       if (ret > 0)
+       {       psf_log_printf (psf, "  Writing ID3v1 trailer.\n") ;
+               psf_fwrite (buffer, 1, ret, psf) ;
+               } ;
+
+       /*
+       ** If possible, seek back and write the LAME/XING/Info headers. This
+       ** contains information about the whole file and a seek table, and can
+       ** only be written after encoding.
+       **
+       ** If enabled, Lame wrote an empty header at the beginning of the data
+       ** that we now fill in.
+       */
+       ret = lame_get_lametag_frame (pmpeg->lamef, 0, 0) ;
+       if (ret > 0)
+       {       if (ret > len)
+               {       len = ret ;
+                       free (buffer) ;
+                       if (! (buffer = malloc (len)))
+                               return SFE_MALLOC_FAILED ;
+                       } ;
+               psf_log_printf (psf, "  Writing LAME info header at offset %d, %d bytes.\n",
+                       psf->dataoffset, len) ;
+               lame_get_lametag_frame (pmpeg->lamef, buffer, len) ;
+               pos = psf_ftell (psf) ;
+               if (psf_fseek (psf, psf->dataoffset, SEEK_SET) == psf->dataoffset)
+               {       psf_fwrite (buffer, 1, ret, psf) ;
+                       psf_fseek (psf, pos, SEEK_SET) ;
+                       } ;
+               } ;
+       free (buffer) ;
+
+       free (pmpeg->block) ;
+       pmpeg->block = NULL ;
+
+       if (pmpeg->lamef)
+       {       lame_close (pmpeg->lamef) ;
+               pmpeg->lamef = NULL ;
+               } ;
+
+       return 0 ;
+} /* mpeg_l3_encoder_close */
+
+static void
+mpeg_l3_encoder_log_config (SF_PRIVATE *psf, lame_t lamef)
+{      const char *version ;
+       const char *chn_mode ;
+
+       switch (lame_get_version (lamef))
+       {       case 0 : version = "2" ; break ;
+               case 1 : version = "1" ; break ;
+               case 2 : version = "2.5" ; break ;
+               default : version = "unknown!?" ; break ;
+               } ;
+       switch (lame_get_mode (lamef))
+       {       case STEREO : chn_mode = "stereo" ; break ;
+               case JOINT_STEREO : chn_mode = "joint-stereo" ; break ;
+               case MONO : chn_mode = "mono" ; break ;
+               default : chn_mode = "unknown!?" ; break ;
+               } ;
+       psf_log_printf (psf, "  MPEG Version      : %s\n", version) ;
+       psf_log_printf (psf, "  Block samples     : %d\n", lame_get_framesize (lamef)) ;
+       psf_log_printf (psf, "  Channel mode      : %s\n", chn_mode) ;
+       psf_log_printf (psf, "  Samplerate        : %d\n", lame_get_out_samplerate (lamef)) ;
+       psf_log_printf (psf, "  Encoder mode      : ") ;
+       switch (lame_get_VBR (lamef))
+       {       case vbr_off :
+                       psf_log_printf (psf, "CBR\n") ;
+                       psf_log_printf (psf, "  Bitrate           : %d kbps\n", lame_get_brate (lamef)) ;
+                       break ;
+               case vbr_abr :
+                       psf_log_printf (psf, "ABR\n") ;
+                       psf_log_printf (psf, "  Mean Bitrate      : %d kbps\n", lame_get_VBR_mean_bitrate_kbps (lamef)) ;
+                       break ;
+
+               case vbr_mt :
+               case vbr_default :
+                       psf_log_printf (psf, "VBR\n") ;
+                       psf_log_printf (psf, "  Quality           : %d\n", lame_get_VBR_q (lamef)) ;
+                       break ;
+
+               default:
+                       psf_log_printf (psf, "Unknown!? (%d)\n", lame_get_VBR (lamef)) ;
+                       break ;
+               } ;
+
+       psf_log_printf (psf, "  Encoder delay     : %d\n", lame_get_encoder_delay (lamef)) ;
+       psf_log_printf (psf, "  Write INFO header : %d\n", lame_get_bWriteVbrTag (lamef)) ;
+} /* mpeg_l3_encoder_log_config */
+
+static int
+mpeg_l3_encoder_construct (SF_PRIVATE *psf)
+{      MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE *) psf->codec_data ;
+       int frame_samples_per_channel ;
+
+       if (pmpeg->initialized == SF_FALSE)
+       {       if (lame_init_params (pmpeg->lamef) < 0)
+               {       psf_log_printf (psf, "Failed to initialize lame encoder!\n") ;
+                       return SFE_INTERNAL ;
+                       } ;
+
+               psf_log_printf (psf, "Initialized LAME encoder.\n") ;
+               mpeg_l3_encoder_log_config (psf, pmpeg->lamef) ;
+
+               frame_samples_per_channel = lame_get_framesize (pmpeg->lamef) ;
+
+               /*
+                * Suggested output buffer size in bytes from lame.h comment is
+                * 1.25 * samples + 7200
+                */
+               pmpeg->block_len = (frame_samples_per_channel * 4) / 3 + 7200 ;
+               pmpeg->frame_samples = frame_samples_per_channel * psf->sf.channels ;
+
+               pmpeg->block = malloc (pmpeg->block_len) ;
+               if (!pmpeg->block)
+                       return SFE_MALLOC_FAILED ;
+
+               pmpeg->initialized = SF_TRUE ;
+               } ;
+
+       return 0 ;
+} /* mpeg_l3_encoder_construct */
+
+static int
+mpeg_l3_encoder_byterate (SF_PRIVATE *psf)
+{      MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE *) psf->codec_data ;
+       int bitrate_mode ;
+       int byterate ;
+       float calculated_byterate ;
+
+       bitrate_mode = mpeg_l3_encoder_get_bitrate_mode (psf) ;
+       byterate = (lame_get_brate (pmpeg->lamef) + 7) / 8 ;
+
+       if (bitrate_mode == SF_BITRATE_MODE_VARIABLE)
+       {       /*
+               ** For VBR, lame_get_brate returns the minimum bitrate, so calculate the
+               ** average byterate so far.
+               */
+               calculated_byterate = psf_ftell (psf) - psf->dataoffset ;
+               calculated_byterate /= (float) psf->write_current ;
+               calculated_byterate *= (float) psf->sf.samplerate ;
+
+               return SF_MIN (byterate, (int) calculated_byterate) ;
+       }
+
+       return byterate ;
+} /* mpeg_l3_encoder_byterate */
+
+static sf_count_t
+mpeg_l3_encode_write_short_mono (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
+       sf_count_t total = 0 ;
+       int nbytes, writecount, writen ;
+
+       if ((psf->error = mpeg_l3_encoder_construct (psf)))
+               return 0 ;
+
+       while (len)
+       {       writecount = SF_MIN (len, (sf_count_t) pmpeg->frame_samples) ;
+
+               nbytes = lame_encode_buffer (pmpeg->lamef, ptr + total, NULL, writecount, pmpeg->block, pmpeg->block_len) ;
+               if (nbytes < 0)
+               {       psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
+                       break ;
+                       } ;
+
+               if (nbytes)
+               {       writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
+                       if (writen != nbytes)
+                       {       psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
+                               } ;
+                       } ;
+
+               total += writecount ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+}
+
+
+static sf_count_t
+mpeg_l3_encode_write_short_stereo (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      BUF_UNION ubuf ;
+       MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
+       sf_count_t total = 0 ;
+       int nbytes, writecount, writen ;
+
+       if ((psf->error = mpeg_l3_encoder_construct (psf)))
+               return 0 ;
+
+       const sf_count_t max_samples = SF_MIN (ARRAY_LEN (ubuf.sbuf), pmpeg->frame_samples) ;
+       while (len)
+       {       writecount = SF_MIN (len, max_samples) ;
+               /*
+                * An oversight, but lame_encode_buffer_interleaved() lacks a const.
+                * As such, need another memcpy to not cause a warning.
+                */
+               memcpy (ubuf.sbuf, ptr + total, writecount) ;
+               nbytes = lame_encode_buffer_interleaved (pmpeg->lamef, ubuf.sbuf, writecount / 2, pmpeg->block, pmpeg->block_len) ;
+               if (nbytes < 0)
+               {       psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
+                       break ;
+                       } ;
+
+               if (nbytes)
+               {       writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
+                       if (writen != nbytes)
+                       {       psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
+                               } ;
+                       } ;
+
+               total += writecount ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+}
+
+
+static sf_count_t
+mpeg_l3_encode_write_int_mono (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
+       sf_count_t total = 0 ;
+       int nbytes, writecount, writen ;
+
+       if ((psf->error = mpeg_l3_encoder_construct (psf)))
+               return 0 ;
+
+       while (len)
+       {       writecount = SF_MIN (len, (sf_count_t) pmpeg->frame_samples) ;
+
+               nbytes = lame_encode_buffer_int (pmpeg->lamef, ptr + total, NULL, writecount, pmpeg->block, pmpeg->block_len) ;
+               if (nbytes < 0)
+               {       psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
+                       break ;
+                       } ;
+
+               if (nbytes)
+               {       writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
+                       if (writen != nbytes)
+                       {       psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
+                               } ;
+                       } ;
+
+               total += writecount ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+}
+
+
+static sf_count_t
+mpeg_l3_encode_write_int_stereo (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
+       sf_count_t total = 0 ;
+       int nbytes, writecount, writen ;
+
+       if ((psf->error = mpeg_l3_encoder_construct (psf)))
+               return 0 ;
+
+       while (len)
+       {       writecount = SF_MIN (len, (sf_count_t) pmpeg->frame_samples) ;
+
+               nbytes = lame_encode_buffer_interleaved_int (pmpeg->lamef, ptr + total, writecount / 2, pmpeg->block, pmpeg->block_len) ;
+               if (nbytes < 0)
+               {       psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
+                       break ;
+                       } ;
+
+               if (nbytes)
+               {       writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
+                       if (writen != nbytes)
+                       {       psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
+                               } ;
+                       } ;
+
+               total += writecount ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+}
+
+
+static sf_count_t
+mpeg_l3_encode_write_float_mono (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
+       sf_count_t total = 0 ;
+       int nbytes, writecount, writen ;
+
+       if ((psf->error = mpeg_l3_encoder_construct (psf)))
+               return 0 ;
+
+       while (len)
+       {       writecount = SF_MIN (len, (sf_count_t) pmpeg->frame_samples) ;
+
+               if (psf->norm_float)
+                       nbytes = lame_encode_buffer_ieee_float (pmpeg->lamef, ptr + total, NULL, writecount, pmpeg->block, pmpeg->block_len) ;
+               else
+                       nbytes = lame_encode_buffer_float (pmpeg->lamef, ptr + total, NULL, writecount, pmpeg->block, pmpeg->block_len) ;
+               if (nbytes < 0)
+               {       psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
+                       break ;
+                       } ;
+
+               if (nbytes)
+               {       writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
+                       if (writen != nbytes)
+                       {       psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
+                               } ;
+                       } ;
+
+               total += writecount ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+}
+
+
+static inline void
+normalize_float (float *dest, const float *src, sf_count_t count, float norm_fact)
+{      while (--count >= 0)
+       {       dest [count] = src [count] * norm_fact ;
+               } ;
+}
+
+
+static sf_count_t
+mpeg_l3_encode_write_float_stereo (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      BUF_UNION ubuf ;
+       MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
+       sf_count_t total = 0 ;
+       int nbytes, writecount, writen ;
+
+       if ((psf->error = mpeg_l3_encoder_construct (psf)))
+               return 0 ;
+
+       const sf_count_t max_samples = SF_MIN (ARRAY_LEN (ubuf.fbuf), pmpeg->frame_samples) ;
+       while (len)
+       {       writecount = SF_MIN (len, max_samples) ;
+
+               if (psf->norm_float)
+                       nbytes = lame_encode_buffer_interleaved_ieee_float (pmpeg->lamef, ptr + total, writecount / 2, pmpeg->block, pmpeg->block_len) ;
+               else
+               {       /* Lame lacks a non-normalized interleaved float write. Bummer. */
+                       normalize_float (ubuf.fbuf, ptr + total, writecount, 1.0 / (float) 0x8000) ;
+                       nbytes = lame_encode_buffer_interleaved_ieee_float (pmpeg->lamef, ubuf.fbuf, writecount / 2, pmpeg->block, pmpeg->block_len) ;
+                       }
+
+               if (nbytes < 0)
+               {       psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
+                       break ;
+                       } ;
+
+               if (nbytes)
+               {       writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
+                       if (writen != nbytes)
+                       {       psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
+                               } ;
+                       } ;
+
+               total += writecount ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+}
+
+
+static inline void
+normalize_double (double *dest, const double *src, sf_count_t count, double norm_fact)
+{      while (--count >= 0)
+       {       dest [count] = src [count] * norm_fact ;
+               } ;
+}
+
+
+static sf_count_t
+mpeg_l3_encode_write_double_mono (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      BUF_UNION ubuf ;
+       MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
+       sf_count_t total = 0 ;
+       int nbytes, writecount, writen ;
+
+       if ((psf->error = mpeg_l3_encoder_construct (psf)))
+               return 0 ;
+
+       const sf_count_t max_samples = SF_MIN (ARRAY_LEN (ubuf.dbuf), pmpeg->frame_samples) ;
+       while (len)
+       {       writecount = SF_MIN (len, max_samples) ;
+
+               if (psf->norm_double)
+                       nbytes = lame_encode_buffer_ieee_double (pmpeg->lamef, ptr + total, NULL, writecount, pmpeg->block, pmpeg->block_len) ;
+               else
+               {       /* Lame lacks non-normalized double writing */
+                       normalize_double (ubuf.dbuf, ptr + total, writecount, 1.0 / (double) 0x8000) ;
+                       nbytes = lame_encode_buffer_ieee_double (pmpeg->lamef, ubuf.dbuf, NULL, writecount, pmpeg->block, pmpeg->block_len) ;
+                       }
+
+               if (nbytes < 0)
+               {       psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
+                       break ;
+                       } ;
+
+               if (nbytes)
+               {       writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
+                       if (writen != nbytes)
+                       {       psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
+                               } ;
+                       } ;
+
+               total += writecount ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+}
+
+
+static sf_count_t
+mpeg_l3_encode_write_double_stereo (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      BUF_UNION ubuf ;
+       MPEG_L3_ENC_PRIVATE *pmpeg = (MPEG_L3_ENC_PRIVATE*) psf->codec_data ;
+       sf_count_t total = 0 ;
+       int nbytes, writecount, writen ;
+
+       if ((psf->error = mpeg_l3_encoder_construct (psf)))
+               return 0 ;
+
+       const sf_count_t max_samples = SF_MIN (ARRAY_LEN (ubuf.dbuf), pmpeg->frame_samples) ;
+       while (len)
+       {       writecount = SF_MIN (len, max_samples) ;
+
+               if (psf->norm_double)
+                       nbytes = lame_encode_buffer_interleaved_ieee_double (pmpeg->lamef, ptr + total, writecount / 2, pmpeg->block, pmpeg->block_len) ;
+               else
+               {       /* Lame lacks interleaved non-normalized double writing */
+                       normalize_double (ubuf.dbuf, ptr + total, writecount, 1.0 / (double) 0x8000) ;
+                       nbytes = lame_encode_buffer_interleaved_ieee_double (pmpeg->lamef, ubuf.dbuf, writecount / 2, pmpeg->block, pmpeg->block_len) ;
+                       }
+
+               if (nbytes < 0)
+               {       psf_log_printf (psf, "lame_encode_buffer returned %d\n", nbytes) ;
+                       break ;
+                       } ;
+
+               if (nbytes)
+               {       writen = psf_fwrite (pmpeg->block, 1, nbytes, psf) ;
+                       if (writen != nbytes)
+                       {       psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", writen, nbytes) ;
+                               } ;
+                       } ;
+
+               total += writecount ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+}
+
+#else /* HAVE_MPEG */
+
+int
+mpeg_l3_encoder_init (SF_PRIVATE *psf, int UNUSED (vbr))
+{      psf_log_printf (psf, "This version of libsndfile was compiled without MPEG Layer 3 encoding support.\n") ;
+       return SFE_UNIMPLEMENTED ;
+} /* mpeg_l3_encoder_init */
+
+#endif
index 5e8f1a3..0e05181 100644 (file)
@@ -128,8 +128,14 @@ wavlike_msadpcm_init       (SF_PRIVATE *psf, int blockalign, int samplesperblock)
        if (psf->file.mode == SFM_WRITE)
                samplesperblock = 2 + 2 * (blockalign - 7 * psf->sf.channels) / psf->sf.channels ;
 
-       if (blockalign < 7 * psf->sf.channels)
-       {       psf_log_printf (psf, "*** Error blockalign (%d) should be > %d.\n", blockalign, 7 * psf->sf.channels) ;
+       /* There's 7 samples per channel in the preamble of each block */
+       if (samplesperblock < 7 * psf->sf.channels)
+       {       psf_log_printf (psf, "*** Error samplesperblock (%d) should be >= %d.\n", samplesperblock, 7 * psf->sf.channels) ;
+               return SFE_INTERNAL ;
+               } ;
+
+       if (2 * blockalign < samplesperblock * psf->sf.channels)
+       {       psf_log_printf (psf, "*** Error blockalign (%d) should be >= %d.\n", blockalign, samplesperblock * psf->sf.channels / 2) ;
                return SFE_INTERNAL ;
                } ;
 
@@ -224,7 +230,7 @@ msadpcm_decode_block        (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms)
                return 1 ;
                } ;
 
-       if ((k = psf_fread (pms->block, 1, pms->blocksize, psf)) != pms->blocksize)
+       if ((k = (int) psf_fread (pms->block, 1, pms->blocksize, psf)) != pms->blocksize)
        {       psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pms->blocksize) ;
                if (k <= 0)
                        return 1 ;
@@ -349,7 +355,7 @@ msadpcm_read_s      (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       readcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
 
-               if ((count = msadpcm_read_block (psf, pms, ptr, readcount)) <= 0)
+               if ((count = (int) msadpcm_read_block (psf, pms, ptr, readcount)) <= 0)
                        return -1 ;
 
                total += count ;
@@ -376,9 +382,9 @@ msadpcm_read_i      (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = ARRAY_LEN (ubuf.sbuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
 
-               if ((count = msadpcm_read_block (psf, pms, sptr, readcount)) <= 0)
+               if ((count = (int) msadpcm_read_block (psf, pms, sptr, readcount)) <= 0)
                        return -1 ;
 
                for (k = 0 ; k < readcount ; k++)
@@ -408,9 +414,9 @@ msadpcm_read_f      (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = ARRAY_LEN (ubuf.sbuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
 
-               if ((count = msadpcm_read_block (psf, pms, sptr, readcount)) <= 0)
+               if ((count = (int) msadpcm_read_block (psf, pms, sptr, readcount)) <= 0)
                        return -1 ;
 
                for (k = 0 ; k < readcount ; k++)
@@ -440,9 +446,9 @@ msadpcm_read_d      (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = ARRAY_LEN (ubuf.sbuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
 
-               if ((count = msadpcm_read_block (psf, pms, sptr, readcount)) <= 0)
+               if ((count = (int) msadpcm_read_block (psf, pms, sptr, readcount)) <= 0)
                        return -1 ;
 
                for (k = 0 ; k < readcount ; k++)
@@ -627,7 +633,7 @@ msadpcm_encode_block        (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms)
 
        /* Write the block to disk. */
 
-       if ((k = psf_fwrite (pms->block, 1, pms->blocksize, psf)) != pms->blocksize)
+       if ((k = (int) psf_fwrite (pms->block, 1, pms->blocksize, psf)) != pms->blocksize)
                psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pms->blocksize) ;
 
        memset (pms->samples, 0, pms->samplesperblock * sizeof (short)) ;
@@ -673,7 +679,7 @@ msadpcm_write_s     (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
        while (len > 0)
        {       writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
 
-               count = msadpcm_write_block (psf, pms, ptr, writecount) ;
+               count = (int) msadpcm_write_block (psf, pms, ptr, writecount) ;
 
                total += count ;
                len -= count ;
@@ -699,10 +705,10 @@ msadpcm_write_i   (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = ARRAY_LEN (ubuf.sbuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        sptr [k] = ptr [total + k] >> 16 ;
-               count = msadpcm_write_block (psf, pms, sptr, writecount) ;
+               count = (int) msadpcm_write_block (psf, pms, sptr, writecount) ;
                total += count ;
                len -= writecount ;
                if (count != writecount)
@@ -729,10 +735,10 @@ msadpcm_write_f   (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = ARRAY_LEN (ubuf.sbuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        sptr [k] = psf_lrintf (normfact * ptr [total + k]) ;
-               count = msadpcm_write_block (psf, pms, sptr, writecount) ;
+               count = (int) msadpcm_write_block (psf, pms, sptr, writecount) ;
                total += count ;
                len -= writecount ;
                if (count != writecount)
@@ -759,10 +765,10 @@ msadpcm_write_d   (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = ARRAY_LEN (ubuf.sbuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        sptr [k] = psf_lrint (normfact * ptr [total + k]) ;
-               count = msadpcm_write_block (psf, pms, sptr, writecount) ;
+               count = (int) msadpcm_write_block (psf, pms, sptr, writecount) ;
                total += count ;
                len -= writecount ;
                if (count != writecount)
index 40f56f5..96d6ad2 100644 (file)
@@ -702,7 +702,7 @@ static int
 psf_nms_adpcm_decode_block (SF_PRIVATE *psf, NMS_ADPCM_PRIVATE *pnms)
 {      int k ;
 
-       if ((k = psf_fread (pnms->block, sizeof (short), pnms->shortsperblock, psf)) != pnms->shortsperblock)
+       if ((k = (int) psf_fread (pnms->block, sizeof (short), pnms->shortsperblock, psf)) != pnms->shortsperblock)
        {       psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pnms->shortsperblock) ;
                memset (pnms->block + (k * sizeof (short)), 0, (pnms->shortsperblock - k) * sizeof (short)) ;
                } ;
@@ -785,7 +785,7 @@ nms_adpcm_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = SF_BUFFER_LEN / sizeof (short) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = nms_adpcm_read_block (psf, pnms, sptr, readcount) ;
 
                for (k = 0 ; k < readcount ; k++)
@@ -818,7 +818,7 @@ nms_adpcm_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = SF_BUFFER_LEN / sizeof (short) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = nms_adpcm_read_block (psf, pnms, sptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = normfact * sptr [k] ;
@@ -850,7 +850,7 @@ nms_adpcm_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = SF_BUFFER_LEN / sizeof (short) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = nms_adpcm_read_block (psf, pnms, sptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = normfact * (double) (sptr [k]) ;
@@ -875,7 +875,7 @@ psf_nms_adpcm_encode_block (SF_PRIVATE *psf, NMS_ADPCM_PRIVATE *pnms)
                endswap_short_array ((signed short *) pnms->block, pnms->shortsperblock) ;
 
        /* Write the block to disk. */
-       if ((k = psf_fwrite (pnms->block, sizeof (short), pnms->shortsperblock, psf)) != pnms->shortsperblock)
+       if ((k = (int) psf_fwrite (pnms->block, sizeof (short), pnms->shortsperblock, psf)) != pnms->shortsperblock)
                psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pnms->shortsperblock) ;
 
        pnms->sample_curr = 0 ;
@@ -945,7 +945,7 @@ nms_adpcm_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = SF_BUFFER_LEN / sizeof (short) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        sptr [k] = ptr [total + k] >> 16 ;
                count = nms_adpcm_write_block (psf, pnms, sptr, writecount) ;
@@ -976,7 +976,7 @@ nms_adpcm_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = SF_BUFFER_LEN / sizeof (short) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        sptr [k] = psf_lrintf (normfact * ptr [total + k]) ;
                count = nms_adpcm_write_block (psf, pnms, sptr, writecount) ;
@@ -1008,7 +1008,7 @@ nms_adpcm_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        sptr = ubuf.sbuf ;
        bufferlen = SF_BUFFER_LEN / sizeof (short) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        sptr [k] = psf_lrint (normfact * ptr [total + k]) ;
                count = nms_adpcm_write_block (psf, pnms, sptr, writecount) ;
index 9be6e91..dfa446e 100644 (file)
@@ -410,10 +410,10 @@ static void
 opus_print_header (SF_PRIVATE *psf, OpusHeader *h)
 {      psf_log_printf (psf, "Opus Header Metadata\n") ;
        psf_log_printf (psf, "  OggOpus version  : %d\n", h->version) ;
-       psf_log_printf (psf, "  Channels                 : %d\n", h->channels) ;
-       psf_log_printf (psf, "  Preskip           : %d samples @48kHz\n", h->preskip) ;
+       psf_log_printf (psf, "  Channels         : %d\n", h->channels) ;
+       psf_log_printf (psf, "  Preskip          : %d samples @48kHz\n", h->preskip) ;
        psf_log_printf (psf, "  Input Samplerate : %d Hz\n", h->input_samplerate) ;
-       psf_log_printf (psf, "  Gain                     : %d.%d\n", arith_shift_right (h->gain & 0xF0, 8), h->gain & 0x0F) ;
+       psf_log_printf (psf, "  Gain             : %d.%d\n", arith_shift_right (h->gain & 0xF0, 8), h->gain & 0x0F) ;
        psf_log_printf (psf, "  Channel Mapping  : ") ;
        switch (h->channel_mapping)
        {       case 0 :        psf_log_printf (psf, "0 (mono or stereo)\n") ; break ;
@@ -426,7 +426,7 @@ opus_print_header (SF_PRIVATE *psf, OpusHeader *h)
        {       int i ;
                psf_log_printf (psf, "   streams total   : %d\n", h->nb_streams) ;
                psf_log_printf (psf, "   streams coupled : %d\n", h->nb_coupled) ;
-               psf_log_printf (psf, "  stream mapping : [") ;
+               psf_log_printf (psf, "   stream mapping : [") ;
                for (i = 0 ; i < h->channels - 1 ; i++)
                        psf_log_printf (psf, "%d,", h->stream_map [i]) ;
                psf_log_printf (psf, "%d]\n", h->stream_map [i]) ;
index 5f53651..1b00af5 100644 (file)
@@ -1,4 +1,5 @@
 /*
+** Copyright (C) 2018-2021 Arthur Taylor <art@ified.ca>
 ** Copyright (C) 2002-2016 Erik de Castro Lopo <erikd@mega-nerd.com>
 ** Copyright (C) 2002-2005 Michael Smith <msmith@xiph.org>
 ** Copyright (C) 2007 John ffitch
@@ -19,7 +20,7 @@
 */
 
 /*
-**  Much of this code is based on the examples in libvorbis from the
+** 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
 **
@@ -78,6 +79,9 @@
 
 #include "ogg.h"
 
+/* How many seconds in the future to not bother bisection searching for. */
+#define VORBIS_SEEK_THRESHOLD 2
+
 typedef int convert_func (SF_PRIVATE *psf, int, void *, int, int, float **) ;
 
 static int     vorbis_read_header (SF_PRIVATE *psf) ;
@@ -85,7 +89,9 @@ static int    vorbis_write_header (SF_PRIVATE *psf, int calc_length) ;
 static int     vorbis_close (SF_PRIVATE *psf) ;
 static int     vorbis_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
 static int     vorbis_byterate (SF_PRIVATE *psf) ;
-static sf_count_t      vorbis_calculate_page_duration (SF_PRIVATE *psf) ;
+static int     vorbis_calculate_granulepos (SF_PRIVATE *psf, uint64_t *gp_out) ;
+static int     vorbis_skip (SF_PRIVATE *psf, uint64_t target_gp) ;
+static int     vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp) ;
 static sf_count_t      vorbis_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
 static sf_count_t      vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
 static sf_count_t      vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
@@ -115,26 +121,22 @@ static STR_PAIRS vorbis_metatypes [] =
        {       SF_STR_ALBUM,           "Album" },
        {       SF_STR_LICENSE,         "License" },
        {       SF_STR_TRACKNUMBER,     "Tracknumber" },
-       {       SF_STR_GENRE,           "Genre" },
+       {       SF_STR_GENRE,           "Genre" },
 } ;
 
 typedef struct
-{      /* Count current location */
-       sf_count_t loc ;
+{      /* Current granule position. */
+       uint64_t gp ;
        /* Struct that stores all the static vorbis bitstream settings */
        vorbis_info     vinfo ;
        /* Struct that stores all the bitstream user comments */
        vorbis_comment vcomment ;
-       /* Ventral working state for the packet->PCM decoder */
+       /* Central working state for the packet->PCM decoder */
        vorbis_dsp_state vdsp ;
        /* Local working space for packet->PCM decode */
        vorbis_block vblock ;
-
        /* Encoding quality in range [0.0, 1.0]. */
        double quality ;
-
-       /* Current granule position. */
-       uint64_t pcm_current ;
        /* Offset of the first samples' granule position. */
        uint64_t pcm_start ;
        /* Last valid samples' granule position. */
@@ -147,9 +149,10 @@ static int
 vorbis_read_header (SF_PRIVATE *psf)
 {      OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
        VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
-       sf_count_t duration ;
        int printed_metadata_msg = 0 ;
-       int i, k, nn ;
+       int i, nn ;
+       sf_count_t last_page ;
+       sf_count_t saved_offset ;
 
        /*
        **  The first page of the Ogg stream we are told to try and open as Vorbis
@@ -184,8 +187,8 @@ vorbis_read_header (SF_PRIVATE *psf)
        **      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
+       **      They're likely large and may span multiple pages.  Thus we read
+       **      and submit data until we get our two packets, 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.
        */
@@ -231,32 +234,23 @@ vorbis_read_header (SF_PRIVATE *psf)
        psf->dataoffset = ogg_sync_ftell (psf) ;
 
        /*
-       **      Caculate the granule position offset. The first page with a payload
+       **      Calculate the granule position offset. The first page with a payload
        **      packet shouldn't end in a continued packet. The difference between the
        **      page's granule position and the sum of frames on the page tells us the
        **      granule position offset.
        **      See https://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-132000A.2
        */
        ogg_stream_unpack_page (psf, odata) ;
-       vdata->pcm_start = odata->pkt [odata->pkt_len - 1].granulepos ;
-       duration = vorbis_calculate_page_duration (psf) ;
-
-       if (duration < (sf_count_t) vdata->pcm_start)
-               vdata->pcm_start -= duration ;
-       else
-               vdata->pcm_start = 0 ;
+       vorbis_calculate_granulepos (psf, &vdata->pcm_start) ;
+       vdata->gp = vdata->pcm_start ;
 
        /*
        **      Find the end of the stream, save it. Only works if the file is seekable.
        */
-       vdata->loc = vdata->pcm_start ;
        vdata->pcm_end = (uint64_t) -1 ;
        psf->datalength = psf->filelength ;
        if (!psf->is_pipe)
-       {       sf_count_t last_page ;
-               sf_count_t saved_offset ;
-
-               saved_offset = ogg_sync_ftell (psf) ;
+       {       saved_offset = ogg_sync_ftell (psf) ;
                last_page = ogg_sync_last_page_before (psf, odata, &vdata->pcm_end, psf->filelength, odata->ostream.serialno) ;
                if (last_page > 0)
                {       if (!ogg_page_eos (&odata->opage))
@@ -277,10 +271,10 @@ vorbis_read_header (SF_PRIVATE *psf)
                psf_log_printf (psf, "PCM end     : unknown\n") ;
 
        /* Throw the comments plus a few lines about the bitstream we're decoding. */
-       for (k = 0 ; k < ARRAY_LEN (vorbis_metatypes) ; k++)
+       for (i = 0 ; i < ARRAY_LEN (vorbis_metatypes) ; i++)
        {       char *dd ;
 
-               dd = vorbis_comment_query (&vdata->vcomment, vorbis_metatypes [k].name, 0) ;
+               dd = vorbis_comment_query (&vdata->vcomment, vorbis_metatypes [i].name, 0) ;
                if (dd == NULL)
                        continue ;
 
@@ -289,8 +283,8 @@ vorbis_read_header (SF_PRIVATE *psf)
                        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_store_string (psf, vorbis_metatypes [i].id, dd) ;
+               psf_log_printf (psf, "  %-10s : %s\n", vorbis_metatypes [i].name, dd) ;
                } ;
        psf_log_printf (psf, "End\n") ;
 
@@ -306,7 +300,7 @@ vorbis_read_header (SF_PRIVATE *psf)
 
        /*      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. */
+       **      for vdsp here. */
        vorbis_block_init (&vdata->vdsp, &vdata->vblock) ;
 
        return 0 ;
@@ -334,7 +328,7 @@ vorbis_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
        if (ret)
                return SFE_BAD_OPEN_FORMAT ;
 
-       vdata->loc = 0 ;
+       vdata->gp = 0 ;
 
        /* add a comment */
        vorbis_comment_init (&vdata->vcomment) ;
@@ -348,15 +342,15 @@ vorbis_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
 
                switch (psf->strings.data [k].type)
                {       case SF_STR_TITLE :                     name = "TITLE" ; break ;
-                       case SF_STR_COPYRIGHT :         name = "COPYRIGHT" ; 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 ;
-                       case SF_STR_TRACKNUMBER :       name = "Tracknumber" ; break ;
-                       case SF_STR_GENRE :             name = "Genre" ; break ;
+                       case SF_STR_TRACKNUMBER :       name = "Tracknumber" ; break ;
+                       case SF_STR_GENRE :                     name = "Genre" ; break ;
 
                        default : continue ;
                        } ;
@@ -636,9 +630,9 @@ vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *t
                        len -= samples ;
                        /* tell libvorbis how many samples we actually consumed */
                        vorbis_synthesis_read (&vdata->vdsp, samples) ;
-                       vdata->loc += samples ;
+                       vdata->gp += samples ;
                        if (len == 0)
-                               return i ; /* Is this necessary */
+                               return i ;
                        } ;
 
                /* Out of samples, load the next packet. */
@@ -648,9 +642,9 @@ vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *t
                        if (nn <= 0)
                                return i ;
                        if (nn == 2)
-                       {       /* Ran over a hole. loc is now out of date, need to recalculate. */
-                               vdata->loc = odata->pkt [odata->pkt_len - 1].granulepos ;
-                               vdata->loc -= vorbis_calculate_page_duration (psf) ;
+                       {       /* Ran over a hole. gp is now out of date, need to recalculate. */
+                               vorbis_synthesis_restart (&vdata->vdsp) ;
+                               vorbis_calculate_granulepos (psf, &vdata->gp) ;
                                }
                        } ;
 
@@ -722,7 +716,7 @@ vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata
                        } ;
                } ;
 
-       vdata->loc += in_frames ;
+       vdata->gp += in_frames ;
 } /* vorbis_write_data */
 
 
@@ -791,11 +785,131 @@ vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t lens)
        return lens ;
 } /* vorbis_write_d */
 
+static int
+vorbis_skip (SF_PRIVATE *psf, uint64_t target)
+{      OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
+       VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
+       ogg_packet *pkt ;
+       int thisblock, lastblock, nn ;
+       const int blocksize = vorbis_info_blocksize (&vdata->vinfo, 1) ;
+
+       /*      Read out any samples that may be in the decoder from a seek without a
+       **      search. */
+       thisblock = vorbis_synthesis_pcmout (&vdata->vdsp, NULL) ;
+       if (thisblock > 0)
+       {       if ((uint64_t) thisblock + vdata->gp >= target)
+                       thisblock = SF_MIN (thisblock, (int) (target - vdata->gp)) ;
+
+               vorbis_synthesis_read (&vdata->vdsp, thisblock) ;
+               vdata->gp += thisblock ;
+               if (vdata->gp == target)
+                       return 0 ;
+               } ;
+
+       /* Read through packets that are before our target */
+       lastblock = 0 ;
+       for ( ; vdata->gp < target ; )
+       {       /* Ensure there are unpacked packets. */
+               if (odata->pkt_indx == odata->pkt_len)
+               {       /* Page out of packets, load and unpack the next page. */
+                       nn = ogg_stream_unpack_page (psf, odata) ;
+                       if (nn < 0)
+                               return nn ;
+                       if (nn == 0)
+                               break ;
+                       if (nn == 2)
+                       {       /* Ran over a hole. gp is now out of date, need to recalculate. */
+                               vorbis_synthesis_restart (&vdata->vdsp) ;
+                               vorbis_calculate_granulepos (psf, &vdata->gp) ;
+                               if (target < vdata->gp)
+                               {       /* Our target is inside the hole :-( */
+                                       return 0 ;
+                                       } ;
+                               } ;
+                       } ;
+
+               pkt = &odata->pkt [odata->pkt_indx] ;
+               thisblock = vorbis_packet_blocksize (&vdata->vinfo, pkt) ;
+               if (thisblock < 0)
+               {       /* Not an audio packet */
+                       odata->pkt_indx++ ;
+                       continue ;
+                       } ;
+
+               if (lastblock)
+               {       vdata->gp += ((lastblock + thisblock) / 4) ;
+                       } ;
+
+               /* Check to see if the block contains our target */
+               if (vdata->gp + ((thisblock + blocksize) / 4) >= target)
+                       break ;
+
+               /* Block is before the target. Track for state, but don't decode. */
+               odata->pkt_indx++ ;
+               vorbis_synthesis_trackonly (&vdata->vblock, pkt) ;
+               vorbis_synthesis_blockin (&vdata->vdsp, &vdata->vblock) ;
+               lastblock = thisblock ;
+               } ;
+
+       /*      We are at the correct block, but still need to consume samples to reach
+       **      our target. */
+       vorbis_read_sample (psf, (void *) NULL, (target - vdata->gp) * psf->sf.channels, vorbis_rnull) ;
+
+       return 0 ;
+} /* vorbis_skip */
+
+static int
+vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp)
+{      OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
+       VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
+       uint64_t best_gp, search_target_gp ;
+       int ret ;
+
+       /* Can't bisect a file we don't know the end of (cannot seek). */
+       if (vdata->pcm_end == (uint64_t) -1)
+               return 0 ;
+
+       /* If the target is for the near future, don't bother bisecting, just skip
+       ** to it. */
+       if (target_gp >= vdata->gp &&
+               target_gp - vdata->gp < ((unsigned) (VORBIS_SEEK_THRESHOLD) * psf->sf.samplerate))
+               return 0 ;
+
+       /*      Search for a position a half large-block before our target. As Vorbis is
+       **      lapped, every sample position come from two blocks, the "left" half of
+       **      one block and the "right" half of the previous block.  The granule
+       **      position of an Ogg page of a Vorbis stream is the sample offset of the
+       **      last finished sample in the stream that can be decoded from a page.  A
+       **      page also contains another half-block of samples waiting to be lapped
+       **      with the first half-block of samples from the next page.
+       **
+       **      Searching for a sample one half of a large block before our target
+       **      guarantees we always load a page containing the previous half block
+       **      required to decode the target.  Downside is we can't use best_gp
+       **      parameter of the page seek function. */
+       search_target_gp = vorbis_info_blocksize (&vdata->vinfo, 1) / 2 ;
+       search_target_gp = search_target_gp < target_gp ? target_gp - search_target_gp : 0 ;
+
+       ret = ogg_stream_seek_page_search (psf, odata, search_target_gp, vdata->pcm_start,
+                       vdata->pcm_end, &best_gp, psf->dataoffset, vdata->last_page) ;
+       if (ret < 0)
+               return ret ;
+
+       ret = ogg_stream_unpack_page (psf, odata) ;
+       if (ret > 0)
+       {       /* Reset the decoder, recalculate position */
+               vorbis_synthesis_restart (&vdata->vdsp) ;
+               ret = vorbis_calculate_granulepos (psf, &vdata->gp) ;
+               } ;
+
+       return ret ;
+} /* vorbis_seek_trysearch */
+
 static sf_count_t
 vorbis_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 ;
-       sf_count_t target ;
+       uint64_t target_gp ;
        int ret ;
 
        if (odata == NULL || vdata == NULL)
@@ -807,63 +921,30 @@ vorbis_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
                } ;
 
        if (psf->file.mode == SFM_READ)
-       {       target = offset + vdata->pcm_start ;
+       {       target_gp = (uint64_t) offset + vdata->pcm_start ;
 
-               /*
-               ** If the end of the file is know, and the seek isn't for the near
-               ** future, do a search of the file for a good place to start.
-               */
-               ret = 0 ;
-               if ((vdata->pcm_end != (uint64_t) -1) &&
-                       (target < vdata->loc || target - vdata->loc > (2 * psf->sf.samplerate)))
-               {       uint64_t best_gp ;
-
-                       best_gp = vdata->pcm_start ;
-
-                       ret = ogg_stream_seek_page_search (psf, odata, target, vdata->pcm_start,
-                               vdata->pcm_end, &best_gp, psf->dataoffset, vdata->last_page) ;
-                       if (ret >= 0)
-                       {       ret = ogg_stream_unpack_page (psf, odata) ;
-                               if (ret == 1)
-                               {       vdata->loc = best_gp ;
-                                       vorbis_synthesis_restart (&vdata->vdsp) ;
-                                       } ;
-                               } ;
-                       } ;
+               ret = vorbis_seek_trysearch (psf, target_gp) ;
 
-               if (ret >= 0 && offset + (sf_count_t) vdata->pcm_start >= vdata->loc)
-                       target = offset + vdata->pcm_start - vdata->loc ;
-               else
+               if (ret < 0 || vdata->gp > target_gp)
                {       /* Search failed (bad data?), reset to the beginning of the stream. */
+                       psf_log_printf (psf, "Vorbis: Seek search failed. Reading through stream from start.\n") ;
                        ogg_stream_reset_serialno (&odata->ostream, odata->ostream.serialno) ;
                        odata->pkt_len = 0 ;
                        odata->pkt_indx = 0 ;
                        ogg_sync_fseek (psf, psf->dataoffset, SEEK_SET) ;
-                       vdata->loc = 0 ;
+                       vdata->gp = vdata->pcm_start ;
                        vorbis_synthesis_restart (&vdata->vdsp) ;
-                       target = offset ;
                        } ;
 
-               while (target > 0)
-               {       sf_count_t m = target > 4096 ? 4096 : target ;
-
-                       /*
-                       **      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.
-                       */
-                       vorbis_read_sample (psf, (void *) NULL, m * psf->sf.channels, vorbis_rnull) ;
-
-                       target -= m ;
-                       } ;
+               vorbis_skip (psf, target_gp) ;
 
-               return vdata->loc - vdata->pcm_start ;
+               return vdata->gp - vdata->pcm_start ;
                } ;
 
-       return 0 ;
+       psf->error = SFE_BAD_SEEK ;
+       return ((sf_count_t) -1) ;
 } /* vorbis_seek */
 
-
 static int
 vorbis_byterate (SF_PRIVATE *psf)
 {
@@ -873,27 +954,88 @@ vorbis_byterate (SF_PRIVATE *psf)
        return -1 ;
 } /* vorbis_byterate */
 
-static sf_count_t
-vorbis_calculate_page_duration (SF_PRIVATE *psf)
+static int
+vorbis_calculate_granulepos (SF_PRIVATE *psf, uint64_t *gp_out)
 {      OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
        VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
-       long thisblock, lastblock ;
-       sf_count_t duration ;
-       int i ;
-
-       lastblock = -1 ;
-       duration = 0 ;
-       for (i = 0 ; i < odata->pkt_len ; i++)
-       {       thisblock = vorbis_packet_blocksize (&vdata->vinfo, &(odata->pkt [i])) ;
-               if (thisblock >= 0)
-               {       if (lastblock != -1)
-                               duration += (lastblock + thisblock) >> 2 ;
-                       lastblock = thisblock ;
+       ogg_packet *pkt ;
+       uint64_t last_gp ;
+       int thisblock, lastblock, i ;
+       unsigned duration ;
+
+       /*      Calculate the granule position when dropped into the middle of a stream
+       **      with an un-primed decoder.
+       **
+       **      Normally the last unpacked packet contains the granule position of the
+       **      last completed sample from decoding all the blocks in the page's
+       **      packets.  By calculating how many samples we can decode from the blocks
+       **      in the page's packets and subtracting it from the final packet's granule
+       **      position we get the position of the first sample to be output from the
+       **      decoder after it primes.  That is, the current granule position.
+       **
+       **      However, there is an ambiguity if this is the last page of a stream. The
+       **      last page of a stream may have a granule position of fewer samples than
+       **      the page actually contains.  The excess samples are padding leftovers
+       **      for and exact sample length file. */
+
+       if (odata->pkt_len > 0)
+       {       /* Calculate how many samples can be decoded from blocks in this page,
+               ** accounting for the fact that blocks are 1/2 lapped. */
+               lastblock = -1 ;
+               duration = 0 ;
+               pkt = odata->pkt ;
+               for (i = 0 ; i < odata->pkt_len ; i++)
+               {       thisblock = vorbis_packet_blocksize (&vdata->vinfo, &pkt [i]) ;
+                       if (thisblock >= 0)
+                       {       if (lastblock != -1)
+                                       duration += (lastblock + thisblock) >> 2 ;
+                               lastblock = thisblock ;
+                               } ;
+                       } ;
+
+               pkt = &odata->pkt [odata->pkt_len - 1] ;
+               last_gp = pkt->granulepos ;
+               if (last_gp == (uint64_t) -1)
+               {       psf_log_printf (psf, "Vorbis: Ogg page has no granule position, cannot calculate sample position!\n") ;
+                       psf->error = SFE_MALFORMED_FILE ;
+                       return -1 ;
+                       } ;
+
+               if (pkt->e_o_s)
+               {       if (last_gp <= duration)
+                       {       /*      Corner case: One page stream. Ogg/Vorbis spec dictates the
+                               **      granule position offset MUST be zero, hence this first (and
+                               **      only) page must start at 0. */
+                               *gp_out = 0 ;
+                               return 1 ;
+                               } ;
+
+                       /*      Otherwise, we cannot know where we are without looking at the
+                       **      blocks of the previous page.  (The granule position of the
+                       **      previous page is not enough, we need the block sizes.)
+                       **
+                       **      We avoid this case by never allowing a bisection search to seek
+                       **      beyond the second-to-last page, so the last page is always
+                       **      approached with a known location and never dropped into.
+                       **
+                       **      The only way we should be able to end up here is if there was a
+                       **      hole in stream just before the last page, in which case all bets
+                       **      are off anyways. */
+                       psf_log_printf (psf, "Vorbis: Cannot calculate ambiguous last page duration. Sample count may be wrong.\n") ;
                        } ;
+
+               if (last_gp < duration)
+               {       psf_log_printf (psf, "Vorbis: Granule position is nonsensical! (Missing end-of-stream marker?)\n") ;
+                       psf->error = SFE_MALFORMED_FILE ;
+                       return -1 ;
+                       } ;
+
+               *gp_out = last_gp - duration ;
+               return 1 ;
                } ;
 
-       return duration ;
-}
+       return 0 ;
+} /* vorbis_calculate_granulepos */
 
 #else /* HAVE_EXTERNAL_XIPH_LIBS */
 
index 459bc46..871931c 100644 (file)
--- a/src/paf.c
+++ b/src/paf.c
@@ -493,7 +493,7 @@ paf24_read_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24)
                } ;
 
        /* Read the block. */
-       if ((k = psf_fread (ppaf24->block, 1, ppaf24->blocksize, psf)) != ppaf24->blocksize)
+       if ((k = (int) psf_fread (ppaf24->block, 1, ppaf24->blocksize, psf)) != ppaf24->blocksize)
                psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, ppaf24->blocksize) ;
 
        /* Do endian swapping if necessary. */
@@ -549,7 +549,7 @@ paf24_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = paf24_read (psf, ppaf24, iptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = iptr [k] >> 16 ;
@@ -591,7 +591,7 @@ paf24_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = paf24_read (psf, ppaf24, iptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = normfact * iptr [k] ;
@@ -619,7 +619,7 @@ paf24_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = paf24_read (psf, ppaf24, iptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = normfact * iptr [k] ;
@@ -668,7 +668,7 @@ paf24_write_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24)
                } ;
 
        /* Write block to disk. */
-       if ((k = psf_fwrite (ppaf24->block, 1, ppaf24->blocksize, psf)) != ppaf24->blocksize)
+       if ((k = (int) psf_fwrite (ppaf24->block, 1, ppaf24->blocksize, psf)) != ppaf24->blocksize)
                psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, ppaf24->blocksize) ;
 
        if (ppaf24->sample_count < ppaf24->write_block * PAF24_SAMPLES_PER_BLOCK + ppaf24->write_count)
@@ -718,7 +718,7 @@ paf24_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        iptr [k] = ptr [total + k] << 16 ;
                count = paf24_write (psf, ppaf24, iptr, writecount) ;
@@ -772,7 +772,7 @@ paf24_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        iptr [k] = psf_lrintf (normfact * ptr [total + k]) ;
                count = paf24_write (psf, ppaf24, iptr, writecount) ;
@@ -803,7 +803,7 @@ paf24_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        iptr [k] = psf_lrint (normfact * ptr [total+k]) ;
                count = paf24_write (psf, ppaf24, iptr, writecount) ;
index 3ea0d09..7e5fdf6 100644 (file)
--- a/src/pcm.c
+++ b/src/pcm.c
@@ -134,10 +134,11 @@ pcm_init (SF_PRIVATE *psf)
        else if ((SF_CODEC (psf->sf.format)) == SF_FORMAT_PCM_U8)
                chars = SF_CHARS_UNSIGNED ;
 
-       if (CPU_IS_BIG_ENDIAN)
-               psf->data_endswap = (psf->endian == SF_ENDIAN_BIG) ? SF_FALSE : SF_TRUE ;
-       else
-               psf->data_endswap = (psf->endian == SF_ENDIAN_LITTLE) ? SF_FALSE : SF_TRUE ;
+#if CPU_IS_BIG_ENDIAN
+       psf->data_endswap = (psf->endian == SF_ENDIAN_BIG) ? SF_FALSE : SF_TRUE ;
+#else
+       psf->data_endswap = (psf->endian == SF_ENDIAN_LITTLE) ? SF_FALSE : SF_TRUE ;
+#endif
 
        if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
        {       switch (psf->bytewidth * 0x10000 + psf->endian + chars)
@@ -283,37 +284,37 @@ pcm_init (SF_PRIVATE *psf)
 
 static inline void
 sc2s_array     (const signed char *src, int count, short *dest)
-{      while (--count >= 0)
-       {       dest [count] = ((uint16_t) src [count]) << 8 ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = ((uint16_t) src [i]) << 8 ;
                } ;
 } /* sc2s_array */
 
 static inline void
 uc2s_array     (const unsigned char *src, int count, short *dest)
-{      while (--count >= 0)
-       {       dest [count] = (((uint32_t) src [count]) - 0x80) << 8 ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = (((uint32_t) src [i]) - 0x80) << 8 ;
                } ;
 } /* uc2s_array */
 
 static inline void
 let2s_array (const tribyte *src, int count, short *dest)
-{      while (--count >= 0)
-               dest [count] = LET2H_16_PTR (src [count].bytes) ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = LET2H_16_PTR (src [i].bytes) ;
 } /* let2s_array */
 
 static inline void
 bet2s_array (const tribyte *src, int count, short *dest)
-{      while (--count >= 0)
-               dest [count] = BET2H_16_PTR (src [count].bytes) ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = BET2H_16_PTR (src [i].bytes) ;
 } /* bet2s_array */
 
 static inline void
 lei2s_array (const int *src, int count, short *dest)
 {      int value ;
 
-       while (--count >= 0)
-       {       value = LE2H_32 (src [count]) ;
-               dest [count] = value >> 16 ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = LE2H_32 (src [i]) ;
+               dest [i] = value >> 16 ;
                } ;
 } /* lei2s_array */
 
@@ -321,9 +322,9 @@ static inline void
 bei2s_array (const int *src, int count, short *dest)
 {      int value ;
 
-       while (--count >= 0)
-       {       value = BE2H_32 (src [count]) ;
-               dest [count] = value >> 16 ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = BE2H_32 (src [i]) ;
+               dest [i] = value >> 16 ;
                } ;
 } /* bei2s_array */
 
@@ -332,15 +333,15 @@ bei2s_array (const int *src, int count, short *dest)
 
 static inline void
 sc2i_array     (const signed char *src, int count, int *dest)
-{      while (--count >= 0)
-       {       dest [count] = arith_shift_left ((int) src [count], 24) ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = arith_shift_left ((int) src [i], 24) ;
                } ;
 } /* sc2i_array */
 
 static inline void
 uc2i_array     (const unsigned char *src, int count, int *dest)
-{      while (--count >= 0)
-       {       dest [count] = arith_shift_left (((int) src [count]) - 128, 24) ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i] = arith_shift_left (((int) src [i]) - 128, 24) ;
                } ;
 } /* uc2i_array */
 
@@ -348,9 +349,9 @@ static inline void
 bes2i_array (const short *src, int count, int *dest)
 {      short value ;
 
-       while (--count >= 0)
-       {       value = BE2H_16 (src [count]) ;
-               dest [count] = arith_shift_left (value, 16) ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = BE2H_16 (src [i]) ;
+               dest [i] = arith_shift_left (value, 16) ;
                } ;
 } /* bes2i_array */
 
@@ -358,22 +359,22 @@ static inline void
 les2i_array (const short *src, int count, int *dest)
 {      short value ;
 
-       while (--count >= 0)
-       {       value = LE2H_16 (src [count]) ;
-               dest [count] = arith_shift_left (value, 16) ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = LE2H_16 (src [i]) ;
+               dest [i] = arith_shift_left (value, 16) ;
                } ;
 } /* les2i_array */
 
 static inline void
 bet2i_array (const tribyte *src, int count, int *dest)
-{      while (--count >= 0)
-               dest [count] = psf_get_be24 (src [count].bytes, 0) ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = psf_get_be24 (src [i].bytes, 0) ;
 } /* bet2i_array */
 
 static inline void
 let2i_array (const tribyte *src, int count, int *dest)
-{      while (--count >= 0)
-               dest [count] = psf_get_le24 (src [count].bytes, 0) ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = psf_get_le24 (src [i].bytes, 0) ;
 } /* let2i_array */
 
 /*--------------------------------------------------------------------------
@@ -381,24 +382,24 @@ let2i_array (const tribyte *src, int count, int *dest)
 
 static inline void
 sc2f_array     (const signed char *src, int count, float *dest, float normfact)
-{      while (--count >= 0)
-               dest [count] = ((float) src [count]) * normfact ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = ((float) src [i]) * normfact ;
 } /* sc2f_array */
 
 static inline void
 uc2f_array     (const unsigned char *src, int count, float *dest, float normfact)
-{      while (--count >= 0)
-               dest [count] = (((int) src [count]) - 128) * normfact ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = (((int) src [i]) - 128) * normfact ;
 } /* uc2f_array */
 
 static inline void
 les2f_array (const short *src, int count, float *dest, float normfact)
 {      short   value ;
 
-       while (--count >= 0)
-       {       value = src [count] ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = src [i] ;
                value = LE2H_16 (value) ;
-               dest [count] = ((float) value) * normfact ;
+               dest [i] = ((float) value) * normfact ;
                } ;
 } /* les2f_array */
 
@@ -406,10 +407,10 @@ static inline void
 bes2f_array (const short *src, int count, float *dest, float normfact)
 {      short                   value ;
 
-       while (--count >= 0)
-       {       value = src [count] ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = src [i] ;
                value = BE2H_16 (value) ;
-               dest [count] = ((float) value) * normfact ;
+               dest [i] = ((float) value) * normfact ;
                } ;
 } /* bes2f_array */
 
@@ -417,9 +418,9 @@ static inline void
 let2f_array (const tribyte *src, int count, float *dest, float normfact)
 {      int value ;
 
-       while (--count >= 0)
-       {       value = psf_get_le24 (src [count].bytes, 0) ;
-               dest [count] = ((float) value) * normfact ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = psf_get_le24 (src [i].bytes, 0) ;
+               dest [i] = ((float) value) * normfact ;
                } ;
 } /* let2f_array */
 
@@ -427,9 +428,9 @@ static inline void
 bet2f_array (const tribyte *src, int count, float *dest, float normfact)
 {      int value ;
 
-       while (--count >= 0)
-       {       value = psf_get_be24 (src [count].bytes, 0) ;
-               dest [count] = ((float) value) * normfact ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = psf_get_be24 (src [i].bytes, 0) ;
+               dest [i] = ((float) value) * normfact ;
                } ;
 } /* bet2f_array */
 
@@ -437,10 +438,10 @@ static inline void
 lei2f_array (const int *src, int count, float *dest, float normfact)
 {      int                     value ;
 
-       while (--count >= 0)
-       {       value = src [count] ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = src [i] ;
                value = LE2H_32 (value) ;
-               dest [count] = ((float) value) * normfact ;
+               dest [i] = ((float) value) * normfact ;
                } ;
 } /* lei2f_array */
 
@@ -448,10 +449,10 @@ static inline void
 bei2f_array (const int *src, int count, float *dest, float normfact)
 {      int                     value ;
 
-       while (--count >= 0)
-       {       value = src [count] ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = src [i] ;
                value = BE2H_32 (value) ;
-               dest [count] = ((float) value) * normfact ;
+               dest [i] = ((float) value) * normfact ;
                } ;
 } /* bei2f_array */
 
@@ -460,24 +461,24 @@ bei2f_array (const int *src, int count, float *dest, float normfact)
 
 static inline void
 sc2d_array     (const signed char *src, int count, double *dest, double normfact)
-{      while (--count >= 0)
-               dest [count] = ((double) src [count]) * normfact ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = ((double) src [i]) * normfact ;
 } /* sc2d_array */
 
 static inline void
 uc2d_array     (const unsigned char *src, int count, double *dest, double normfact)
-{      while (--count >= 0)
-               dest [count] = (((int) src [count]) - 128) * normfact ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = (((int) src [i]) - 128) * normfact ;
 } /* uc2d_array */
 
 static inline void
 les2d_array (const short *src, int count, double *dest, double normfact)
 {      short   value ;
 
-       while (--count >= 0)
-       {       value = src [count] ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = src [i] ;
                value = LE2H_16 (value) ;
-               dest [count] = ((double) value) * normfact ;
+               dest [i] = ((double) value) * normfact ;
                } ;
 } /* les2d_array */
 
@@ -485,10 +486,10 @@ static inline void
 bes2d_array (const short *src, int count, double *dest, double normfact)
 {      short   value ;
 
-       while (--count >= 0)
-       {       value = src [count] ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = src [i] ;
                value = BE2H_16 (value) ;
-               dest [count] = ((double) value) * normfact ;
+               dest [i] = ((double) value) * normfact ;
                } ;
 } /* bes2d_array */
 
@@ -496,9 +497,9 @@ static inline void
 let2d_array (const tribyte *src, int count, double *dest, double normfact)
 {      int value ;
 
-       while (--count >= 0)
-       {       value = psf_get_le24 (src [count].bytes, 0) ;
-               dest [count] = ((double) value) * normfact ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = psf_get_le24 (src [i].bytes, 0) ;
+               dest [i] = ((double) value) * normfact ;
                } ;
 } /* let2d_array */
 
@@ -506,9 +507,9 @@ static inline void
 bet2d_array (const tribyte *src, int count, double *dest, double normfact)
 {      int value ;
 
-       while (--count >= 0)
-       {       value = psf_get_be24 (src [count].bytes, 0) ;
-               dest [count] = ((double) value) * normfact ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = psf_get_be24 (src [i].bytes, 0) ;
+               dest [i] = ((double) value) * normfact ;
                } ;
 } /* bet2d_array */
 
@@ -516,10 +517,10 @@ static inline void
 lei2d_array (const int *src, int count, double *dest, double normfact)
 {      int     value ;
 
-       while (--count >= 0)
-       {       value = src [count] ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = src [i] ;
                value = LE2H_32 (value) ;
-               dest [count] = ((double) value) * normfact ;
+               dest [i] = ((double) value) * normfact ;
                } ;
 } /* lei2d_array */
 
@@ -527,10 +528,10 @@ static inline void
 bei2d_array (const int *src, int count, double *dest, double normfact)
 {      int     value ;
 
-       while (--count >= 0)
-       {       value = src [count] ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = src [i] ;
                value = BE2H_32 (value) ;
-               dest [count] = ((double) value) * normfact ;
+               dest [i] = ((double) value) * normfact ;
                } ;
 } /* bei2d_array */
 
@@ -539,31 +540,31 @@ bei2d_array (const int *src, int count, double *dest, double normfact)
 
 static inline void
 s2sc_array     (const short *src, signed char *dest, int count)
-{      while (--count >= 0)
-               dest [count] = src [count] >> 8 ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = src [i] >> 8 ;
 } /* s2sc_array */
 
 static inline void
 s2uc_array     (const short *src, unsigned char *dest, int count)
-{      while (--count >= 0)
-               dest [count] = (src [count] >> 8) + 0x80 ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = (src [i] >> 8) + 0x80 ;
 } /* s2uc_array */
 
 static inline void
 s2let_array (const short *src, tribyte *dest, int count)
-{      while (--count >= 0)
-       {       dest [count].bytes [0] = 0 ;
-               dest [count].bytes [1] = src [count] ;
-               dest [count].bytes [2] = src [count] >> 8 ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i].bytes [0] = 0 ;
+               dest [i].bytes [1] = src [i] ;
+               dest [i].bytes [2] = src [i] >> 8 ;
                } ;
 } /* s2let_array */
 
 static inline void
 s2bet_array (const short *src, tribyte *dest, int count)
-{      while (--count >= 0)
-       {       dest [count].bytes [2] = 0 ;
-               dest [count].bytes [1] = src [count] ;
-               dest [count].bytes [0] = src [count] >> 8 ;
+{      for (int i = 0 ; i < count ; i++)
+       {       dest [i].bytes [2] = 0 ;
+               dest [i].bytes [1] = src [i] ;
+               dest [i].bytes [0] = src [i] >> 8 ;
                } ;
 } /* s2bet_array */
 
@@ -571,13 +572,12 @@ static inline void
 s2lei_array (const short *src, int *dest, int count)
 {      unsigned char   *ucptr ;
 
-       ucptr = ((unsigned char*) dest) + 4 * count ;
-       while (--count >= 0)
-       {       ucptr -= 4 ;
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
                ucptr [0] = 0 ;
                ucptr [1] = 0 ;
-               ucptr [2] = src [count] ;
-               ucptr [3] = src [count] >> 8 ;
+               ucptr [2] = src [i] ;
+               ucptr [3] = src [i] >> 8 ;
                } ;
 } /* s2lei_array */
 
@@ -585,11 +585,10 @@ static inline void
 s2bei_array (const short *src, int *dest, int count)
 {      unsigned char   *ucptr ;
 
-       ucptr = ((unsigned char*) dest) + 4 * count ;
-       while (--count >= 0)
-       {       ucptr -= 4 ;
-               ucptr [0] = src [count] >> 8 ;
-               ucptr [1] = src [count] ;
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               ucptr [0] = src [i] >> 8 ;
+               ucptr [1] = src [i] ;
                ucptr [2] = 0 ;
                ucptr [3] = 0 ;
                } ;
@@ -600,25 +599,24 @@ s2bei_array (const short *src, int *dest, int count)
 
 static inline void
 i2sc_array     (const int *src, signed char *dest, int count)
-{      while (--count >= 0)
-               dest [count] = (src [count] >> 24) ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = (src [i] >> 24) ;
 } /* i2sc_array */
 
 static inline void
 i2uc_array     (const int *src, unsigned char *dest, int count)
-{      while (--count >= 0)
-               dest [count] = ((src [count] >> 24) + 128) ;
+{      for (int i = 0 ; i < count ; i++)
+               dest [i] = ((src [i] >> 24) + 128) ;
 } /* i2uc_array */
 
 static inline void
 i2bes_array (const int *src, short *dest, int count)
 {      unsigned char   *ucptr ;
 
-       ucptr = ((unsigned char*) dest) + 2 * count ;
-       while (--count >= 0)
-       {       ucptr -= 2 ;
-               ucptr [0] = src [count] >> 24 ;
-               ucptr [1] = src [count] >> 16 ;
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               ucptr [0] = src [i] >> 24 ;
+               ucptr [1] = src [i] >> 16 ;
                } ;
 } /* i2bes_array */
 
@@ -626,11 +624,10 @@ static inline void
 i2les_array (const int *src, short *dest, int count)
 {      unsigned char   *ucptr ;
 
-       ucptr = ((unsigned char*) dest) + 2 * count ;
-       while (--count >= 0)
-       {       ucptr -= 2 ;
-               ucptr [0] = src [count] >> 16 ;
-               ucptr [1] = src [count] >> 24 ;
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               ucptr [0] = src [i] >> 16 ;
+               ucptr [1] = src [i] >> 24 ;
                } ;
 } /* i2les_array */
 
@@ -638,11 +635,11 @@ static inline void
 i2let_array (const int *src, tribyte *dest, int count)
 {      int value ;
 
-       while (--count >= 0)
-       {       value = src [count] >> 8 ;
-               dest [count].bytes [0] = value ;
-               dest [count].bytes [1] = value >> 8 ;
-               dest [count].bytes [2] = value >> 16 ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = src [i] >> 8 ;
+               dest [i].bytes [0] = value ;
+               dest [i].bytes [1] = value >> 8 ;
+               dest [i].bytes [2] = value >> 16 ;
                } ;
 } /* i2let_array */
 
@@ -650,11 +647,11 @@ static inline void
 i2bet_array (const int *src, tribyte *dest, int count)
 {      int value ;
 
-       while (--count >= 0)
-       {       value = src [count] >> 8 ;
-               dest [count].bytes [2] = value ;
-               dest [count].bytes [1] = value >> 8 ;
-               dest [count].bytes [0] = value >> 16 ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = src [i] >> 8 ;
+               dest [i].bytes [2] = value ;
+               dest [i].bytes [1] = value >> 8 ;
+               dest [i].bytes [0] = value >> 16 ;
                } ;
 } /* i2bet_array */
 
@@ -672,7 +669,7 @@ pcm_read_sc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                sc2s_array (ubuf.scbuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -694,7 +691,7 @@ pcm_read_uc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
                uc2s_array (ubuf.ucbuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -709,9 +706,10 @@ static sf_count_t
 pcm_read_bes2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
 {      int             total ;
 
-       total = psf_fread (ptr, sizeof (short), len, psf) ;
-       if (CPU_IS_LITTLE_ENDIAN)
-               endswap_short_array (ptr, len) ;
+       total = (int) psf_fread (ptr, sizeof (short), len, psf) ;
+#if CPU_IS_LITTLE_ENDIAN
+       endswap_short_array (ptr, len) ;
+#endif
 
        return total ;
 } /* pcm_read_bes2s */
@@ -721,8 +719,9 @@ pcm_read_les2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
 {      int             total ;
 
        total = psf_fread (ptr, sizeof (short), len, psf) ;
-       if (CPU_IS_BIG_ENDIAN)
-               endswap_short_array (ptr, len) ;
+#if CPU_IS_BIG_ENDIAN
+       endswap_short_array (ptr, len) ;
+#endif
 
        return total ;
 } /* pcm_read_les2s */
@@ -738,7 +737,7 @@ pcm_read_bet2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                bet2s_array ((tribyte*) (ubuf.ucbuf), readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -760,7 +759,7 @@ pcm_read_let2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                let2s_array ((tribyte*) (ubuf.ucbuf), readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -782,7 +781,7 @@ pcm_read_bei2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
                bei2s_array (ubuf.ibuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -804,7 +803,7 @@ pcm_read_lei2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
                lei2s_array (ubuf.ibuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -829,7 +828,7 @@ pcm_read_sc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                sc2i_array (ubuf.scbuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -851,7 +850,7 @@ pcm_read_uc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
                uc2i_array (ubuf.ucbuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -873,7 +872,7 @@ pcm_read_bes2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                bes2i_array (ubuf.sbuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -895,7 +894,7 @@ pcm_read_les2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                les2i_array (ubuf.sbuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -917,7 +916,7 @@ pcm_read_bet2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                bet2i_array ((tribyte*) (ubuf.ucbuf), readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -939,7 +938,7 @@ pcm_read_let2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                let2i_array ((tribyte*) (ubuf.ucbuf), readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -955,8 +954,9 @@ pcm_read_bei2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
 {      int             total ;
 
        total = psf_fread (ptr, sizeof (int), len, psf) ;
-       if (CPU_IS_LITTLE_ENDIAN)
-               endswap_int_array       (ptr, len) ;
+#if CPU_IS_LITTLE_ENDIAN
+       endswap_int_array       (ptr, len) ;
+#endif
 
        return total ;
 } /* pcm_read_bei2i */
@@ -966,8 +966,9 @@ pcm_read_lei2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
 {      int             total ;
 
        total = psf_fread (ptr, sizeof (int), len, psf) ;
-       if (CPU_IS_BIG_ENDIAN)
-               endswap_int_array       (ptr, len) ;
+#if CPU_IS_BIG_ENDIAN
+       endswap_int_array       (ptr, len) ;
+#endif
 
        return total ;
 } /* pcm_read_lei2i */
@@ -989,7 +990,7 @@ pcm_read_sc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                sc2f_array (ubuf.scbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1014,7 +1015,7 @@ pcm_read_uc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
                uc2f_array (ubuf.ucbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1039,7 +1040,7 @@ pcm_read_bes2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                bes2f_array (ubuf.sbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1064,7 +1065,7 @@ pcm_read_les2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                les2f_array (ubuf.sbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1090,7 +1091,7 @@ pcm_read_bet2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                bet2f_array ((tribyte*) (ubuf.ucbuf), readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1116,7 +1117,7 @@ pcm_read_let2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                let2f_array ((tribyte*) (ubuf.ucbuf), readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1141,7 +1142,7 @@ pcm_read_bei2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
                bei2f_array (ubuf.ibuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1166,7 +1167,7 @@ pcm_read_lei2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
                lei2f_array (ubuf.ibuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1194,7 +1195,7 @@ pcm_read_sc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                sc2d_array (ubuf.scbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1219,7 +1220,7 @@ pcm_read_uc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
                uc2d_array (ubuf.ucbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1244,7 +1245,7 @@ pcm_read_bes2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                bes2d_array (ubuf.sbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1269,7 +1270,7 @@ pcm_read_les2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                les2d_array (ubuf.sbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1294,7 +1295,7 @@ pcm_read_bet2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                bet2d_array ((tribyte*) (ubuf.ucbuf), readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1320,7 +1321,7 @@ pcm_read_let2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                let2d_array ((tribyte*) (ubuf.ucbuf), readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1345,7 +1346,7 @@ pcm_read_bei2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
                bei2d_array (ubuf.ibuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1370,7 +1371,7 @@ pcm_read_lei2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
                lei2d_array (ubuf.ibuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -1398,7 +1399,7 @@ pcm_write_s2sc    (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                s2sc_array (ptr + total, ubuf.scbuf, bufferlen) ;
-               writecount = psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1420,7 +1421,7 @@ pcm_write_s2uc    (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                s2uc_array (ptr + total, ubuf.ucbuf, bufferlen) ;
-               writecount = psf_fwrite (ubuf.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1432,21 +1433,21 @@ pcm_write_s2uc  (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
 
 static sf_count_t
 pcm_write_s2bes        (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
-{      BUF_UNION       ubuf ;
+{
+#if CPU_IS_BIG_ENDIAN
+       return psf_fwrite (ptr, sizeof (short), len, psf) ;
+#else
+       BUF_UNION       ubuf ;
        int                     bufferlen, writecount ;
        sf_count_t      total = 0 ;
 
-       if (CPU_IS_BIG_ENDIAN)
-               return psf_fwrite (ptr, sizeof (short), len, psf) ;
-       else
-
        bufferlen = ARRAY_LEN (ubuf.sbuf) ;
 
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                endswap_short_copy (ubuf.sbuf, ptr + total, bufferlen) ;
-               writecount = psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1454,24 +1455,26 @@ pcm_write_s2bes (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
                } ;
 
        return total ;
+#endif
 } /* pcm_write_s2bes */
 
 static sf_count_t
 pcm_write_s2les        (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
-{      BUF_UNION       ubuf ;
+{
+#if CPU_IS_LITTLE_ENDIAN
+       return psf_fwrite (ptr, sizeof (short), len, psf) ;
+#else
+       BUF_UNION       ubuf ;
        int                     bufferlen, writecount ;
        sf_count_t      total = 0 ;
 
-       if (CPU_IS_LITTLE_ENDIAN)
-               return psf_fwrite (ptr, sizeof (short), len, psf) ;
-
        bufferlen = ARRAY_LEN (ubuf.sbuf) ;
 
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                endswap_short_copy (ubuf.sbuf, ptr + total, bufferlen) ;
-               writecount = psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1479,6 +1482,7 @@ pcm_write_s2les   (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
                } ;
 
        return total ;
+#endif
 } /* pcm_write_s2les */
 
 static sf_count_t
@@ -1493,7 +1497,7 @@ pcm_write_s2bet   (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                s2bet_array (ptr + total, (tribyte*) (ubuf.ucbuf), bufferlen) ;
-               writecount = psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1515,7 +1519,7 @@ pcm_write_s2let   (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                s2let_array (ptr + total, (tribyte*) (ubuf.ucbuf), bufferlen) ;
-               writecount = psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1537,7 +1541,7 @@ pcm_write_s2bei   (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                s2bei_array (ptr + total, ubuf.ibuf, bufferlen) ;
-               writecount = psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1559,7 +1563,7 @@ pcm_write_s2lei   (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                s2lei_array (ptr + total, ubuf.ibuf, bufferlen) ;
-               writecount = psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1584,7 +1588,7 @@ pcm_write_i2sc    (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                i2sc_array (ptr + total, ubuf.scbuf, bufferlen) ;
-               writecount = psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1606,7 +1610,7 @@ pcm_write_i2uc    (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                i2uc_array (ptr + total, ubuf.ucbuf, bufferlen) ;
-               writecount = psf_fwrite (ubuf.ucbuf, sizeof (signed char), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, sizeof (signed char), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1628,7 +1632,7 @@ pcm_write_i2bes   (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                i2bes_array (ptr + total, ubuf.sbuf, bufferlen) ;
-               writecount = psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1650,7 +1654,7 @@ pcm_write_i2les   (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                i2les_array (ptr + total, ubuf.sbuf, bufferlen) ;
-               writecount = psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1672,7 +1676,7 @@ pcm_write_i2bet   (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                i2bet_array (ptr + total, (tribyte*) (ubuf.ucbuf), bufferlen) ;
-               writecount = psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1694,7 +1698,7 @@ pcm_write_i2let   (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                i2let_array (ptr + total, (tribyte*) (ubuf.ucbuf), bufferlen) ;
-               writecount = psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1706,20 +1710,21 @@ pcm_write_i2let (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
 
 static sf_count_t
 pcm_write_i2bei        (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
-{      BUF_UNION       ubuf ;
+{
+#if CPU_IS_BIG_ENDIAN
+       return psf_fwrite (ptr, sizeof (int), len, psf) ;
+#else
+       BUF_UNION       ubuf ;
        int                     bufferlen, writecount ;
        sf_count_t      total = 0 ;
 
-       if (CPU_IS_BIG_ENDIAN)
-               return psf_fwrite (ptr, sizeof (int), len, psf) ;
-
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
 
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                endswap_int_copy (ubuf.ibuf, ptr + total, bufferlen) ;
-               writecount = psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1727,24 +1732,26 @@ pcm_write_i2bei (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
                } ;
 
        return total ;
+#endif
 } /* pcm_write_i2bei */
 
 static sf_count_t
 pcm_write_i2lei        (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
-{      BUF_UNION       ubuf ;
+{
+#if CPU_IS_LITTLE_ENDIAN
+       return psf_fwrite (ptr, sizeof (int), len, psf) ;
+#else
+       BUF_UNION       ubuf ;
        int                     bufferlen, writecount ;
        sf_count_t      total = 0 ;
 
-       if (CPU_IS_LITTLE_ENDIAN)
-               return psf_fwrite (ptr, sizeof (int), len, psf) ;
-
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
 
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                endswap_int_copy (ubuf.ibuf, ptr + total, bufferlen) ;
-               writecount = psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1752,6 +1759,7 @@ pcm_write_i2lei   (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
                } ;
 
        return total ;
+#endif
 } /* pcm_write_i2lei */
 
 /*------------------------------------------------------------------------------
@@ -1765,8 +1773,8 @@ f2sc_array (const float *src, signed char *dest, int count, int normalize)
 
        normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
 
-       while (--count >= 0)
-       {       dest [count] = psf_lrintf (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+       {       dest [i] = psf_lrintf (src [i] * normfact) ;
                } ;
 } /* f2sc_array */
 
@@ -1776,18 +1784,22 @@ f2sc_clip_array (const float *src, signed char *dest, int count, int normalize)
 
        normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x1000000) ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
-               {       dest [count] = 127 ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       dest [i] = 127 ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
-               {       dest [count] = -128 ;
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
+               {       dest [i] = -128 ;
                        continue ;
                        } ;
+#endif
 
-               dest [count] = psf_lrintf (scaled_value) >> 24 ;
+               dest [i] = psf_lrintf (scaled_value) >> 24 ;
                } ;
 } /* f2sc_clip_array */
 
@@ -1805,7 +1817,7 @@ pcm_write_f2sc    (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, ubuf.scbuf, bufferlen, psf->norm_float) ;
-               writecount = psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1824,8 +1836,8 @@ f2uc_array        (const float *src, unsigned char *dest, int count, int normalize)
 
        normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
 
-       while (--count >= 0)
-       {       dest [count] = psf_lrintf (src [count] * normfact) + 128 ;
+       for (int i = 0 ; i < count ; i++)
+       {       dest [i] = psf_lrintf (src [i] * normfact) + 128 ;
                } ;
 } /* f2uc_array */
 
@@ -1835,18 +1847,22 @@ f2uc_clip_array (const float *src, unsigned char *dest, int count, int normalize
 
        normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x1000000) ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
-               {       dest [count] = 0xFF ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       dest [i] = 0xFF ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
-               {       dest [count] = 0 ;
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
+               {       dest [i] = 0 ;
                        continue ;
                        } ;
+#endif
 
-               dest [count] = (psf_lrintf (scaled_value) >> 24) + 128 ;
+               dest [i] = (psf_lrintf (scaled_value) >> 24) + 128 ;
                } ;
 } /* f2uc_clip_array */
 
@@ -1864,7 +1880,7 @@ pcm_write_f2uc    (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, ubuf.ucbuf, bufferlen, psf->norm_float) ;
-               writecount = psf_fwrite (ubuf.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1884,11 +1900,10 @@ f2bes_array (const float *src, short *dest, int count, int normalize)
        short                   value ;
 
        normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
-       ucptr = ((unsigned char*) dest) + 2 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 2 ;
-               value = psf_lrintf (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               value = psf_lrintf (src [i] * normfact) ;
                ucptr [1] = value ;
                ucptr [0] = value >> 8 ;
                        } ;
@@ -1901,21 +1916,24 @@ f2bes_clip_array (const float *src, short *dest, int count, int normalize)
        int                             value ;
 
        normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x10000) ;
-       ucptr = ((unsigned char*) dest) + 2 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 2 ;
-               scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
                {       ucptr [1] = 0xFF ;
                        ucptr [0] = 0x7F ;
                        continue ;
                } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
                {       ucptr [1] = 0x00 ;
                        ucptr [0] = 0x80 ;
                        continue ;
                        } ;
+#endif
 
                value = psf_lrintf (scaled_value) ;
                ucptr [1] = value >> 16 ;
@@ -1937,7 +1955,7 @@ pcm_write_f2bes   (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, ubuf.sbuf, bufferlen, psf->norm_float) ;
-               writecount = psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                                break ;
@@ -1957,11 +1975,10 @@ f2les_array (const float *src, short *dest, int count, int normalize)
        int                             value ;
 
        normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
-       ucptr = ((unsigned char*) dest) + 2 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 2 ;
-               value = psf_lrintf (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               value = psf_lrintf (src [i] * normfact) ;
                ucptr [0] = value ;
                ucptr [1] = value >> 8 ;
                } ;
@@ -1974,21 +1991,24 @@ f2les_clip_array (const float *src, short *dest, int count, int normalize)
        int                             value ;
 
        normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x10000) ;
-       ucptr = ((unsigned char*) dest) + 2 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 2 ;
-               scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
                {       ucptr [0] = 0xFF ;
                        ucptr [1] = 0x7F ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
                {       ucptr [0] = 0x00 ;
                        ucptr [1] = 0x80 ;
                        continue ;
                        } ;
+#endif
 
                value = psf_lrintf (scaled_value) ;
                ucptr [0] = value >> 16 ;
@@ -2010,7 +2030,7 @@ pcm_write_f2les   (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, ubuf.sbuf, bufferlen, psf->norm_float) ;
-               writecount = psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -2030,11 +2050,11 @@ f2let_array (const float *src, tribyte *dest, int count, int normalize)
 
        normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
 
-       while (--count >= 0)
-       {       value = psf_lrintf (src [count] * normfact) ;
-               dest [count].bytes [0] = value ;
-               dest [count].bytes [1] = value >> 8 ;
-               dest [count].bytes [2] = value >> 16 ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = psf_lrintf (src [i] * normfact) ;
+               dest [i].bytes [0] = value ;
+               dest [i].bytes [1] = value >> 8 ;
+               dest [i].bytes [2] = value >> 16 ;
                } ;
 } /* f2let_array */
 
@@ -2045,25 +2065,29 @@ f2let_clip_array (const float *src, tribyte *dest, int count, int normalize)
 
        normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x100) ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
-               {       dest [count].bytes [0] = 0xFF ;
-                       dest [count].bytes [1] = 0xFF ;
-                       dest [count].bytes [2] = 0x7F ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       dest [i].bytes [0] = 0xFF ;
+                       dest [i].bytes [1] = 0xFF ;
+                       dest [i].bytes [2] = 0x7F ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
-               {       dest [count].bytes [0] = 0x00 ;
-                       dest [count].bytes [1] = 0x00 ;
-                       dest [count].bytes [2] = 0x80 ;
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
+               {       dest [i].bytes [0] = 0x00 ;
+                       dest [i].bytes [1] = 0x00 ;
+                       dest [i].bytes [2] = 0x80 ;
                        continue ;
                } ;
+#endif
 
                value = psf_lrintf (scaled_value) ;
-               dest [count].bytes [0] = value >> 8 ;
-               dest [count].bytes [1] = value >> 16 ;
-               dest [count].bytes [2] = value >> 24 ;
+               dest [i].bytes [0] = value >> 8 ;
+               dest [i].bytes [1] = value >> 16 ;
+               dest [i].bytes [2] = value >> 24 ;
                } ;
 } /* f2let_clip_array */
 
@@ -2081,7 +2105,7 @@ pcm_write_f2let   (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, (tribyte*) (ubuf.ucbuf), bufferlen, psf->norm_float) ;
-               writecount = psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -2101,11 +2125,11 @@ f2bet_array (const float *src, tribyte *dest, int count, int normalize)
 
        normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
 
-       while (--count >= 0)
-       {       value = psf_lrintf (src [count] * normfact) ;
-               dest [count].bytes [0] = value >> 16 ;
-               dest [count].bytes [1] = value >> 8 ;
-               dest [count].bytes [2] = value ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = psf_lrintf (src [i] * normfact) ;
+               dest [i].bytes [0] = value >> 16 ;
+               dest [i].bytes [1] = value >> 8 ;
+               dest [i].bytes [2] = value ;
                } ;
 } /* f2bet_array */
 
@@ -2116,25 +2140,29 @@ f2bet_clip_array (const float *src, tribyte *dest, int count, int normalize)
 
        normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x100) ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
-               {       dest [count].bytes [0] = 0x7F ;
-                       dest [count].bytes [1] = 0xFF ;
-                       dest [count].bytes [2] = 0xFF ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       dest [i].bytes [0] = 0x7F ;
+                       dest [i].bytes [1] = 0xFF ;
+                       dest [i].bytes [2] = 0xFF ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
-               {       dest [count].bytes [0] = 0x80 ;
-                       dest [count].bytes [1] = 0x00 ;
-                       dest [count].bytes [2] = 0x00 ;
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
+               {       dest [i].bytes [0] = 0x80 ;
+                       dest [i].bytes [1] = 0x00 ;
+                       dest [i].bytes [2] = 0x00 ;
                        continue ;
                } ;
+#endif
 
                value = psf_lrint (scaled_value) ;
-               dest [count].bytes [0] = value >> 24 ;
-               dest [count].bytes [1] = value >> 16 ;
-               dest [count].bytes [2] = value >> 8 ;
+               dest [i].bytes [0] = value >> 24 ;
+               dest [i].bytes [1] = value >> 16 ;
+               dest [i].bytes [2] = value >> 8 ;
                } ;
 } /* f2bet_clip_array */
 
@@ -2152,7 +2180,7 @@ pcm_write_f2bet   (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, (tribyte*) (ubuf.ucbuf), bufferlen, psf->norm_float) ;
-               writecount = psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -2172,10 +2200,10 @@ f2bei_array (const float *src, int *dest, int count, int normalize)
        int                             value ;
 
        normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
-       ucptr = ((unsigned char*) dest) + 4 * count ;
-       while (--count >= 0)
-       {       ucptr -= 4 ;
-               value = psf_lrintf (src [count] * normfact) ;
+
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               value = psf_lrintf (src [i] * normfact) ;
                ucptr [0] = value >> 24 ;
                ucptr [1] = value >> 16 ;
                ucptr [2] = value >> 8 ;
@@ -2190,25 +2218,28 @@ f2bei_clip_array (const float *src, int *dest, int count, int normalize)
        int                             value ;
 
        normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
-       ucptr = ((unsigned char*) dest) + 4 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 4 ;
-               scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= 1.0 * 0x7FFFFFFF)
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= 1.0 * 0x7FFFFFFF)
                {       ucptr [0] = 0x7F ;
                        ucptr [1] = 0xFF ;
                        ucptr [2] = 0xFF ;
                        ucptr [3] = 0xFF ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
                {       ucptr [0] = 0x80 ;
                        ucptr [1] = 0x00 ;
                        ucptr [2] = 0x00 ;
                        ucptr [3] = 0x00 ;
                        continue ;
                } ;
+#endif
 
                value = psf_lrintf (scaled_value) ;
                ucptr [0] = value >> 24 ;
@@ -2232,7 +2263,7 @@ pcm_write_f2bei   (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, ubuf.ibuf, bufferlen, psf->norm_float) ;
-               writecount = psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -2252,11 +2283,10 @@ f2lei_array (const float *src, int *dest, int count, int normalize)
        int                             value ;
 
        normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
-       ucptr = ((unsigned char*) dest) + 4 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 4 ;
-               value = psf_lrintf (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               value = psf_lrintf (src [i] * normfact) ;
                ucptr [0] = value ;
                ucptr [1] = value >> 8 ;
                ucptr [2] = value >> 16 ;
@@ -2271,25 +2301,28 @@ f2lei_clip_array (const float *src, int *dest, int count, int normalize)
        int                             value ;
 
        normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
-       ucptr = ((unsigned char*) dest) + 4 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 4 ;
-               scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
                {       ucptr [0] = 0xFF ;
                        ucptr [1] = 0xFF ;
                        ucptr [2] = 0xFF ;
                        ucptr [3] = 0x7F ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
                {       ucptr [0] = 0x00 ;
                        ucptr [1] = 0x00 ;
                        ucptr [2] = 0x00 ;
                        ucptr [3] = 0x80 ;
                        continue ;
                        } ;
+#endif
 
                value = psf_lrintf (scaled_value) ;
                ucptr [0] = value ;
@@ -2313,7 +2346,7 @@ pcm_write_f2lei   (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, ubuf.ibuf, bufferlen, psf->norm_float) ;
-               writecount = psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -2332,8 +2365,8 @@ d2sc_array        (const double *src, signed char *dest, int count, int normalize)
 
        normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
 
-       while (--count >= 0)
-       {       dest [count] = psf_lrint (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+       {       dest [i] = psf_lrint (src [i] * normfact) ;
                } ;
 } /* d2sc_array */
 
@@ -2343,18 +2376,22 @@ d2sc_clip_array (const double *src, signed char *dest, int count, int normalize)
 
        normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x1000000) ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
-               {       dest [count] = 127 ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       dest [i] = 127 ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
-               {       dest [count] = -128 ;
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
+               {       dest [i] = -128 ;
                        continue ;
                        } ;
+#endif
 
-               dest [count] = psf_lrintf (scaled_value) >> 24 ;
+               dest [i] = psf_lrintf (scaled_value) >> 24 ;
                } ;
 } /* d2sc_clip_array */
 
@@ -2372,7 +2409,7 @@ pcm_write_d2sc    (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, ubuf.scbuf, bufferlen, psf->norm_double) ;
-               writecount = psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -2391,8 +2428,8 @@ d2uc_array        (const double *src, unsigned char *dest, int count, int normalize)
 
        normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
 
-       while (--count >= 0)
-       {       dest [count] = psf_lrint (src [count] * normfact) + 128 ;
+       for (int i = 0 ; i < count ; i++)
+       {       dest [i] = psf_lrint (src [i] * normfact) + 128 ;
                } ;
 } /* d2uc_array */
 
@@ -2402,18 +2439,22 @@ d2uc_clip_array (const double *src, unsigned char *dest, int count, int normaliz
 
        normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x1000000) ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
-               {       dest [count] = 255 ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       dest [i] = 255 ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
-               {       dest [count] = 0 ;
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
+               {       dest [i] = 0 ;
                        continue ;
                        } ;
+#endif
 
-               dest [count] = (psf_lrint (src [count] * normfact) >> 24) + 128 ;
+               dest [i] = (psf_lrint (src [i] * normfact) >> 24) + 128 ;
                } ;
 } /* d2uc_clip_array */
 
@@ -2431,7 +2472,7 @@ pcm_write_d2uc    (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, ubuf.ucbuf, bufferlen, psf->norm_double) ;
-               writecount = psf_fwrite (ubuf.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -2451,11 +2492,10 @@ d2bes_array (const double *src, short *dest, int count, int normalize)
        double                  normfact ;
 
        normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
-       ucptr = ((unsigned char*) dest) + 2 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 2 ;
-               value = psf_lrint (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               value = psf_lrint (src [i] * normfact) ;
                ucptr [1] = value ;
                ucptr [0] = value >> 8 ;
                } ;
@@ -2468,21 +2508,24 @@ d2bes_clip_array (const double *src, short *dest, int count, int normalize)
        int                             value ;
 
        normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x10000) ;
-       ucptr = ((unsigned char*) dest) + 2 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 2 ;
-               scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
                {       ucptr [1] = 0xFF ;
                        ucptr [0] = 0x7F ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
                {       ucptr [1] = 0x00 ;
                        ucptr [0] = 0x80 ;
                        continue ;
                        } ;
+#endif
 
                value = psf_lrint (scaled_value) ;
                ucptr [1] = value >> 16 ;
@@ -2504,7 +2547,7 @@ pcm_write_d2bes   (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, ubuf.sbuf, bufferlen, psf->norm_double) ;
-               writecount = psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -2524,11 +2567,10 @@ d2les_array (const double *src, short *dest, int count, int normalize)
        double                  normfact ;
 
        normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
-       ucptr = ((unsigned char*) dest) + 2 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 2 ;
-               value = psf_lrint (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               value = psf_lrint (src [i] * normfact) ;
                ucptr [0] = value ;
                ucptr [1] = value >> 8 ;
                } ;
@@ -2541,21 +2583,24 @@ d2les_clip_array (const double *src, short *dest, int count, int normalize)
        double                  normfact, scaled_value ;
 
        normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x10000) ;
-       ucptr = ((unsigned char*) dest) + 2 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 2 ;
-               scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
                {       ucptr [0] = 0xFF ;
                        ucptr [1] = 0x7F ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
                {       ucptr [0] = 0x00 ;
                        ucptr [1] = 0x80 ;
                        continue ;
                        } ;
+#endif
 
                value = psf_lrint (scaled_value) ;
                ucptr [0] = value >> 16 ;
@@ -2577,7 +2622,7 @@ pcm_write_d2les   (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, ubuf.sbuf, bufferlen, psf->norm_double) ;
-               writecount = psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -2597,11 +2642,11 @@ d2let_array (const double *src, tribyte *dest, int count, int normalize)
 
        normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
 
-       while (--count >= 0)
-       {       value = psf_lrint (src [count] * normfact) ;
-               dest [count].bytes [0] = value ;
-               dest [count].bytes [1] = value >> 8 ;
-               dest [count].bytes [2] = value >> 16 ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = psf_lrint (src [i] * normfact) ;
+               dest [i].bytes [0] = value ;
+               dest [i].bytes [1] = value >> 8 ;
+               dest [i].bytes [2] = value >> 16 ;
                } ;
 } /* d2let_array */
 
@@ -2612,25 +2657,29 @@ d2let_clip_array (const double *src, tribyte *dest, int count, int normalize)
 
        normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x100) ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
-               {       dest [count].bytes [0] = 0xFF ;
-                       dest [count].bytes [1] = 0xFF ;
-                       dest [count].bytes [2] = 0x7F ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       dest [i].bytes [0] = 0xFF ;
+                       dest [i].bytes [1] = 0xFF ;
+                       dest [i].bytes [2] = 0x7F ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
-               {       dest [count].bytes [0] = 0x00 ;
-                       dest [count].bytes [1] = 0x00 ;
-                       dest [count].bytes [2] = 0x80 ;
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
+               {       dest [i].bytes [0] = 0x00 ;
+                       dest [i].bytes [1] = 0x00 ;
+                       dest [i].bytes [2] = 0x80 ;
                        continue ;
                        } ;
+#endif
 
                value = psf_lrint (scaled_value) ;
-               dest [count].bytes [0] = value >> 8 ;
-               dest [count].bytes [1] = value >> 16 ;
-               dest [count].bytes [2] = value >> 24 ;
+               dest [i].bytes [0] = value >> 8 ;
+               dest [i].bytes [1] = value >> 16 ;
+               dest [i].bytes [2] = value >> 24 ;
                } ;
 } /* d2let_clip_array */
 
@@ -2648,7 +2697,7 @@ pcm_write_d2let   (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, (tribyte*) (ubuf.ucbuf), bufferlen, psf->norm_double) ;
-               writecount = psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -2668,11 +2717,11 @@ d2bet_array (const double *src, tribyte *dest, int count, int normalize)
 
        normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
 
-       while (--count >= 0)
-       {       value = psf_lrint (src [count] * normfact) ;
-               dest [count].bytes [2] = value ;
-               dest [count].bytes [1] = value >> 8 ;
-               dest [count].bytes [0] = value >> 16 ;
+       for (int i = 0 ; i < count ; i++)
+       {       value = psf_lrint (src [i] * normfact) ;
+               dest [i].bytes [2] = value ;
+               dest [i].bytes [1] = value >> 8 ;
+               dest [i].bytes [0] = value >> 16 ;
                } ;
 } /* d2bet_array */
 
@@ -2683,25 +2732,29 @@ d2bet_clip_array (const double *src, tribyte *dest, int count, int normalize)
 
        normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x100) ;
 
-       while (--count >= 0)
-       {       scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
-               {       dest [count].bytes [2] = 0xFF ;
-                       dest [count].bytes [1] = 0xFF ;
-                       dest [count].bytes [0] = 0x7F ;
+       for (int i = 0 ; i < count ; i++)
+       {       scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       dest [i].bytes [2] = 0xFF ;
+                       dest [i].bytes [1] = 0xFF ;
+                       dest [i].bytes [0] = 0x7F ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
-               {       dest [count].bytes [2] = 0x00 ;
-                       dest [count].bytes [1] = 0x00 ;
-                       dest [count].bytes [0] = 0x80 ;
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
+               {       dest [i].bytes [2] = 0x00 ;
+                       dest [i].bytes [1] = 0x00 ;
+                       dest [i].bytes [0] = 0x80 ;
                        continue ;
                        } ;
+#endif
 
                value = psf_lrint (scaled_value) ;
-               dest [count].bytes [2] = value >> 8 ;
-               dest [count].bytes [1] = value >> 16 ;
-               dest [count].bytes [0] = value >> 24 ;
+               dest [i].bytes [2] = value >> 8 ;
+               dest [i].bytes [1] = value >> 16 ;
+               dest [i].bytes [0] = value >> 24 ;
                } ;
 } /* d2bet_clip_array */
 
@@ -2719,7 +2772,7 @@ pcm_write_d2bet   (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, (tribyte*) (ubuf.ucbuf), bufferlen, psf->norm_double) ;
-               writecount = psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -2739,11 +2792,10 @@ d2bei_array (const double *src, int *dest, int count, int normalize)
        double                  normfact ;
 
        normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
-       ucptr = ((unsigned char*) dest) + 4 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 4 ;
-               value = psf_lrint (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               value = psf_lrint (src [i] * normfact) ;
                ucptr [0] = value >> 24 ;
                ucptr [1] = value >> 16 ;
                ucptr [2] = value >> 8 ;
@@ -2758,25 +2810,28 @@ d2bei_clip_array (const double *src, int *dest, int count, int normalize)
        double                  normfact, scaled_value ;
 
        normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
-       ucptr = ((unsigned char*) dest) + 4 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 4 ;
-               scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
                {       ucptr [3] = 0xFF ;
                        ucptr [2] = 0xFF ;
                        ucptr [1] = 0xFF ;
                        ucptr [0] = 0x7F ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
                {       ucptr [3] = 0x00 ;
                        ucptr [2] = 0x00 ;
                        ucptr [1] = 0x00 ;
                        ucptr [0] = 0x80 ;
                        continue ;
                        } ;
+#endif
 
                value = psf_lrint (scaled_value) ;
                ucptr [0] = value >> 24 ;
@@ -2800,7 +2855,7 @@ pcm_write_d2bei   (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, ubuf.ibuf, bufferlen, psf->norm_double) ;
-               writecount = psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -2820,11 +2875,10 @@ d2lei_array (const double *src, int *dest, int count, int normalize)
        double                  normfact ;
 
        normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
-       ucptr = ((unsigned char*) dest) + 4 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 4 ;
-               value = psf_lrint (src [count] * normfact) ;
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               value = psf_lrint (src [i] * normfact) ;
                ucptr [0] = value ;
                ucptr [1] = value >> 8 ;
                ucptr [2] = value >> 16 ;
@@ -2839,25 +2893,28 @@ d2lei_clip_array (const double *src, int *dest, int count, int normalize)
        double                  normfact, scaled_value ;
 
        normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
-       ucptr = ((unsigned char*) dest) + 4 * count ;
 
-       while (--count >= 0)
-       {       ucptr -= 4 ;
-               scaled_value = src [count] * normfact ;
-               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+       for (int i = 0 ; i < count ; i++)
+       {       ucptr = (unsigned char*) &dest [i] ;
+               scaled_value = src [i] * normfact ;
+#if CPU_CLIPS_POSITIVE == 0
+               if (scaled_value >= (1.0 * 0x7FFFFFFF))
                {       ucptr [0] = 0xFF ;
                        ucptr [1] = 0xFF ;
                        ucptr [2] = 0xFF ;
                        ucptr [3] = 0x7F ;
                        continue ;
                        } ;
-               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+#endif
+#if CPU_CLIPS_NEGATIVE == 0
+               if (scaled_value <= (-8.0 * 0x10000000))
                {       ucptr [0] = 0x00 ;
                        ucptr [1] = 0x00 ;
                        ucptr [2] = 0x00 ;
                        ucptr [3] = 0x80 ;
                        continue ;
                        } ;
+#endif
 
                value = psf_lrint (scaled_value) ;
                ucptr [0] = value ;
@@ -2881,7 +2938,7 @@ pcm_write_d2lei   (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                convert (ptr + total, ubuf.ibuf, bufferlen, psf->norm_double) ;
-               writecount = psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ibuf, sizeof (int), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
index 876cd45..123db44 100644 (file)
@@ -197,7 +197,7 @@ rf64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
        else
                psf_log_printf (psf, "%M : 0x%x (should be 0xFFFFFFFF)\n  %M\n", RF64_MARKER, WAVE_MARKER) ;
 
-       while (NOT (done))
+       while (!done)
        {
                marker = chunk_size = 0 ;
                psf_binheader_readf (psf, "em4", &marker, &chunk_size) ;
@@ -328,7 +328,7 @@ rf64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
                                        if (psf->datalength + psf->dataoffset < psf->filelength)
                                                psf->dataend = psf->datalength + psf->dataoffset ;
 
-                                       if (NOT (psf->sf.seekable) || psf->dataoffset < 0)
+                                       if (!psf->sf.seekable || psf->dataoffset < 0)
                                                break ;
 
                                        /* Seek past data and continue reading header. */
@@ -762,7 +762,7 @@ rf64_write_header (SF_PRIVATE *psf, int calc_length)
 
        psf->dataoffset = psf->header.indx ;
 
-       if (NOT (has_data))
+       if (!has_data)
                psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
        else if (current > 0)
                psf_fseek (psf, current, SEEK_SET) ;
index dd3dbef..f5ef9de 100644 (file)
--- a/src/sd2.c
+++ b/src/sd2.c
@@ -240,7 +240,7 @@ sd2_write_rsrc_fork (SF_PRIVATE *psf, int UNUSED (calc_length))
        /* Very start of resource fork. */
        psf_binheader_writef (psf, "E444", BHW4 (rsrc.data_offset), BHW4 (rsrc.map_offset), BHW4 (rsrc.data_length)) ;
 
-       psf_binheader_writef (psf, "Eop", BHWo (0x30), BHWp (psf->file.name.c)) ;
+       psf_binheader_writef (psf, "Eop", BHWo (0x30), BHWp (psf->file.name)) ;
        psf_binheader_writef (psf, "Eo2mm", BHWo (0x50), BHW2 (0), BHWm (Sd2f_MARKER), BHWm (lsf1_MARKER)) ;
 
        /* Very start of resource map. */
index 85c8c11..6bc7617 100644 (file)
--- a/src/sds.c
+++ b/src/sds.c
@@ -281,7 +281,7 @@ sds_read_header (SF_PRIVATE *psf, SDS_PRIVATE *psds)
 
        for (blockcount = 0 ; bytesread < psf->filelength ; blockcount++)
        {
-               bytesread += psf_fread (&marker, 1, 2, psf) ;
+               bytesread += (int) psf_fread (&marker, 1, 2, psf) ;
 
                if (marker == 0)
                        break ;
@@ -431,7 +431,7 @@ sds_2byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds)
                return 1 ;
                } ;
 
-       if ((k = psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
+       if ((k = (int) psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
                psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
 
        if (psds->read_data [0] != 0xF0)
@@ -475,7 +475,7 @@ sds_3byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds)
                return 1 ;
                } ;
 
-       if ((k = psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
+       if ((k = (int) psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
                psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
 
        if (psds->read_data [0] != 0xF0)
@@ -519,7 +519,7 @@ sds_4byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds)
                return 1 ;
                } ;
 
-       if ((k = psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
+       if ((k = (int) psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
                psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
 
        if (psds->read_data [0] != 0xF0)
@@ -565,7 +565,7 @@ sds_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = sds_read (psf, psds, iptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = iptr [k] >> 16 ;
@@ -611,7 +611,7 @@ sds_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = sds_read (psf, psds, iptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = normfact * iptr [k] ;
@@ -643,7 +643,7 @@ sds_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
                count = sds_read (psf, psds, iptr, readcount) ;
                for (k = 0 ; k < readcount ; k++)
                        ptr [total + k] = normfact * iptr [k] ;
@@ -794,7 +794,7 @@ sds_2byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
        psds->write_data [SDS_BLOCK_SIZE - 2] = checksum ;
        psds->write_data [SDS_BLOCK_SIZE - 1] = 0xF7 ;
 
-       if ((k = psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
+       if ((k = (int) psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
                psf_log_printf (psf, "*** Warning : psf_fwrite (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
 
        psds->write_block ++ ;
@@ -836,7 +836,7 @@ sds_3byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
        psds->write_data [SDS_BLOCK_SIZE - 2] = checksum ;
        psds->write_data [SDS_BLOCK_SIZE - 1] = 0xF7 ;
 
-       if ((k = psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
+       if ((k = (int) psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
                psf_log_printf (psf, "*** Warning : psf_fwrite (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
 
        psds->write_block ++ ;
@@ -879,7 +879,7 @@ sds_4byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
        psds->write_data [SDS_BLOCK_SIZE - 2] = checksum ;
        psds->write_data [SDS_BLOCK_SIZE - 1] = 0xF7 ;
 
-       if ((k = psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
+       if ((k = (int) psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
                psf_log_printf (psf, "*** Warning : psf_fwrite (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
 
        psds->write_block ++ ;
@@ -908,7 +908,7 @@ sds_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        iptr [k] = arith_shift_left (ptr [total + k], 16) ;
                count = sds_write (psf, psds, iptr, writecount) ;
@@ -956,7 +956,7 @@ sds_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        iptr [k] = normfact * ptr [total + k] ;
                count = sds_write (psf, psds, iptr, writecount) ;
@@ -989,7 +989,7 @@ sds_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        iptr = ubuf.ibuf ;
        bufferlen = ARRAY_LEN (ubuf.ibuf) ;
        while (len > 0)
-       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
                for (k = 0 ; k < writecount ; k++)
                        iptr [k] = normfact * ptr [total + k] ;
                count = sds_write (psf, psds, iptr, writecount) ;
index 9367a96..ab02742 100644 (file)
 #include <stdint.h>
 #include <inttypes.h>
 
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
 #if HAVE_BYTESWAP_H                    /* Linux, any CPU */
 #include <byteswap.h>
 
 #define        ENDSWAP_32(x)           (bswap_32 (x))
 #define        ENDSWAP_64(x)           (bswap_64 (x))
 
-#elif defined __has_builtin
+#elif __has_builtin(__builtin_bswap16) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)
 
-#if __has_builtin (__builtin_bswap16)
 #define ENDSWAP_16(x) ((int16_t) __builtin_bswap16 ((uint16_t) x))
-#endif
-
-#if __has_builtin (__builtin_bswap32)
 #define ENDSWAP_32(x) ((int32_t) __builtin_bswap32 ((uint32_t) x))
-#endif
-
-#if __has_builtin (__builtin_bswap64)
 #define ENDSWAP_64(x) ((int64_t) __builtin_bswap64 ((uint64_t) x))
-#endif
 
 #elif COMPILER_IS_GCC
 
@@ -210,43 +206,39 @@ static inline int64_t
 psf_get_be64 (const uint8_t *ptr, int offset)
 {      int64_t value ;
 
-       value = ((uint32_t) ptr [offset]) << 24 ;
-       value += ptr [offset + 1] << 16 ;
-       value += ptr [offset + 2] << 8 ;
+       value = (int64_t) ((uint64_t) ptr [offset] << 24) ;
+       value += (int64_t) ((uint64_t) ptr [offset + 1] << 16) ;
+       value += (int64_t) ((uint64_t) ptr [offset + 2] << 8) ;
        value += ptr [offset + 3] ;
 
        value = (int64_t) (((uint64_t) value) << 32) ;
 
-       value += ((uint32_t) ptr [offset + 4]) << 24 ;
-       value += ptr [offset + 5] << 16 ;
-       value += ptr [offset + 6] << 8 ;
+       value += (int64_t) ((uint64_t) ptr [offset + 4] << 24) ;
+       value += (int64_t) ((uint64_t) ptr [offset + 5] << 16) ;
+       value += (int64_t) ((uint64_t) ptr [offset + 6] << 8) ;
        value += ptr [offset + 7] ;
        return value ;
 } /* psf_get_be64 */
 
 static inline int64_t
 psf_get_le64 (const uint8_t *ptr, int offset)
-{      int64_t value ;
-
-       value = ((uint32_t) ptr [offset + 7]) << 24 ;
-       value += ptr [offset + 6] << 16 ;
-       value += ptr [offset + 5] << 8 ;
+{      int64_t value = (int64_t) ((uint64_t) ptr [offset + 7] << 24) ;
+       value += (int64_t) ((uint64_t) ptr [offset + 6] << 16) ;
+       value += (int64_t) ((uint64_t) ptr [offset + 5] << 8) ;
        value += ptr [offset + 4] ;
 
        value = (int64_t) (((uint64_t) value) << 32) ;
 
-       value += ((uint32_t) ptr [offset + 3]) << 24 ;
-       value += ptr [offset + 2] << 16 ;
-       value += ptr [offset + 1] << 8 ;
+       value += (int64_t) ((uint64_t) ptr [offset + 3] << 24) ;
+       value += (int64_t) ((uint64_t) ptr [offset + 2] << 16) ;
+       value += (int64_t) ((uint64_t) ptr [offset + 1] << 8) ;
        value += ptr [offset] ;
        return value ;
 } /* psf_get_le64 */
 
 static inline int32_t
 psf_get_be32 (const uint8_t *ptr, int offset)
-{      int32_t value ;
-
-       value = ((uint32_t) ptr [offset]) << 24 ;
+{      int32_t value = ((uint32_t) ptr [offset]) << 24 ;
        value += ptr [offset + 1] << 16 ;
        value += ptr [offset + 2] << 8 ;
        value += ptr [offset + 3] ;
@@ -255,9 +247,7 @@ psf_get_be32 (const uint8_t *ptr, int offset)
 
 static inline int32_t
 psf_get_le32 (const uint8_t *ptr, int offset)
-{      int32_t value ;
-
-       value = ((uint32_t) ptr [offset + 3]) << 24 ;
+{      int32_t value = ((uint32_t) ptr [offset + 3]) << 24 ;
        value += ptr [offset + 2] << 16 ;
        value += ptr [offset + 1] << 8 ;
        value += ptr [offset] ;
@@ -266,9 +256,7 @@ psf_get_le32 (const uint8_t *ptr, int offset)
 
 static inline int32_t
 psf_get_be24 (const uint8_t *ptr, int offset)
-{      int32_t value ;
-
-       value = ((uint32_t) ptr [offset]) << 24 ;
+{      int32_t value = ((uint32_t) ptr [offset]) << 24 ;
        value += ptr [offset + 1] << 16 ;
        value += ptr [offset + 2] << 8 ;
        return value ;
@@ -276,9 +264,7 @@ psf_get_be24 (const uint8_t *ptr, int offset)
 
 static inline int32_t
 psf_get_le24 (const uint8_t *ptr, int offset)
-{      int32_t value ;
-
-       value = ((uint32_t) ptr [offset + 2]) << 24 ;
+{      int32_t value = ((uint32_t) ptr [offset + 2]) << 24 ;
        value += ptr [offset + 1] << 16 ;
        value += ptr [offset] << 8 ;
        return value ;
@@ -295,37 +281,35 @@ psf_get_be16 (const uint8_t *ptr, int offset)
 
 static inline void
 endswap_short_array (short *ptr, int len)
-{      short   temp ;
-
-       while (--len >= 0)
-       {       temp = ptr [len] ;
-               ptr [len] = ENDSWAP_16 (temp) ;
+{
+       for (int i = 0 ; i < len ; i++)
+       {       short temp = ptr [i] ;
+               ptr [i] = ENDSWAP_16 (temp) ;
                } ;
 } /* endswap_short_array */
 
 static inline void
 endswap_short_copy (short *dest, const short *src, int len)
 {
-       while (--len >= 0)
-       {       dest [len] = ENDSWAP_16 (src [len]) ;
+       for (int i = 0 ; i < len ; i++)
+       {       dest [i] = ENDSWAP_16 (src [i]) ;
                } ;
 } /* endswap_short_copy */
 
 static inline void
 endswap_int_array (int *ptr, int len)
-{      int temp ;
-
-       while (--len >= 0)
-       {       temp = ptr [len] ;
-               ptr [len] = ENDSWAP_32 (temp) ;
+{
+       for (int i = 0 ; i < len ; i++)
+       {       int temp = ptr [i] ;
+               ptr [i] = ENDSWAP_32 (temp) ;
                } ;
 } /* endswap_int_array */
 
 static inline void
 endswap_int_copy (int *dest, const int *src, int len)
 {
-       while (--len >= 0)
-       {       dest [len] = ENDSWAP_32 (src [len]) ;
+       for (int i = 0 ; i < len ; i++)
+       {       dest [i] = ENDSWAP_32 (src [i]) ;
                } ;
 } /* endswap_int_copy */
 
@@ -334,21 +318,19 @@ endswap_int_copy (int *dest, const int *src, int len)
 
 static inline void
 endswap_int64_t_array (int64_t *ptr, int len)
-{      int64_t value ;
-
-       while (--len >= 0)
-       {       value = ptr [len] ;
-               ptr [len] = ENDSWAP_64 (value) ;
+{
+       for (int i = 0 ; i < len ; i++)
+       {       int64_t value = ptr [i] ;
+               ptr [i] = ENDSWAP_64 (value) ;
                } ;
 } /* endswap_int64_t_array */
 
 static inline void
 endswap_int64_t_copy (int64_t *dest, const int64_t *src, int len)
-{      int64_t value ;
-
-       while (--len >= 0)
-       {       value = src [len] ;
-               dest [len] = ENDSWAP_64 (value) ;
+{
+       for (int i = 0 ; i < len ; i++)
+       {       int64_t value = src [i] ;
+               dest [i] = ENDSWAP_64 (value) ;
                } ;
 } /* endswap_int64_t_copy */
 
index 63beda8..2517723 100644 (file)
 #include <io.h>
 #endif
 
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
 #define                SNDFILE_MAGICK  0x1234C0DE
 
 #ifdef __APPLE__
@@ -277,7 +282,18 @@ ErrorStruct SndfileErrors [] =
        {       SFE_FILENAME_TOO_LONG   , "Error : Supplied filename too long." },
        {       SFE_NEGATIVE_RW_LEN             , "Error : Length parameter passed to read/write is negative." },
 
-       {       SFE_OPUS_BAD_SAMPLERATE , "Error : Opus only supports sample rates of 8000, 12000, 16000, 24000 and 48000." },
+       {       SFE_OPUS_BAD_SAMPLERATE , "Error : Opus only supports sample rates of 8000, 12000, 16000, 24000, and 48000." },
+
+       {       SFE_MPEG_BAD_SAMPLERATE , "Error : MPEG-1/2/2.5 only supports sample rates of 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, and 48000." },
+
+       {       SFE_CAF_NOT_CAF                 , "Error : Not a CAF file." },
+       {       SFE_CAF_NO_DESC                 , "Error : No 'desc' marker in CAF file." },
+       {       SFE_CAF_BAD_PEAK                , "Error : Bad 'PEAK' chunk in CAF file." },
+
+       {       SFE_AVR_NOT_AVR                 , "Error : Not an AVR file." },
+       {       SFE_AVR_BAD_REZ_SIGN    , "Error : Bad rez/sign combination." },
+
+       {       SFE_MPC_NO_MARKER               , "Error : No marker in MPC2K file." },
 
        {       SFE_MAX_ERROR                   , "Maximum error number." },
        {       SFE_MAX_ERROR + 1               , NULL }
@@ -291,7 +307,6 @@ static int  guess_file_type (SF_PRIVATE *psf) ;
 static int     validate_sfinfo (SF_INFO *sfinfo) ;
 static int     validate_psf (SF_PRIVATE *psf) ;
 static void    save_header_info (SF_PRIVATE *psf) ;
-static int     copy_filename (SF_PRIVATE *psf, const char *path) ;
 static int     psf_close (SF_PRIVATE *psf) ;
 
 static int     try_resource_fork (SF_PRIVATE * psf) ;
@@ -332,6 +347,14 @@ static char        sf_syserr [SF_SYSERR_LEN] = { 0 } ;
 SNDFILE*
 sf_open        (const char *path, int mode, SF_INFO *sfinfo)
 {      SF_PRIVATE      *psf ;
+       const char *utf8path_ptr ;
+#ifdef _WIN32
+       LPWSTR wpath ;
+       int nResult ;
+       int wpath_len ;
+       char utf8path [SF_FILENAME_LEN] ;
+       DWORD dwError ;
+#endif
 
        /* Ultimate sanity check. */
        assert (sizeof (sf_count_t) == 8) ;
@@ -345,8 +368,62 @@ sf_open    (const char *path, int mode, SF_INFO *sfinfo)
 
        psf_log_printf (psf, "File : %s\n", path) ;
 
-       if (copy_filename (psf, path) != 0)
+#ifdef _WIN32
+       nResult = MultiByteToWideChar (CP_ACP, 0, path, -1, NULL, 0) ;
+       if (nResult == 0)
+       {       sf_errno = SF_ERR_UNSUPPORTED_ENCODING ;
+               psf_close (psf) ;
+               return NULL ;
+               } ;
+
+       wpath_len = nResult ;
+       wpath = malloc (wpath_len * sizeof (WCHAR)) ;
+       if (!wpath)
+       {       sf_errno = SFE_MALLOC_FAILED ;
+               psf_close (psf) ;
+               return NULL ;
+               } ;
+
+       nResult = MultiByteToWideChar (CP_ACP, 0, path, -1, wpath, wpath_len) ;
+       if (nResult == 0)
+       {       sf_errno = SF_ERR_UNSUPPORTED_ENCODING ;
+               free (wpath) ;
+               psf_close (psf) ;
+               return NULL ;
+               } ;
+
+       nResult = WideCharToMultiByte (CP_UTF8, 0, wpath, wpath_len, NULL, 0, NULL,
+               NULL) ;
+       if (nResult == 0)
+       {       sf_errno = SF_ERR_UNSUPPORTED_ENCODING ;
+               free (wpath) ;
+               psf_close (psf) ;
+               return NULL ;
+               } ;
+
+       nResult = WideCharToMultiByte (CP_UTF8, 0, wpath, wpath_len, utf8path,
+               SF_FILENAME_LEN, NULL, NULL) ;
+
+       free (wpath) ;
+
+       if (nResult == 0)
+       {       dwError = GetLastError () ;
+               if (dwError == ERROR_INSUFFICIENT_BUFFER)
+                       sf_errno = SFE_FILENAME_TOO_LONG ;
+               else
+                       sf_errno = SF_ERR_UNSUPPORTED_ENCODING ;
+               psf_close (psf) ;
+               return NULL ;
+               } ;
+
+       utf8path_ptr = utf8path ;
+#else
+       utf8path_ptr = path ;
+#endif
+
+       if (psf_copy_filename (psf, utf8path_ptr) != 0)
        {       sf_errno = psf->error ;
+               psf_close (psf) ;
                return  NULL ;
                } ;
 
@@ -381,7 +458,7 @@ sf_open_fd  (int fd, int mode, SF_INFO *sfinfo, int close_desc)
                } ;
 
        psf_init_files (psf) ;
-       copy_filename (psf, "") ;
+       psf_copy_filename (psf, "") ;
 
        psf->file.mode = mode ;
        psf_set_file (psf, fd) ;
@@ -614,6 +691,8 @@ sf_format_check     (const SF_INFO *info)
                                if ((subformat == SF_FORMAT_NMS_ADPCM_16 || subformat == SF_FORMAT_NMS_ADPCM_24 ||
                                                        subformat == SF_FORMAT_NMS_ADPCM_32) && info->channels == 1)
                                        return 1 ;
+                               if (subformat == SF_FORMAT_MPEG_LAYER_III && info->channels <= 2)
+                                       return 1 ;
                                break ;
 
                case SF_FORMAT_WAVEX :
@@ -884,6 +963,15 @@ sf_format_check    (const SF_INFO *info)
                                if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
                                        return 1 ;
                                break ;
+
+               case SF_FORMAT_MPEG :
+                               if (info->channels > 2)
+                                       return 0 ;
+                               if (endian != SF_ENDIAN_FILE)
+                                       return 0 ;
+                               if (subformat == SF_FORMAT_MPEG_LAYER_I || subformat == SF_FORMAT_MPEG_LAYER_II || subformat == SF_FORMAT_MPEG_LAYER_III)
+                                       return 1 ;
+                               break ;
                default : break ;
                } ;
 
@@ -1226,7 +1314,7 @@ sf_command        (SNDFILE *sndfile, int command, void *data, int datasize)
                                return SF_FALSE ;
                                } ;
 
-                       if (NOT (broadcast_var_set (psf, data, datasize)))
+                       if (!broadcast_var_set (psf, data, datasize))
                                return SF_FALSE ;
 
                        if (psf->write_header)
@@ -1255,7 +1343,7 @@ sf_command        (SNDFILE *sndfile, int command, void *data, int datasize)
                        {       psf->error = SFE_CMD_HAS_DATA ;
                                return SF_FALSE ;
                                } ;
-                       if (NOT (cart_var_set (psf, data, datasize)))
+                       if (!cart_var_set (psf, data, datasize))
                                return SF_FALSE ;
                        if (psf->write_header)
                                psf->write_header (psf, SF_TRUE) ;
@@ -2612,7 +2700,7 @@ try_resource_fork (SF_PRIVATE * psf)
                } ;
 
        /* More checking here. */
-       psf_log_printf (psf, "Resource fork : %s\n", psf->rsrc.path.c) ;
+       psf_log_printf (psf, "Resource fork : %s\n", psf->rsrc.path) ;
 
        return SF_FORMAT_SD2 ;
 } /* try_resource_fork */
@@ -2623,7 +2711,7 @@ format_from_extension (SF_PRIVATE *psf)
        char buffer [16] ;
        int format = 0 ;
 
-       if ((cptr = strrchr (psf->file.name.c, '.')) == NULL)
+       if ((cptr = strrchr (psf->file.name, '.')) == NULL)
                return 0 ;
 
        cptr ++ ;
@@ -2668,6 +2756,13 @@ format_from_extension (SF_PRIVATE *psf)
                psf->sf.samplerate = 8000 ;
                format = SF_FORMAT_RAW | SF_FORMAT_GSM610 ;
                }
+       else if (strcmp (cptr, "mp3") == 0)
+       {       /*
+                * MPEG streams are quite tollerate of crap. If we couldn't identify a
+                * MP3 stream, but it has a .mp3 extension, let libmpg123 have a try.
+                */
+               format = SF_FORMAT_MPEG ;
+               }
 
        /* For RAW files, make sure the dataoffset if set correctly. */
        if ((SF_CONTAINER (format)) == SF_FORMAT_RAW)
@@ -2680,6 +2775,7 @@ static int
 guess_file_type (SF_PRIVATE *psf)
 {      uint32_t buffer [3], format ;
 
+retry:
        if (psf_binheader_readf (psf, "b", &buffer, SIGNED_SIZEOF (buffer)) != SIGNED_SIZEOF (buffer))
        {       psf->error = SFE_BAD_FILE_READ ;
                return 0 ;
@@ -2776,11 +2872,18 @@ guess_file_type (SF_PRIVATE *psf)
        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 (0xFF, 0xE0, 0, 0)) == MAKE_MARKER (0xFF, 0xE0, 0, 0) && /* Frame sync */
+               (buffer [0] & MAKE_MARKER (0, 0x18, 0, 0)) != MAKE_MARKER (0, 0x08, 0, 0) && /* Valid MPEG version */
+               (buffer [0] & MAKE_MARKER (0, 0x06, 0, 0)) != MAKE_MARKER (0, 0, 0, 0) && /* Valid layer description */
+               (buffer [0] & MAKE_MARKER (0, 0, 0xF0, 0)) != MAKE_MARKER (0, 0, 0xF0, 0) && /* Valid bitrate */
+               (buffer [0] & MAKE_MARKER (0, 0, 0x0C, 0)) != MAKE_MARKER (0, 0, 0x0C, 0)) /* Valid samplerate */
+               return SF_FORMAT_MPEG ;
+
        if (buffer [0] == MAKE_MARKER ('I', 'D', '3', 2) || buffer [0] == MAKE_MARKER ('I', 'D', '3', 3)
                        || buffer [0] == MAKE_MARKER ('I', 'D', '3', 4))
        {       psf_log_printf (psf, "Found 'ID3' marker.\n") ;
                if (id3_skip (psf))
-                       return guess_file_type (psf) ;
+                       goto retry ;
                return 0 ;
                } ;
 
@@ -2805,11 +2908,11 @@ guess_file_type (SF_PRIVATE *psf)
 
 static int
 validate_sfinfo (SF_INFO *sfinfo)
-{      if (sfinfo->samplerate < 1)
+{      if ((sfinfo->samplerate < 1) || (sfinfo->samplerate > SF_MAX_SAMPLERATE))
                return 0 ;
        if (sfinfo->frames < 0)
                return 0 ;
-       if (sfinfo->channels < 1)
+       if ((sfinfo->channels < 1) || (sfinfo->channels > SF_MAX_CHANNELS))
                return 0 ;
        if ((SF_CONTAINER (sfinfo->format)) == 0)
                return 0 ;
@@ -2844,34 +2947,6 @@ save_header_info (SF_PRIVATE *psf)
 {      snprintf (sf_parselog, sizeof (sf_parselog), "%s", psf->parselog.buf) ;
 } /* save_header_info */
 
-static int
-copy_filename (SF_PRIVATE *psf, const char *path)
-{      const char *ccptr ;
-       char *cptr ;
-
-       if (strlen (path) > 1 && strlen (path) - 1 >= sizeof (psf->file.path.c))
-       {       psf->error = SFE_FILENAME_TOO_LONG ;
-               return psf->error ;
-               } ;
-
-       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->file.name.c, sizeof (psf->file.name.c), "%s", ccptr) ;
-
-       /* Now grab the 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->file.dir.c [0] = 0 ;
-
-       return 0 ;
-} /* copy_filename */
-
 /*==============================================================================
 */
 
@@ -3185,6 +3260,10 @@ psf_open_file (SF_PRIVATE *psf, SF_INFO *sfinfo)
                                error = mpc2k_open (psf) ;
                                break ;
 
+               case    SF_FORMAT_MPEG :
+                               error = mpeg_open (psf) ;
+                               break ;
+
                /* Lite remove end */
 
                default :
@@ -3205,6 +3284,7 @@ psf_open_file (SF_PRIVATE *psf, SF_INFO *sfinfo)
                                /* Actual embedded files. */
                                break ;
 
+                       case SF_FORMAT_MPEG :
                        case SF_FORMAT_FLAC :
                                /* Flac with an ID3v2 header? */
                                break ;
index 72d803f..a6b7232 100644 (file)
--- a/src/svx.c
+++ b/src/svx.c
@@ -240,12 +240,12 @@ svx_read_header   (SF_PRIVATE *psf)
 
                                        psf_log_printf (psf, " %M : %u\n", marker, chunk_size) ;
 
-                                       if (strlen (psf->file.name.c) != chunk_size)
-                                       {       if (chunk_size > sizeof (psf->file.name.c) - 1)
+                                       if (strlen (psf->file.name) != chunk_size)
+                                       {       if (chunk_size > sizeof (psf->file.name) - 1)
                                                        return SFE_SVX_BAD_NAME_LENGTH ;
 
-                                               psf_binheader_readf (psf, "b", psf->file.name.c, chunk_size) ;
-                                               psf->file.name.c [chunk_size] = 0 ;
+                                               psf_binheader_readf (psf, "b", psf->file.name, chunk_size) ;
+                                               psf->file.name [chunk_size] = 0 ;
                                                }
                                        else
                                                psf_binheader_readf (psf, "j", chunk_size) ;
@@ -307,7 +307,8 @@ svx_read_header     (SF_PRIVATE *psf)
                                        if ((chunk_size = psf_ftell (psf)) & 0x03)
                                        {       psf_log_printf (psf, "  Unknown chunk marker at position %d. Resynching.\n", chunk_size - 4) ;
 
-                                               psf_binheader_readf (psf, "j", -3) ;
+                                               chunk_size = chunk_size & 3 ;
+                                               psf_binheader_readf (psf, "j", 4 - chunk_size) ;
                                                break ;
                                                } ;
                                        psf_log_printf (psf, "*** Unknown chunk marker (%X) at position %D. Exiting parser.\n", marker, psf_ftell (psf) - 8) ;
@@ -380,7 +381,7 @@ svx_write_header (SF_PRIVATE *psf, int calc_length)
                psf_binheader_writef (psf, "Em44", BHWm (CHAN_MARKER), BHW4 (4), BHW4 (6)) ;
 
        /* Filename and annotation strings. */
-       psf_binheader_writef (psf, "Emsms", BHWm (NAME_MARKER), BHWs (psf->file.name.c), BHWm (ANNO_MARKER), BHWs (annotation)) ;
+       psf_binheader_writef (psf, "Emsms", BHWm (NAME_MARKER), BHWs (psf->file.name), BHWm (ANNO_MARKER), BHWs (annotation)) ;
 
        /* BODY marker and size. */
        psf_binheader_writef (psf, "Etm8", BHWm (BODY_MARKER), BHW8 ((psf->datalength < 0) ?
index dbea943..5ae81fb 100644 (file)
@@ -89,7 +89,11 @@ test_broadcast_var_set (void)
 static void
 test_broadcast_var_zero (void)
 {      SF_PRIVATE      sf_private, *psf ;
+#ifdef _MSC_VER
        SF_BROADCAST_INFO_VAR (0) bi ;
+#else
+       SF_BROADCAST_INFO_VAR () bi ;
+#endif
 
        psf = &sf_private ;
        memset (psf, 0, sizeof (sf_private)) ;
index 329e226..f6ee36e 100644 (file)
@@ -62,7 +62,7 @@ conversion_test (char endian)
        memset (psf, 0, sizeof (sf_private)) ;
 
        psf->file.mode = SFM_WRITE ;
-       snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
+       snprintf (psf->file.path, sizeof (psf->file.path), "%s", filename) ;
 
        if (psf_fopen (psf) != 0)
        {       printf ("\n\nError : failed to open file '%s' for write.\n\n", filename) ;
@@ -77,7 +77,7 @@ conversion_test (char endian)
        memset (psf, 0, sizeof (sf_private)) ;
 
        psf->file.mode = SFM_READ ;
-       snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
+       snprintf (psf->file.path, sizeof (psf->file.path), "%s", filename) ;
 
        if (psf_fopen (psf) != 0)
        {       printf ("\n\nError : failed to open file '%s' for read.\n\n", filename) ;
index 36a85b0..1e5b0f5 100644 (file)
@@ -73,7 +73,7 @@ file_open_test (const char *filename)
                } ;
 
        psf->file.mode = SFM_READ ;
-       snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
+       snprintf (psf->file.path, sizeof (psf->file.path), "%s", filename) ;
 
        /* Test that open for read fails if the file doesn't exist. */
        error = psf_fopen (psf) ;
@@ -91,7 +91,7 @@ file_open_test (const char *filename)
 
        test_close_or_die (psf, __LINE__) ;
 
-       unlink (psf->file.path.c) ;
+       unlink (psf->file.path) ;
 
        /* Test file open in read/write mode for a non-existant file. */
        psf->file.mode = SFM_RDWR ;
@@ -105,7 +105,7 @@ file_open_test (const char *filename)
 
        test_close_or_die (psf, __LINE__) ;
 
-       unlink (psf->file.path.c) ;
+       unlink (psf->file.path) ;
        puts ("ok") ;
 } /* file_open_test */
 
@@ -126,7 +126,7 @@ file_read_write_test (const char *filename)
 
        memset (&sf_data, 0, sizeof (sf_data)) ;
        psf = &sf_data ;
-       snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
+       snprintf (psf->file.path, sizeof (psf->file.path), "%s", filename) ;
 
        /* Test file open in write mode. */
        psf->file.mode = SFM_WRITE ;
@@ -282,7 +282,7 @@ file_truncate_test (const char *filename)
        memset (buffer, 0xEE, sizeof (buffer)) ;
 
        psf = &sf_data ;
-       snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
+       snprintf (psf->file.path, sizeof (psf->file.path), "%s", filename) ;
 
        /*
        ** Open the file write mode, write 0xEE data and then extend the file
@@ -302,13 +302,13 @@ file_truncate_test (const char *filename)
 
        for (k = 0 ; k < SIGNED_SIZEOF (buffer) / 2 ; k++)
                if (buffer [k] != 0xEE)
-               {       printf ("\n\nLine %d : buffer [%d] = %d (should be 0xEE)\n\n", __LINE__, k, buffer [k]) ;
+               {       printf ("\n\nLine %d : buffer [%d] = %hhu (should be 0xEE)\n\n", __LINE__, k, buffer [k]) ;
                        exit (1) ;
                        } ;
 
        for (k = SIGNED_SIZEOF (buffer) / 2 ; k < SIGNED_SIZEOF (buffer) ; k++)
                if (buffer [k] != 0)
-               {       printf ("\n\nLine %d : buffer [%d] = %d (should be 0)\n\n", __LINE__, k, buffer [k]) ;
+               {       printf ("\n\nLine %d : buffer [%d] = %hhu (should be 0)\n\n", __LINE__, k, buffer [k]) ;
                        exit (1) ;
                        } ;
 
@@ -339,7 +339,7 @@ file_seek_with_offset_test (const char *filename)
        memset (&sf_data, 0, sizeof (sf_data)) ;
        psf = &sf_data ;
        psf->file.mode = SFM_READ ;
-       snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
+       snprintf (psf->file.path, sizeof (psf->file.path), "%s", filename) ;
        test_open_or_die (psf, __LINE__) ;
 
        /* Gather basic info before setting offset. */
index e1806a1..ada6237 100644 (file)
@@ -113,6 +113,8 @@ test_log_printf (void)
        /* Test printing of strings. */
        CMP_4_ARGS (__LINE__, errors, "B %s, %3s, %8s, %-8s", "str") ;
 
+       CMP_4_ARGS (__LINE__, errors, "B %.2s, %.8s, %-8.8s, %-4.2s", "str") ;
+
        if (errors)
        {       puts ("\nExiting due to errors.\n") ;
                exit (1) ;
index 744e354..ed2f8ff 100644 (file)
@@ -793,69 +793,69 @@ unsigned char ulaw_encode [8193] =
 
 static inline void
 ulaw2s_array (unsigned char *buffer, int count, short *ptr)
-{      while (--count >= 0)
-               ptr [count] = ulaw_decode [(int) buffer [count]] ;
+{      for (int i = 0 ; i < count ; i++)
+               ptr [i] = ulaw_decode [(int) buffer [i]] ;
 } /* ulaw2s_array */
 
 static inline void
 ulaw2i_array (unsigned char *buffer, int count, int *ptr)
-{      while (--count >= 0)
-               ptr [count] = ((uint32_t) ulaw_decode [buffer [count]]) << 16 ;
+{      for (int i = 0 ; i < count ; i++)
+               ptr [i] = ((uint32_t) ulaw_decode [buffer [i]]) << 16 ;
 } /* ulaw2i_array */
 
 static inline void
 ulaw2f_array (unsigned char *buffer, int count, float *ptr, float normfact)
-{      while (--count >= 0)
-               ptr [count] = normfact * ulaw_decode [(int) buffer [count]] ;
+{      for (int i = 0 ; i < count ; i++)
+               ptr [i] = normfact * ulaw_decode [(int) buffer [i]] ;
 } /* ulaw2f_array */
 
 static inline void
 ulaw2d_array (const unsigned char *buffer, int count, double *ptr, double normfact)
-{      while (--count >= 0)
-               ptr [count] = normfact * ulaw_decode [(int) buffer [count]] ;
+{      for (int i = 0 ; i < count ; i++)
+               ptr [i] = normfact * ulaw_decode [(int) buffer [i]] ;
 } /* ulaw2d_array */
 
 static inline void
 s2ulaw_array (const short *ptr, int count, unsigned char *buffer)
-{      while (--count >= 0)
-       {       if (ptr [count] >= 0)
-                       buffer [count] = ulaw_encode [ptr [count] / 4] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       if (ptr [i] >= 0)
+                       buffer [i] = ulaw_encode [ptr [i] / 4] ;
                else
-                       buffer [count] = 0x7F & ulaw_encode [ptr [count] / -4] ;
+                       buffer [i] = 0x7F & ulaw_encode [ptr [i] / -4] ;
                } ;
 } /* s2ulaw_array */
 
 static inline void
 i2ulaw_array (const int *ptr, int count, unsigned char *buffer)
-{      while (--count >= 0)
-       {       if (ptr [count] == INT_MIN)
-                       buffer [count] = ulaw_encode [INT_MAX >> (16 + 2)] ;
-               else if (ptr [count] >= 0)
-                       buffer [count] = ulaw_encode [ptr [count] >> (16 + 2)] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       if (ptr [i] == INT_MIN)
+                       buffer [i] = ulaw_encode [INT_MAX >> (16 + 2)] ;
+               else if (ptr [i] >= 0)
+                       buffer [i] = ulaw_encode [ptr [i] >> (16 + 2)] ;
                else
-                       buffer [count] = 0x7F & ulaw_encode [-ptr [count] >> (16 + 2)] ;
+                       buffer [i] = 0x7F & ulaw_encode [-ptr [i] >> (16 + 2)] ;
                } ;
 } /* i2ulaw_array */
 
 static inline void
 f2ulaw_array (const float *ptr, int count, unsigned char *buffer, float normfact)
-{      while (--count >= 0)
-       {       if (ptr [count] >= 0)
-                       buffer [count] = ulaw_encode [psf_lrintf (normfact * ptr [count])] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       if (ptr [i] >= 0)
+                       buffer [i] = ulaw_encode [psf_lrintf (normfact * ptr [i])] ;
                else
-                       buffer [count] = 0x7F & ulaw_encode [- psf_lrintf (normfact * ptr [count])] ;
+                       buffer [i] = 0x7F & ulaw_encode [- psf_lrintf (normfact * ptr [i])] ;
                } ;
 } /* f2ulaw_array */
 
 static inline void
 d2ulaw_array (const double *ptr, int count, unsigned char *buffer, double normfact)
-{      while (--count >= 0)
-       {       if (!isfinite (ptr [count]))
-                       buffer [count] = 0 ;
-               else if (ptr [count] >= 0)
-                       buffer [count] = ulaw_encode [psf_lrint (normfact * ptr [count])] ;
+{      for (int i = 0 ; i < count ; i++)
+       {       if (!isfinite (ptr [i]))
+                       buffer [i] = 0 ;
+               else if (ptr [i] >= 0)
+                       buffer [i] = ulaw_encode [psf_lrint (normfact * ptr [i])] ;
                else
-                       buffer [count] = 0x7F & ulaw_encode [- psf_lrint (normfact * ptr [count])] ;
+                       buffer [i] = 0x7F & ulaw_encode [- psf_lrint (normfact * ptr [i])] ;
                } ;
 } /* d2ulaw_array */
 
@@ -873,7 +873,7 @@ ulaw_read_ulaw2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
                ulaw2s_array (ubuf.ucbuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -895,7 +895,7 @@ ulaw_read_ulaw2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
                ulaw2i_array (ubuf.ucbuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -920,7 +920,7 @@ ulaw_read_ulaw2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
                ulaw2f_array (ubuf.ucbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -944,7 +944,7 @@ ulaw_read_ulaw2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
                ulaw2d_array (ubuf.ucbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -970,7 +970,7 @@ ulaw_write_s2ulaw   (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                s2ulaw_array (ptr + total, bufferlen, ubuf.ucbuf) ;
-               writecount = psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -992,7 +992,7 @@ ulaw_write_i2ulaw   (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                i2ulaw_array (ptr + total, bufferlen, ubuf.ucbuf) ;
-               writecount = psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1018,7 +1018,7 @@ ulaw_write_f2ulaw (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                f2ulaw_array (ptr + total, bufferlen, ubuf.ucbuf, normfact) ;
-               writecount = psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1044,7 +1044,7 @@ ulaw_write_d2ulaw (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                d2ulaw_array (ptr + total, bufferlen, ubuf.ucbuf, normfact) ;
-               writecount = psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
index 50c3d05..e206675 100644 (file)
@@ -128,7 +128,7 @@ vox_read_block (SF_PRIVATE *psf, IMA_OKI_ADPCM *pvox, short *ptr, int len)
        while (indx < len)
        {       pvox->code_count = (len - indx > IMA_OKI_ADPCM_PCM_LEN) ? IMA_OKI_ADPCM_CODE_LEN : (len - indx + 1) / 2 ;
 
-               if ((k = psf_fread (pvox->codes, 1, pvox->code_count, psf)) != pvox->code_count)
+               if ((k = (int) psf_fread (pvox->codes, 1, pvox->code_count, psf)) != pvox->code_count)
                {       if (psf_ftell (psf) != psf->filelength)
                                psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pvox->code_count) ;
                        if (k == 0)
@@ -275,7 +275,7 @@ vox_write_block (SF_PRIVATE *psf, IMA_OKI_ADPCM *pvox, const short *ptr, int len
 
                ima_oki_adpcm_encode_block (pvox) ;
 
-               if ((k = psf_fwrite (pvox->codes, 1, pvox->code_count, psf)) != pvox->code_count)
+               if ((k = (int) psf_fwrite (pvox->codes, 1, pvox->code_count, psf)) != pvox->code_count)
                        psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pvox->code_count) ;
 
                indx += pvox->pcm_count ;
index 426480b..14346cd 100644 (file)
--- a/src/w64.c
+++ b/src/w64.c
@@ -241,7 +241,9 @@ w64_read_header     (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
                        psf_binheader_readf (psf, "j", 8 - (psf->header.indx & 0x7)) ;
 
                /* Generate hash of 16 byte marker. */
-               marker = chunk_size = 0 ;
+               marker = 0 ;
+               chunk_size = 0 ;
+
                bytesread = psf_binheader_readf (psf, "eh8", &marker, &chunk_size) ;
                if (bytesread == 0)
                        break ;
index fd3e453..0dd6c73 100644 (file)
--- a/src/wav.c
+++ b/src/wav.c
 #define wvpk_MARKER (MAKE_MARKER ('w', 'v', 'p', 'k'))
 #define OggS_MARKER (MAKE_MARKER ('O', 'g', 'g', 'S'))
 
+/* ID3v1 trailer which can show up at the end and erronerously look like a chunk. */
+#define TAG__MARKER (MAKE_MARKER ('T', 'A', 'G', 0))
+#define TAG__MARKER_MASK (MAKE_MARKER (0xff, 0xff, 0xff, 0))
+
 #define WAVLIKE_PEAK_CHUNK_SIZE(ch)    (2 * sizeof (int) + ch * (sizeof (float) + sizeof (int)))
 
 
 enum
-{      HAVE_RIFF       = 0x01,
-       HAVE_WAVE       = 0x02,
-       HAVE_fmt        = 0x04,
-       HAVE_fact       = 0x08,
-       HAVE_PEAK       = 0x10,
-       HAVE_data       = 0x20,
-       HAVE_other      = 0x80000000
+{      HAVE_RIFF       = 1 << 0,
+       HAVE_WAVE       = 1 << 1,
+       HAVE_fmt        = 1 << 2,
+       HAVE_fact       = 1 << 3,
+       HAVE_PEAK       = 1 << 4,
+       HAVE_data       = 1 << 5,
+       HAVE_other      = 1 << 6
 } ;
 
 
-
 /*  known WAVEFORMATEXTENSIBLE GUIDS  */
 static const EXT_SUBFORMAT MSGUID_SUBTYPE_PCM =
 {      0x00000001, 0x0000, 0x0010, {   0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
@@ -204,6 +207,14 @@ wav_open   (SF_PRIVATE *psf)
                        psf->sf.frames = 0 ;
                        } ;
 
+#if (ENABLE_EXPERIMENTAL_CODE == 0)
+               /* For now, don't support writing MPEGLAYER3 WAVs, as we can't guarentee that
+               ** such a file written by libsndfile would have the same length when opened again.
+               */
+               if (subformat == SF_FORMAT_MPEG_LAYER_III)
+                       return SFE_UNSUPPORTED_ENCODING ;
+#endif
+
                if (subformat == SF_FORMAT_IMA_ADPCM || subformat == SF_FORMAT_MS_ADPCM)
                {       blockalign = wavlike_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
                        framesperblock = -1 ; /* Corrected later. */
@@ -274,6 +285,10 @@ wav_open   (SF_PRIVATE *psf)
                                        error = gsm610_init (psf) ;
                                        break ;
 
+               case SF_FORMAT_MPEG_LAYER_III :
+                                       error = mpeg_init (psf, SF_BITRATE_MODE_CONSTANT, SF_FALSE) ;
+                                       break ;
+
                default :       return SFE_UNIMPLEMENTED ;
                } ;
 
@@ -605,6 +620,15 @@ wav_read_header    (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
                                                break ;
                                                } ;
 
+                                       if ((marker & TAG__MARKER_MASK) == TAG__MARKER &&
+                                               psf_ftell (psf) - 8 + 128 == psf->filelength)
+                                       {       psf_log_printf (psf, "*** Hit ID3v1 trailer. Exiting parser.\n") ;
+                                               chunk_size = 128 ;
+                                               done = SF_TRUE ;
+                                               parsestage |= HAVE_other ;
+                                               break ;
+                                               } ;
+
                                        if (psf_isprint ((marker >> 24) & 0xFF) && psf_isprint ((marker >> 16) & 0xFF)
                                                && psf_isprint ((marker >> 8) & 0xFF) && psf_isprint (marker & 0xFF))
                                        {       psf_log_printf (psf, "*** %M : %u (unknown marker)\n", marker, chunk_size) ;
@@ -683,8 +707,6 @@ wav_read_header     (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
                        break ;
 
                case WAVE_FORMAT_NMS_VBXADPCM :
-                       *blockalign = wav_fmt->min.blockalign ;
-                       *framesperblock = 160 ;
                        switch (wav_fmt->min.bitwidth)
                        {       case 2 :
                                        psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16 ;
@@ -740,6 +762,12 @@ wav_read_header    (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
                                        psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_G721_32 ;
                                        break ;
 
+               case WAVE_FORMAT_MPEGLAYER3 :
+                                       psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_MPEG_LAYER_III ;
+                                       if (parsestage & HAVE_fact)
+                                               psf->sf.frames = fact_chunk.frames ;
+                                       break ;
+
                default : return SFE_UNIMPLEMENTED ;
                } ;
 
@@ -924,6 +952,59 @@ wav_write_fmt_chunk (SF_PRIVATE *psf)
                                        add_fact_chunk = SF_TRUE ;
                                        break ;
 
+#if (ENABLE_EXPERIMENTAL_CODE == 0)
+               case SF_FORMAT_MPEG_LAYER_III :
+                                       {       int bytespersec, blockalign, flags, blocksize, samplesperblock, codecdelay ;
+
+                                               /* Intended to be set as the average sample rate.
+                                               ** TODO: Maybe re-write this on close with final average
+                                               ** byterate? */
+                                               bytespersec             = psf->byterate (psf) ;
+
+                                               /* Average block size. Info only I think. */
+                                               blocksize               = (1152 * bytespersec) / psf->sf.samplerate ;
+
+                                               /* Can be set to block size IFF the block size is
+                                               ** constant, set to 1 otherwise. Constant sized
+                                               ** MPEG block streams are uncommon (CBR @ 32kHz and
+                                               ** 48kHz only. Meh. */
+                                               blockalign              = 1 ;
+
+                                               /* TODO: Only flags defined are padding-type. I /think/
+                                               ** Lame does ISO style padding by default, which has a
+                                               ** flag value of 0.
+                                               */
+                                               flags                   = 0 ;
+
+                                               /* Should only vary per MPEG 1.0/2.0 vs '2.5'.
+                                               ** TODO: Move this out to MPEG specific place? */
+                                               samplesperblock = psf->sf.samplerate >= 32000 ? 1152 : 576 ;
+
+                                               /* Set as 0 if unknown.
+                                               ** TODO: Plumb this cleanly from Lame.
+                                               */
+                                               codecdelay              = 0 ;
+
+                                               /* fmt chunk. */
+                                               fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 + 4 + 2 + 2 + 2 ;
+
+                                               /* fmt : size, WAV format type, channels. */
+                                               psf_binheader_writef (psf, "422", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_MPEGLAYER3), BHW2 (psf->sf.channels)) ;
+
+                                               /* fmt : samplerate, bytespersec. */
+                                               psf_binheader_writef (psf, "44", BHW4 (psf->sf.samplerate), BHW4 (bytespersec)) ;
+
+                                               /* fmt : blockalign, bitwidth, extrabytes, id. */
+                                               psf_binheader_writef (psf, "2222", BHW2 (blockalign), BHW2 (0), BHW2 (12), BHW2 (1)) ;
+
+                                               /* fmt : flags, blocksize, samplesperblock, codecdelay */
+                                               psf_binheader_writef (psf, "4222", BHW4 (flags), BHW2 (blocksize), BHW2 (samplesperblock), BHW2 (codecdelay)) ;
+                                               } ;
+
+                                       add_fact_chunk = SF_TRUE ;
+                                       break ;
+#endif
+
                default :       return SFE_UNIMPLEMENTED ;
                } ;
 
@@ -1325,8 +1406,9 @@ wav_read_smpl_chunk (SF_PRIVATE *psf, uint32_t chunklen)
        psf_log_printf (psf, "  SMPTE Format : %u\n", dword) ;
 
        bytesread += psf_binheader_readf (psf, "4", &dword) ;
-       snprintf (buffer, sizeof (buffer), "%02d:%02d:%02d %02d",
-                               (dword >> 24) & 0x7F, (dword >> 16) & 0x7F, (dword >> 8) & 0x7F, dword & 0x7F) ;
+       snprintf (buffer, sizeof (buffer), "%02"PRIu32 ":%02"PRIu32 ":%02"PRIu32
+                               " %02"PRIu32 "", (dword >> 24) & 0x7F, (dword >> 16) & 0x7F,
+                               (dword >> 8) & 0x7F, dword & 0x7F) ;
        psf_log_printf (psf, "  SMPTE Offset : %s\n", buffer) ;
 
        bytesread += psf_binheader_readf (psf, "4", &loop_count) ;
index b59c684..a3388d7 100644 (file)
@@ -173,6 +173,7 @@ wavlike_read_fmt_chunk (SF_PRIVATE *psf, int fmtsize)
        {       switch (wav_fmt->format)
                {       case WAVE_FORMAT_GSM610 :
                        case WAVE_FORMAT_IPP_ITU_G_723_1 :
+                       case WAVE_FORMAT_MPEGLAYER3 :
                                        psf_log_printf (psf, "  Bit Width     : %d\n", wav_fmt->min.bitwidth) ;
                                        break ;
                        default :
@@ -183,7 +184,8 @@ wavlike_read_fmt_chunk (SF_PRIVATE *psf, int fmtsize)
        {       switch (wav_fmt->format)
                {       case WAVE_FORMAT_GSM610 :
                        case WAVE_FORMAT_IPP_ITU_G_723_1 :
-               psf_log_printf (psf, "  Bit Width     : %d (should be 0)\n", wav_fmt->min.bitwidth) ;
+                       case WAVE_FORMAT_MPEGLAYER3 :
+                                       psf_log_printf (psf, "  Bit Width     : %d (should be 0)\n", wav_fmt->min.bitwidth) ;
                                        break ;
                        default :
                                        psf_log_printf (psf, "  Bit Width     : %d\n", wav_fmt->min.bitwidth) ;
@@ -306,6 +308,23 @@ wavlike_read_fmt_chunk (SF_PRIVATE *psf, int fmtsize)
                                psf_log_printf (psf, "  Samples/Block : %d\n", wav_fmt->gsm610.samplesperblock) ;
                                break ;
 
+               case WAVE_FORMAT_MPEGLAYER3 :
+                               bytesread += psf_binheader_readf (psf, "24222", &(wav_fmt->mpeg3.extrabytes),
+                                       &(wav_fmt->mpeg3.id), &(wav_fmt->mpeg3.flags), &(wav_fmt->mpeg3.blocksize),
+                                       &(wav_fmt->mpeg3.samplesperblock), &(wav_fmt->mpeg3.codecdelay)) ;
+
+                               psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->mpeg3.bytespersec) ;
+                               psf_log_printf (psf, "  Extra Bytes   : %d\n", wav_fmt->mpeg3.extrabytes) ;
+                               if (wav_fmt->mpeg3.id != 1)
+                                       psf_log_printf (psf, "  ID            : %d (unknown, should be 1)\n", wav_fmt->mpeg3.id) ;
+                               else
+                                       psf_log_printf (psf, "  ID            : MPEGLAYER3_ID_MPEG\n") ;
+                               psf_log_printf (psf, "  Flags         : 0x%08x\n", wav_fmt->mpeg3.flags) ;
+                               psf_log_printf (psf, "  Block Size    : %d\n", wav_fmt->mpeg3.blocksize) ;
+                               psf_log_printf (psf, "  Samples/Block : %d\n", wav_fmt->mpeg3.samplesperblock) ;
+                               psf_log_printf (psf, "  Codec Delay   : %d samples\n", wav_fmt->mpeg3.codecdelay) ;
+                               break ;
+
                case WAVE_FORMAT_EXTENSIBLE :
                                if (wav_fmt->ext.bytespersec != wav_fmt->ext.samplerate * wav_fmt->ext.blockalign)
                                        psf_log_printf (psf, "  Bytes/sec     : %d (should be %d)\n", wav_fmt->ext.bytespersec, wav_fmt->ext.samplerate * wav_fmt->ext.blockalign) ;
@@ -830,7 +849,11 @@ wavlike_read_cart_chunk (SF_PRIVATE *psf, uint32_t chunksize)
                return 0 ;
                } ;
 
-       if (chunksize >= sizeof (SF_CART_INFO_16K))
+       /*
+       **      SF_CART_INFO_16K has an extra field 'tag_text_size' that isn't part
+       **      of the chunk, so don't include it in the size check.
+       */
+       if (chunksize >= sizeof (SF_CART_INFO_16K) - 4)
        {       psf_log_printf (psf, "cart : %u too big to be handled\n", chunksize) ;
                psf_binheader_readf (psf, "j", chunksize) ;
                return 0 ;
index 4cde1e9..686287d 100644 (file)
@@ -264,6 +264,21 @@ typedef    struct
 } GSM610_WAV_FMT ;
 
 typedef struct
+{      unsigned short  format ;
+       unsigned short  channels ;
+       unsigned int    samplerate ;
+       unsigned int    bytespersec ;
+       unsigned short  blockalign ;
+       unsigned short  bitwidth ;
+       unsigned short  extrabytes ;
+       unsigned short  id ;
+       unsigned int    flags ;
+       unsigned short  blocksize ;
+       unsigned short  samplesperblock ;
+       unsigned short  codecdelay ;
+} MPEGLAYER3_WAV_FMT ;
+
+typedef struct
 {      unsigned int    esf_field1 ;
        unsigned short  esf_field2 ;
        unsigned short  esf_field3 ;
@@ -291,6 +306,7 @@ typedef union
        G72x_ADPCM_WAV_FMT      g72x ;
        EXTENSIBLE_WAV_FMT      ext ;
        GSM610_WAV_FMT          gsm610 ;
+       MPEGLAYER3_WAV_FMT      mpeg3 ;
        WAV_FMT_SIZE20          size20 ;
        char                            padding [512] ;
 } WAV_FMT ;
index 2ef3002..c11ed9b 100644 (file)
 #if OS_IS_WIN32
 #include <windows.h>
 
-#define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
 #include "sndfile.h"
 #include "common.h"
 
 extern int sf_errno ;
 
-static void copy_filename (SF_PRIVATE * psf, LPCWSTR wpath) ;
-
 SNDFILE*
 sf_wchar_open (LPCWSTR wpath, int mode, SF_INFO *sfinfo)
 {      SF_PRIVATE      *psf ;
-       char utf8name [512] ;
+       char utf8name [SF_BUFFER_LEN] ;
+       DWORD dwError ;
 
        if ((psf = psf_allocate ()) == NULL)
        {       sf_errno = SFE_MALLOC_FAILED ;
@@ -48,12 +46,20 @@ sf_wchar_open (LPCWSTR wpath, int mode, SF_INFO *sfinfo)
        psf_init_files (psf) ;
 
        if (WideCharToMultiByte (CP_UTF8, 0, wpath, -1, utf8name, sizeof (utf8name), NULL, NULL) == 0)
-               psf->file.path.wc [0] = 0 ;
+       {       dwError = GetLastError () ;
+               if (dwError == ERROR_INSUFFICIENT_BUFFER)
+                       sf_errno = SFE_FILENAME_TOO_LONG ;
+               else
+                       sf_errno = SF_ERR_UNSUPPORTED_ENCODING ;
+
+               sf_close (psf) ;
+
+               return NULL ;
+               } ;
 
        psf_log_printf (psf, "File : '%s' (utf-8 converted from ucs-2)\n", utf8name) ;
 
-       copy_filename (psf, wpath) ;
-       psf->file.use_wchar = SF_TRUE ;
+       psf_copy_filename (psf, utf8name) ;
        psf->file.mode = mode ;
 
        psf->error = psf_fopen (psf) ;
@@ -61,32 +67,4 @@ sf_wchar_open (LPCWSTR wpath, int mode, SF_INFO *sfinfo)
        return psf_open_file (psf, sfinfo) ;
 } /* sf_wchar_open */
 
-
-static void
-copy_filename (SF_PRIVATE *psf, LPCWSTR wpath)
-{      const wchar_t *cwcptr ;
-       wchar_t *wcptr ;
-
-       wcsncpy (psf->file.path.wc, wpath, ARRAY_LEN (psf->file.path.wc)) ;
-       psf->file.path.wc [ARRAY_LEN (psf->file.path.wc) - 1] = 0 ;
-       if ((cwcptr = wcsrchr (wpath, '/')) || (cwcptr = wcsrchr (wpath, '\\')))
-               cwcptr ++ ;
-       else
-               cwcptr = wpath ;
-
-       wcsncpy (psf->file.name.wc, cwcptr, ARRAY_LEN (psf->file.name.wc)) ;
-       psf->file.name.wc [ARRAY_LEN (psf->file.name.wc) - 1] = 0 ;
-
-       /* Now grab the directory. */
-       wcsncpy (psf->file.dir.wc, wpath, ARRAY_LEN (psf->file.dir.wc)) ;
-       psf->file.dir.wc [ARRAY_LEN (psf->file.dir.wc) - 1] = 0 ;
-
-       if ((wcptr = wcsrchr (psf->file.dir.wc, '/')) || (wcptr = wcsrchr (psf->file.dir.wc, '\\')))
-               wcptr [1] = 0 ;
-       else
-               psf->file.dir.wc [0] = 0 ;
-
-       return ;
-} /* copy_filename */
-
 #endif
index c102060..e816947 100644 (file)
--- a/src/xi.c
+++ b/src/xi.c
@@ -252,7 +252,7 @@ dpcm_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
                bufferlen = ARRAY_LEN (ubuf.sbuf) ;
                while (total > 0)
                {       len = (total > bufferlen) ? bufferlen : total ;
-                       total -= dpcm_read_dles2s (psf, ubuf.sbuf, len) ;
+                       total -= (int) dpcm_read_dles2s (psf, ubuf.sbuf, len) ;
                        } ;
                }
        else
@@ -260,7 +260,7 @@ dpcm_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
                bufferlen = ARRAY_LEN (ubuf.sbuf) ;
                while (total > 0)
                {       len = (total > bufferlen) ? bufferlen : total ;
-                       total -= dpcm_read_dsc2s (psf, ubuf.sbuf, len) ;
+                       total -= (int) dpcm_read_dsc2s (psf, ubuf.sbuf, len) ;
                        } ;
                } ;
 
@@ -312,10 +312,6 @@ xi_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
 
        psf_binheader_writef (psf, "b", BHWv (pxi->sample_name), BHWz (sizeof (pxi->sample_name))) ;
 
-
-
-
-
        /* Header construction complete so write it out. */
        psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ;
 
@@ -409,8 +405,6 @@ xi_read_header (SF_PRIVATE *psf)
 
                psf_log_printf (psf, "  size    : %d\n", sample_sizes [k]) ;
 
-
-
                psf_log_printf (psf, "  loop\n    begin : %d\n    end   : %d\n", loop_begin, loop_end) ;
 
                psf_log_printf (psf, "  volume  : %u\n  f. tune : %d\n  flags   : 0x%02X ",
@@ -522,7 +516,7 @@ dpcm_read_dsc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                dsc2s_array (pxi, ubuf.scbuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -548,7 +542,7 @@ dpcm_read_dsc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                dsc2i_array (pxi, ubuf.scbuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -577,7 +571,7 @@ dpcm_read_dsc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                dsc2f_array (pxi, ubuf.scbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -606,7 +600,7 @@ dpcm_read_dsc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                dsc2d_array (pxi, ubuf.scbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -635,7 +629,7 @@ dpcm_read_dles2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                dles2s_array (pxi, ubuf.sbuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -661,7 +655,7 @@ dpcm_read_dles2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                dles2i_array (pxi, ubuf.sbuf, readcount, ptr + total) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -690,7 +684,7 @@ dpcm_read_dles2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                dles2f_array (pxi, ubuf.sbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -719,7 +713,7 @@ dpcm_read_dles2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
        while (len > 0)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
-               readcount = psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               readcount = (int) psf_fread (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                dles2d_array (pxi, ubuf.sbuf, readcount, ptr + total, normfact) ;
                total += readcount ;
                if (readcount < bufferlen)
@@ -760,7 +754,7 @@ dpcm_write_s2dsc (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                s2dsc_array (pxi, ptr + total, ubuf.scbuf, bufferlen) ;
-               writecount = psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -786,7 +780,7 @@ dpcm_write_i2dsc (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                i2dsc_array (pxi, ptr + total, ubuf.scbuf, bufferlen) ;
-               writecount = psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -815,7 +809,7 @@ dpcm_write_f2dsc (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                f2dsc_array (pxi, ptr + total, ubuf.scbuf, bufferlen, normfact) ;
-               writecount = psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -844,7 +838,7 @@ dpcm_write_d2dsc (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                d2dsc_array (pxi, ptr + total, ubuf.scbuf, bufferlen, normfact) ;
-               writecount = psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.scbuf, sizeof (signed char), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -871,7 +865,7 @@ dpcm_write_s2dles (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                s2dles_array (pxi, ptr + total, ubuf.sbuf, bufferlen) ;
-               writecount = psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -897,7 +891,7 @@ dpcm_write_i2dles (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                i2dles_array (pxi, ptr + total, ubuf.sbuf, bufferlen) ;
-               writecount = psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -926,7 +920,7 @@ dpcm_write_f2dles (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                f2dles_array (pxi, ptr + total, ubuf.sbuf, bufferlen, normfact) ;
-               writecount = psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -955,7 +949,7 @@ dpcm_write_d2dles (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
        {       if (len < bufferlen)
                        bufferlen = (int) len ;
                d2dles_array (pxi, ptr + total, ubuf.sbuf, bufferlen, normfact) ;
-               writecount = psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
+               writecount = (int) psf_fwrite (ubuf.sbuf, sizeof (short), bufferlen, psf) ;
                total += writecount ;
                if (writecount < bufferlen)
                        break ;
@@ -1227,4 +1221,3 @@ d2dles_array (XI_PRIVATE *pxi, const double *src, short *dest, int count, double
 
        pxi->last_16 = last_val ;
 } /* d2dles_array */
-
index b928083..01b3dc4 100644 (file)
@@ -49,7 +49,7 @@ main (void)
 
        print_test_name ("alaw_test", "encoder") ;
 
-       filename = "test.raw" ;
+       filename = "alaw_test.raw" ;
 
        sf_info_setup (&sfinfo, SF_FORMAT_RAW | SF_FORMAT_ALAW, 44100, 1) ;
 
index ed34064..0e358e8 100644 (file)
@@ -38,8 +38,8 @@
 #define LOG_BUFFER_SIZE                1024
 
 static void    chunk_test (const char *filename, int format) ;
-static void wav_subchunk_test (size_t chunk_size) ;
-static void    large_free_test (const char *filename, int format, size_t chunk_size) ;
+static void wav_subchunk_test (unsigned int chunk_size) ;
+static void    large_free_test (const char *filename, int format, unsigned int chunk_size) ;
 
 int
 main (int argc, char *argv [])
@@ -133,7 +133,7 @@ chunk_test_helper (const char *filename, int format, const char * testdata)
        snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ;
        chunk_info.id_size = 4 ;
        chunk_info.data = strdup (testdata) ;
-       chunk_info.datalen = strlen (chunk_info.data) ;
+       chunk_info.datalen = (unsigned int) strlen (chunk_info.data) ;
 
        length_before = chunk_info.datalen ;
 
@@ -224,7 +224,7 @@ multichunk_test_helper (const char *filename, int format, const char * testdata
                chunk_info.id_size = 4 ;
 
                chunk_info.data = strdup (testdata [i]) ;
-               chunk_info.datalen = strlen (chunk_info.data) ;
+               chunk_info.datalen = (unsigned int) strlen (chunk_info.data) ;
 
                length_before [i] = chunk_info.datalen ;
 
@@ -316,7 +316,7 @@ chunk_test (const char *filename, int format)
 
 
 static void
-wav_subchunk_test (size_t chunk_size)
+wav_subchunk_test (unsigned int chunk_size)
 {      SNDFILE                 * file ;
        SF_INFO                 sfinfo ;
        SF_CHUNK_INFO   chunk_info ;
@@ -325,7 +325,7 @@ wav_subchunk_test (size_t chunk_size)
        short audio [16] ;
        int     err, value ;
 
-       snprintf (filename, sizeof (filename), "subchunk_%04d.wav", (int) chunk_size) ;
+       snprintf (filename, sizeof (filename), "subchunk_%04u.wav", chunk_size) ;
        print_test_name (__func__, filename) ;
 
        exit_if_true (sizeof (chunk_data) < chunk_size, "\n\nLine %d : sizeof (data) < chunk_size\n\n", __LINE__) ;
@@ -353,7 +353,7 @@ wav_subchunk_test (size_t chunk_size)
        snprintf (chunk_info.id, sizeof (chunk_info.id), "LIST") ;
        chunk_info.id_size = 4 ;
        chunk_info.data = chunk_data ;
-       chunk_info.datalen = chunk_size ;
+       chunk_info.datalen = (unsigned int) chunk_size ;
 
        err = sf_set_chunk (file, &chunk_info) ;
        exit_if_true (
@@ -386,7 +386,7 @@ wav_subchunk_test (size_t chunk_size)
 } /* wav_subchunk_test */
 
 static void
-large_free_test (const char *filename, int format, size_t chunk_size)
+large_free_test (const char *filename, int format, unsigned int chunk_size)
 {      SNDFILE                 * file ;
        SF_INFO                 sfinfo ;
        SF_CHUNK_INFO   chunk_info ;
index 625d8e5..86cbcfb 100644 (file)
@@ -115,8 +115,8 @@ main (int argc, char *argv [])
        {       /*      Preliminary float/double normalisation tests. More testing
                **      is done in the program 'floating_point_test'.
                */
-               float_norm_test         ("float.wav") ;
-               double_norm_test        ("double.wav") ;
+               float_norm_test         ("cmd_float.wav") ;
+               double_norm_test        ("cmd_double.wav") ;
                test_count ++ ;
                } ;
 
@@ -239,9 +239,9 @@ float_norm_test (const char *filename)
 
        /* Create float_data with all values being less than 1.0. */
        for (k = 0 ; k < BUFFER_LEN / 2 ; k++)
-               float_data [k] = (k + 5) / (2.0 * BUFFER_LEN) ;
+               float_data [k] = (k + 5) / (2.0f * BUFFER_LEN) ;
        for (k = BUFFER_LEN / 2 ; k < BUFFER_LEN ; k++)
-               float_data [k] = (k + 5) ;
+               float_data [k] = (float) (k + 5) ;
 
        if (! (file = sf_open (filename, SFM_WRITE, &sfinfo)))
        {       printf ("Line %d: sf_open_write failed with error : ", __LINE__) ;
@@ -252,7 +252,7 @@ float_norm_test (const char *filename)
 
        /* Normalisation is on by default so no need to do anything here. */
 
-       if ((k = sf_write_float (file, float_data, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
+       if ((k = (unsigned int) sf_write_float (file, float_data, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
        {       printf ("Line %d: sf_write_float failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
                exit (1) ;
                } ;
@@ -260,7 +260,7 @@ float_norm_test (const char *filename)
        /* Turn normalisation off. */
        sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
 
-       if ((k = sf_write_float (file, float_data + BUFFER_LEN / 2, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
+       if ((k = (unsigned int) sf_write_float (file, float_data + BUFFER_LEN / 2, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
        {       printf ("Line %d: sf_write_float failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
                exit (1) ;
                } ;
@@ -291,7 +291,7 @@ float_norm_test (const char *filename)
                } ;
 
        /* Read float_data and check that it is normalised (ie default). */
-       if ((k = sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN)
+       if ((k = (unsigned int) sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN)
        {       printf ("\n\nLine %d: sf_read_float failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
                exit (1) ;
                } ;
@@ -306,7 +306,7 @@ float_norm_test (const char *filename)
        sf_seek (file, 0, SEEK_SET) ;
        sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
 
-       if ((k = sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN)
+       if ((k = (unsigned int) sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN)
        {       printf ("\n\nLine %d: sf_read_float failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
                exit (1) ;
                } ;
@@ -321,7 +321,7 @@ float_norm_test (const char *filename)
        sf_seek (file, 0, SEEK_SET) ;
        sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_TRUE) ;
 
-       if ((k = sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN)
+       if ((k = (unsigned int) sf_read_float (file, float_data, BUFFER_LEN)) != BUFFER_LEN)
        {       printf ("\n\nLine %d: sf_read_float failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
                exit (1) ;
                } ;
@@ -369,7 +369,7 @@ double_norm_test (const char *filename)
        /* Normailsation is on by default so no need to do anything here. */
        /*-sf_command (file, "set-norm-double", "true", 0) ;-*/
 
-       if ((k = sf_write_double (file, double_data, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
+       if ((k = (unsigned int) sf_write_double (file, double_data, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
        {       printf ("Line %d: sf_write_double failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
                exit (1) ;
                } ;
@@ -377,7 +377,7 @@ double_norm_test (const char *filename)
        /* Turn normalisation off. */
        sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
 
-       if ((k = sf_write_double (file, double_data + BUFFER_LEN / 2, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
+       if ((k = (unsigned int) sf_write_double (file, double_data + BUFFER_LEN / 2, BUFFER_LEN / 2)) != BUFFER_LEN / 2)
        {       printf ("Line %d: sf_write_double failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
                exit (1) ;
                } ;
@@ -407,7 +407,7 @@ double_norm_test (const char *filename)
                } ;
 
        /* Read double_data and check that it is normalised (ie default). */
-       if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN)
+       if ((k = (unsigned int) sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN)
        {       printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
                exit (1) ;
                } ;
@@ -422,7 +422,7 @@ double_norm_test (const char *filename)
        sf_seek (file, 0, SEEK_SET) ;
        sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
 
-       if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN)
+       if ((k = (unsigned int) sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN)
        {       printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
                exit (1) ;
                } ;
@@ -437,7 +437,7 @@ double_norm_test (const char *filename)
        sf_seek (file, 0, SEEK_SET) ;
        sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_TRUE) ;
 
-       if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN)
+       if ((k = (unsigned int) sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN)
        {       printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ;
                exit (1) ;
                } ;
@@ -532,7 +532,7 @@ format_tests        (void)
        /* Now test subtype formats. */
        sf_command (NULL, SFC_GET_FORMAT_SUBTYPE_COUNT, &count, sizeof (int)) ;
 
-       if (count < 0 || count > 30)
+       if (count < 0 || count > 33)
        {       printf ("Line %d: Weird count.\n", __LINE__) ;
                exit (1) ;
                } ;
@@ -1021,7 +1021,7 @@ cue_test_var (const char *filename, int filetype, int count)
        sfinfo.channels         = 1 ;
 
        file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
-       if (sf_command (file, SFC_SET_CUE, write_cue, cues_size) == SF_FALSE)
+       if (sf_command (file, SFC_SET_CUE, write_cue, (int) cues_size) == SF_FALSE)
        {       printf ("\n\nLine %d : sf_command (SFC_SET_CUE) failed with %d cues, datasize %zu --> error: %s\n\n", __LINE__, count, cues_size, sf_strerror (file)) ;
                exit (1) ;
                } ;
@@ -1032,7 +1032,7 @@ cue_test_var (const char *filename, int filetype, int count)
 
        file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
 
-       if (sf_command (file, SFC_GET_CUE, read_cue, cues_size) == SF_FALSE)
+       if (sf_command (file, SFC_GET_CUE, read_cue, (int) cues_size) == SF_FALSE)
        {       printf ("\n\nLine %d : sf_command (SFC_GET_CUE) failed with %d cues, datasize %zu --> error: %s\n\n", __LINE__, count, cues_size, sf_strerror (file)) ;
                exit (1) ;
                } ;
@@ -1351,7 +1351,7 @@ broadcast_coding_history_test (const char *filename)
                exit (1) ;
                } ;
 
-       bc_write.coding_history_size = strlen (supplied_history) ;
+       bc_write.coding_history_size = (uint32_t) strlen (supplied_history) ;
        bc_write.coding_history_size = snprintf (bc_write.coding_history, sizeof (bc_write.coding_history), "%s", supplied_history) ;
 
        file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
@@ -1423,7 +1423,7 @@ broadcast_coding_history_size (const char *filename)
        for (k = 0 ; bc_write.coding_history_size < 512 ; k++)
        {       snprintf (bc_write.coding_history + bc_write.coding_history_size,
                        sizeof (bc_write.coding_history) - bc_write.coding_history_size, "line %4d\n", k) ;
-               bc_write.coding_history_size = strlen (bc_write.coding_history) ;
+               bc_write.coding_history_size = (uint32_t) strlen (bc_write.coding_history) ;
                } ;
 
        exit_if_true (bc_write.coding_history_size < 512,
@@ -1493,7 +1493,7 @@ cart_test (const char *filename, int filetype)
        ca_write.level_reference = 42 ;
        snprintf (ca_write.url, sizeof (ca_write.url), "http://www.test.com/test_url") ;
        snprintf (ca_write.tag_text, sizeof (ca_write.tag_text), "tag text test! \r\n") ; // must be terminated \r\n to be valid
-       ca_write.tag_text_size = strlen (ca_write.tag_text) ;
+       ca_write.tag_text_size = (uint32_t) strlen (ca_write.tag_text) ;
 
        file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
        if (sf_command (file, SFC_SET_CART_INFO, &ca_write, sizeof (ca_write)) == SF_FALSE)
@@ -1652,7 +1652,7 @@ cart_rdwr_test (const char *filename, int filetype)
        cinfo.level_reference = 42 ;
        snprintf (cinfo.url, sizeof (cinfo.url), "http://www.test.com/test_url") ;
        snprintf (cinfo.tag_text, sizeof (cinfo.tag_text), "tag text test!\r\n") ;
-       cinfo.tag_text_size = strlen (cinfo.tag_text) ;
+       cinfo.tag_text_size = (uint32_t) strlen (cinfo.tag_text) ;
 
        file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ;
        frames = sfinfo.frames ;
index c8f43c8..b7dae30 100644 (file)
@@ -37,6 +37,8 @@
 #define        SAMPLE_RATE             16000
 #define        DATA_LENGTH             (SAMPLE_RATE)
 
+static const char CMP_TEST_PREFIX[] = "cmp" ;
+
 static float data_out [DATA_LENGTH] ;
 
 static inline float
@@ -53,6 +55,8 @@ vorbis_test (void)
        float max_abs = 0.0 ;
        unsigned k ;
 
+       get_unique_test_name (&filename, CMP_TEST_PREFIX) ;
+
        print_test_name ("vorbis_test", filename) ;
 
        /* Generate float data. */
@@ -98,7 +102,7 @@ vorbis_test (void)
        sf_close (file) ;
 
        for (k = 0 ; k < ARRAY_LEN (float_data) ; k ++)
-               max_abs = max_float (max_abs, fabs (float_data [k])) ;
+               max_abs = max_float (max_abs, fabsf (float_data [k])) ;
 
        exit_if_true (max_abs > 1.023,
                "\n\nLine %d : max_abs %f should be < 1.023.\n\n", __LINE__, max_abs) ;
@@ -123,6 +127,8 @@ compression_size_test (int format, const char * filename)
        double quality ;
        int k ;
 
+       get_unique_test_name (&filename, CMP_TEST_PREFIX) ;
+
        snprintf (q3_fname, sizeof (q3_fname), "q3_%s", filename) ;
        snprintf (q6_fname, sizeof (q6_fname), "q6_%s", filename) ;
 
@@ -154,8 +160,8 @@ compression_size_test (int format, const char * filename)
        sf_close (q3_file) ;
        sf_close (q6_file) ;
 
-       q3_size = file_length (q3_fname) ;
-       q6_size = file_length (q6_fname) ;
+       q3_size = (int) file_length (q3_fname) ;
+       q6_size = (int) file_length (q6_fname) ;
 
        exit_if_true (q3_size >= q6_size,
                "\n\nLine %d : q3 size (%d) >= q6 size (%d)\n\n", __LINE__, q3_size, q6_size) ;
@@ -178,33 +184,50 @@ main (int argc, char *argv [])
                        "        vorbis - test Ogg/Vorbis\n"
                        "        flac   - test FLAC\n"
                        "        opus   - test Opus\n"
+                       "        mpeg   - test mpeg\n"
                        "        all    - perform all tests\n",
                        argv [0]) ;
                exit (0) ;
                } ;
 
-       if (! HAVE_EXTERNAL_XIPH_LIBS)
-       {       puts ("    No Ogg/Vorbis tests because Ogg/Vorbis support was not compiled in.") ;
-               return 0 ;
-       } ;
-
        if (strcmp (argv [1], "all") == 0)
                all_tests = 1 ;
 
        if (all_tests || strcmp (argv [1], "vorbis") == 0)
-       {       vorbis_test () ;
-               compression_size_test (SF_FORMAT_OGG | SF_FORMAT_VORBIS, "vorbis.oga") ;
-               tests ++ ;
+       {       if (HAVE_EXTERNAL_XIPH_LIBS)
+               {       vorbis_test () ;
+                       compression_size_test (SF_FORMAT_OGG | SF_FORMAT_VORBIS, "vorbis.oga") ;
+                       tests ++ ;
+                       }
+               else
+                       puts ("    No Ogg Vorbis tests because support was not compiled in.") ;
                } ;
 
        if (all_tests || strcmp (argv [1], "flac") == 0)
-       {       compression_size_test (SF_FORMAT_FLAC | SF_FORMAT_PCM_16, "pcm16.flac") ;
-               tests ++ ;
+       {       if (HAVE_EXTERNAL_XIPH_LIBS)
+               {       compression_size_test (SF_FORMAT_FLAC | SF_FORMAT_PCM_16, "pcm16.flac") ;
+                       tests ++ ;
+                       }
+               else
+                       puts ("    No FLAC tests because support was not compiled in.") ;
                } ;
 
        if (all_tests || strcmp (argv [1], "opus") == 0)
-       {       compression_size_test (SF_FORMAT_OGG | SF_FORMAT_OPUS, "opus.opus") ;
-               tests ++ ;
+       {       if (HAVE_EXTERNAL_XIPH_LIBS)
+               {       compression_size_test (SF_FORMAT_OGG | SF_FORMAT_OPUS, "opus.opus") ;
+                       tests ++ ;
+                       }
+               else
+                       puts ("    No Opus tests because support was not compiled in.") ;
+               } ;
+
+       if (all_tests || strcmp (argv [1], "mpeg") == 0)
+       {       if (HAVE_MPEG)
+               {       compression_size_test (SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III, "mpeg.mp3") ;
+                       tests ++ ;
+                       }
+               else
+                       puts ("    No MPEG tests because support was not compiled in.") ;
                } ;
 
        return 0 ;
index b2cae06..0c92f87 100644 (file)
@@ -86,7 +86,7 @@ dwvw_test (const char *filename, int format, int bit_width)
 
        file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
 
-       if ((k = sf_read_int (file, read_buf, BUFFER_SIZE)) != BUFFER_SIZE)
+       if ((k = (int) sf_read_int (file, read_buf, BUFFER_SIZE)) != BUFFER_SIZE)
        {       printf ("Error (line %d) : Only read %d/%d.frames.\n", __LINE__, k, BUFFER_SIZE) ;
                exit (1) ;
                }
index 2e348e4..495d88b 100644 (file)
 #include "sf_unistd.h"
 #endif
 
-#if OS_IS_WIN32
-#include <windows.h>
-#endif
-
 #include <sndfile.h>
 
 #include "utils.h"
@@ -213,19 +209,10 @@ error_close_test (void)
 
        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) ;
-                       } ;
+               printf ("\nHowever, this is a known bug on windows platform so we'll ignore it.\n\n") ;
 #else
-               printf ("\n\nLine %d : sf_close should not have returned zero.\n", __LINE__) ;
                exit (1) ;
 #endif
                } ;
@@ -255,7 +242,7 @@ unrecognised_test (void)
        sndfile = sf_open (filename, SFM_READ, &sfinfo) ;
 
        exit_if_true (sndfile != NULL,
-               "\n\nLine %d : SNDFILE* pointer (%p) should ne NULL.\n", __LINE__, sndfile
+               "\n\nLine %d : SNDFILE* pointer (%p) should be NULL.\n", __LINE__, (void *) sndfile
                ) ;
 
        k = sf_error (sndfile) ;
index 7258fa2..9651391 100644 (file)
 
 #define        SAMPLE_RATE                     16000
 
+static const char FPT_TEST_PREFIX[] = "fpt" ;
+
 static void    float_scaled_test       (const char *filename, int allow_exit, int replace_float, int filetype, double target_snr) ;
 static void    double_scaled_test      (const char *filename, int allow_exit, int replace_float, int filetype, double target_snr) ;
 
 [+ FOR float_type +][+ FOR int_type +][+ FOR endian_type
-+]static void [+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test (const char * filename) ;
++]static void [+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test (const char * filename, int replace_float) ;
 [+ ENDFOR endian_type +][+ ENDFOR int_type +][+ ENDFOR float_type
 +]
 
@@ -125,6 +127,10 @@ main (int argc, char *argv [])
        float_scaled_test       ("opus.opus", allow_exit, SF_FALSE, SF_FORMAT_OGG | SF_FORMAT_OPUS, -32.0) ;
 #endif
 
+#if HAVE_MPEG
+       float_scaled_test       ("mpeg.mp3", allow_exit, SF_FALSE, SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III, -52.0) ;
+#endif
+
        float_scaled_test       ("replace_float.raw", allow_exit, SF_TRUE, SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_FLOAT, -163.0) ;
 
        /*==============================================================================
@@ -183,14 +189,18 @@ main (int argc, char *argv [])
        double_scaled_test      ("opus.opus", allow_exit, SF_FALSE, SF_FORMAT_OGG | SF_FORMAT_OPUS, -32.0) ;
 #endif
 
+#if HAVE_MPEG
+       double_scaled_test      ("mpeg.mp3", allow_exit, SF_FALSE, SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III, -52.0) ;
+#endif
+
        double_scaled_test      ("replace_double.raw", allow_exit, SF_TRUE, SF_FORMAT_RAW | SF_FORMAT_DOUBLE, -201.0) ;
 
        putchar ('\n') ;
        /* Float int tests. */
-[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type
-+]     [+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test ("[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +].au") ;
-[+ ENDFOR endian_type +][+ ENDFOR int_type +][+ ENDFOR float_type
-+]
+[+ FOR float_type +][+ FOR int_type +][+ FOR endian_type +]
+[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test ("[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +].au", SF_FALSE) ;
+[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test ("[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_replace.au", SF_TRUE) ;
+[+ ENDFOR endian_type +][+ ENDFOR int_type +][+ ENDFOR float_type +]
 
        return 0 ;
 } /* main */
@@ -206,6 +216,7 @@ float_scaled_test (const char *filename, int allow_exit, int replace_float, int
        double          snr ;
        int                     byterate ;
 
+       get_unique_test_name (&filename, FPT_TEST_PREFIX) ;
        print_test_name ("float_scaled_test", filename) ;
 
        gen_windowed_sine_float (float_data, DFT_DATA_LENGTH, 0.9999) ;
@@ -259,6 +270,7 @@ double_scaled_test (const char *filename, int allow_exit, int replace_float, int
        double          snr ;
        int                     byterate ;
 
+       get_unique_test_name (&filename, FPT_TEST_PREFIX) ;
        print_test_name ("double_scaled_test", filename) ;
 
        gen_windowed_sine_double (double_data, DFT_DATA_LENGTH, 0.9999) ;
@@ -311,12 +323,13 @@ double_scaled_test (const char *filename, int allow_exit, int replace_float, int
 [+ FOR float_type +][+ FOR int_type +][+ FOR endian_type
 +]
 static void
-[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test (const char * filename)
+[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test (const char * filename, int replace_float)
 {      SNDFILE         *file ;
        SF_INFO         sfinfo ;
        int                     max ;
        unsigned        k ;
 
+       get_unique_test_name (&filename, FPT_TEST_PREFIX) ;
        print_test_name ("[+ (get "float_name") +]_[+ (get "int_name") +]_[+ (get "end_name") +]_test", filename) ;
 
        gen_windowed_sine_[+ (get "float_name") +] ([+ (get "float_name") +]_data, ARRAY_LEN ([+ (get "float_name") +]_data), 0.9999) ;
@@ -328,10 +341,12 @@ static void
        sfinfo.format           = [+ (get "end_type") +] | SF_FORMAT_AU | [+ (get "minor_type") +] ;
 
        file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
+       sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
        test_write_[+ (get "float_name") +]_or_die (file, 0, [+ (get "float_name") +]_data, ARRAY_LEN ([+ (get "float_name") +]_data), __LINE__) ;
        sf_close (file) ;
 
        file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
+       sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ;
 
        if (sfinfo.frames != ARRAY_LEN ([+ (get "float_name") +]_data))
        {       printf ("\n\nLine %d: Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, DFT_DATA_LENGTH) ;
index 7ab71c9..2e76679 100644 (file)
@@ -121,6 +121,16 @@ format_combo_test (void)
                                __LINE__
                                ) ;
 
+                       /* Only have decode, not encode support for MPEG Layer I and II */
+                       if (subtype_fmt_info.format == SF_FORMAT_MPEG_LAYER_I ||
+                                       subtype_fmt_info.format == SF_FORMAT_MPEG_LAYER_II)
+                               continue ;
+
+                       /* MPEG Layer III in WAV is decode only currently */
+                       if (subtype_fmt_info.format == SF_FORMAT_MPEG_LAYER_III &&
+                                       major_fmt_info.format == SF_FORMAT_WAV)
+                               continue ;
+
                        snprintf (filename, sizeof (filename), "format-check.%s", major_fmt_info.extension) ;
 
                        sndfile = sf_open (filename, SFM_WRITE, &info) ;
index 87efbb4..b49b271 100644 (file)
@@ -39,10 +39,10 @@ generate_file (const char * filename, int format, int len)
 
        output = calloc (len, sizeof (float)) ;
 
-       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) ;
-       crappy_snare (output, len, 3 * len / 4, 0.85, maxabs) ;
+       maxabs = crappy_snare (output, len, 0, 0.95f, maxabs) ;
+       maxabs = crappy_snare (output, len, len / 4, 0.85f, maxabs) ;
+       maxabs = crappy_snare (output, len, 2 * len / 4, 0.85f, maxabs) ;
+       crappy_snare (output, len, 3 * len / 4, 0.85f, maxabs) ;
 
        write_mono_file (filename, format, 44100, output, len) ;
 
@@ -51,24 +51,24 @@ generate_file (const char * filename, int format, int len)
 
 static inline float
 rand_float (void)
-{      return rand () / (0.5 * RAND_MAX) - 1.0 ;
+{      return rand () / (0.5f * (float) RAND_MAX) - 1.0f ;
 } /* rand_float */
 
 static float
 crappy_snare (float *output, int len, int offset, float gain, float maxabs)
 {      int k ;
-       float env = 0.0 ;
+       float env = 0.0f ;
 
        for (k = offset ; k < len && env < gain ; k++)
-       {       env += 0.03 ;
+       {       env += 0.03f ;
                output [k] += env * rand_float () ;
-               maxabs = SF_MAX (maxabs, fabs (output [k])) ;
+               maxabs = SF_MAX (maxabs, fabsf (output [k])) ;
                } ;
 
        for ( ; k < len && env > 1e-8 ; k++)
-       {       env *= 0.995 ;
+       {       env *= 0.995f ;
                output [k] += env * rand_float () ;
-               maxabs = SF_MAX (maxabs, fabs (output [k])) ;
+               maxabs = SF_MAX (maxabs, fabsf (output [k])) ;
                } ;
 
        return maxabs ;
index f4dd5b5..b02fbef 100644 (file)
@@ -106,7 +106,7 @@ main (int argc, char *argv [])
                update_seek_int_test ("header_int.aiff", SF_FORMAT_AIFF) ;
                update_seek_float_test ("header_float.aiff", SF_FORMAT_AIFF) ;
                update_seek_double_test ("header_double.aiff", SF_FORMAT_AIFF) ;
-               header_shrink_test ("header_shrink.wav", SF_FORMAT_AIFF) ;
+               header_shrink_test ("header_shrink.aiff", SF_FORMAT_AIFF) ;
                extra_header_test ("extra.aiff", SF_FORMAT_AIFF) ;
                test_count++ ;
                } ;
index 059fa68..86aa6db 100644 (file)
@@ -44,11 +44,11 @@ main (void)
 {
        old_test () ;
 
-       headerless_test ("raw.vox", SF_FORMAT_VOX_ADPCM, SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM) ;
-       headerless_test ("raw.gsm", SF_FORMAT_GSM610, SF_FORMAT_RAW | SF_FORMAT_GSM610) ;
+       headerless_test ("headerless.vox", SF_FORMAT_VOX_ADPCM, SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM) ;
+       headerless_test ("headerless.gsm", SF_FORMAT_GSM610, SF_FORMAT_RAW | SF_FORMAT_GSM610) ;
 
-       headerless_test ("raw.snd", SF_FORMAT_ULAW, SF_FORMAT_RAW | SF_FORMAT_ULAW) ;
-       headerless_test ("raw.au" , SF_FORMAT_ULAW, SF_FORMAT_RAW | SF_FORMAT_ULAW) ;
+       headerless_test ("headerless.snd", SF_FORMAT_ULAW, SF_FORMAT_RAW | SF_FORMAT_ULAW) ;
+       headerless_test ("headerless.au" , SF_FORMAT_ULAW, SF_FORMAT_RAW | SF_FORMAT_ULAW) ;
 
        return 0 ;
 } /* main */
@@ -74,7 +74,7 @@ headerless_test (const char * filename, int format, int expected)
 
        file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
 
-       if ((k = sf_write_short (file, buffer, BUFFER_SIZE)) != BUFFER_SIZE)
+       if ((k = (int) sf_write_short (file, buffer, BUFFER_SIZE)) != BUFFER_SIZE)
        {       printf ("Line %d: sf_write_short failed with short write (%d => %d).\n", __LINE__, BUFFER_SIZE, k) ;
                fflush (stdout) ;
                puts (sf_strerror (file)) ;
@@ -135,7 +135,7 @@ old_test (void)
 
        file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
 
-       if ((k = sf_write_short (file, buffer, BUFFER_SIZE)) != BUFFER_SIZE)
+       if ((k = (int) sf_write_short (file, buffer, BUFFER_SIZE)) != BUFFER_SIZE)
        {       printf ("Line %d: sf_write_short failed with short write (%d => %d).\n", __LINE__, BUFFER_SIZE, k) ;
                fflush (stdout) ;
                puts (sf_strerror (file)) ;
@@ -168,7 +168,7 @@ old_test (void)
 
        check_log_buffer_or_die (file, __LINE__) ;
 
-       if ((k = sf_read_short (file, buffer, BUFFER_SIZE)) != BUFFER_SIZE)
+       if ((k = (int) sf_read_short (file, buffer, BUFFER_SIZE)) != BUFFER_SIZE)
        {       printf ("Line %d: short read (%d).\n", __LINE__, k) ;
                exit (1) ;
                } ;
index b265301..932c72e 100644 (file)
@@ -34,7 +34,6 @@
 
 #if OS_IS_WIN32
 #include <windows.h>
-#define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
 #endif
 
 #include "sndfile.h"
index 4862468..0629cae 100644 (file)
@@ -66,7 +66,7 @@ main (int argc, char *argv [])
        {       int value = k / 32 ;
                int_data [k] = (value & 1 ? -1 : 1) * value ;
                short_data [k] = int_data [k] ;
-               float_data [k] = int_data [k] / 32000.0 ;
+               float_data [k] = int_data [k] / 32000.0f ;
                double_data [k] = int_data [k] / 32000.0 ;
                }
 
index cca274c..9280321 100644 (file)
@@ -44,6 +44,8 @@
 
 #define                LCT_MAX(x, y)   ((x) > (y) ? (x) : (y))
 
+static const char LCT_TEST_PREFIX[] = "lct" ;
+
 static void    lcomp_test_short        (const char *filename, int filetype, int chan, double margin) ;
 static void    lcomp_test_int          (const char *filename, int filetype, int chan, double margin) ;
 static void    lcomp_test_float        (const char *filename, int filetype, int chan, double margin) ;
@@ -651,6 +653,7 @@ lcomp_test_short (const char *filename, int filetype, int channels, double margi
        sf_count_t              datalen ;
        short                   *orig, *data ;
 
+       get_unique_test_name (&filename, LCT_TEST_PREFIX) ;
        print_test_name ("lcomp_test_short", filename) ;
 
        datalen = BUFFER_SIZE / channels ;
@@ -658,7 +661,7 @@ lcomp_test_short (const char *filename, int filetype, int channels, double margi
        data = data_buffer.s ;
        orig = orig_buffer.s ;
 
-       gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
+       gen_signal_double (orig_buffer.d, 32000.0, channels, (int) datalen) ;
        for (k = 0 ; k < channels * datalen ; k++)
                orig [k] = (short) (orig_buffer.d [k]) ;
 
@@ -709,7 +712,7 @@ lcomp_test_short (const char *filename, int filetype, int channels, double margi
        for (k = 0 ; k < datalen ; k++)
        {       if (error_function (data [k], orig [k], margin))
                {       printf ("\n\nLine %d: Incorrect sample A (#%d : %d should be %d).\n", __LINE__, k, data [k], orig [k]) ;
-                       oct_save_short (orig, data, datalen) ;
+                       oct_save_short (orig, data, (int) datalen) ;
                        exit (1) ;
                        } ;
                half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ;
@@ -720,7 +723,7 @@ lcomp_test_short (const char *filename, int filetype, int channels, double margi
                exit (1) ;
                } ;
 
-       if ((k = sf_readf_short (file, data, datalen)) != sfinfo.frames - datalen)
+       if ((k = (int) sf_readf_short (file, data, datalen)) != sfinfo.frames - datalen)
        {       printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__,
                        channels * sfinfo.frames - datalen, k) ;
                exit (1) ;
@@ -744,7 +747,7 @@ lcomp_test_short (const char *filename, int filetype, int channels, double margi
 
        /* Now test sf_seek function. */
 
-       if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
+       if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0)
        {       printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
                exit (1) ;
                } ;
@@ -765,7 +768,7 @@ lcomp_test_short (const char *filename, int filetype, int channels, double margi
        seekpos = BUFFER_SIZE / 10 ;
 
        /* Check seek from start of file. */
-       if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
+       if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos)
        {       printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
                exit (1) ;
                } ;
@@ -777,23 +780,23 @@ lcomp_test_short (const char *filename, int filetype, int channels, double margi
                exit (1) ;
                } ;
 
-       if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
+       if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
        {       printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
                exit (1) ;
                } ;
 
-       seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
-       k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
+       seekpos = (int) sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
+       k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
        test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
        if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
        {       printf ("\n\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_short failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ;
-               oct_save_short (orig, data, datalen) ;
+               oct_save_short (orig, data, (int) datalen) ;
                exit (1) ;
                } ;
 
-       seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
+       seekpos = (int) sf_seek (file, 0, SEEK_CUR) - 20 ;
        /* Check seek backward from current position. */
-       k = sf_seek (file, -20, SEEK_CUR) ;
+       k = (int) sf_seek (file, -20, SEEK_CUR) ;
        test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
        if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
        {       printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_short failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ;
@@ -803,13 +806,13 @@ lcomp_test_short (const char *filename, int filetype, int channels, double margi
        /* Check that read past end of file returns number of items. */
        sf_seek (file, sfinfo.frames, SEEK_SET) ;
 
-       if ((k = sf_readf_short (file, data, datalen)) != 0)
+       if ((k = (int) sf_readf_short (file, data, datalen)) != 0)
        {       printf ("\n\nLine %d: Return value from sf_readf_short past end of file incorrect (%d).\n", __LINE__, k) ;
                exit (1) ;
                } ;
 
        /* Check seek backward from end. */
-       if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
+       if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
        {       printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
                exit (1) ;
                } ;
@@ -838,6 +841,7 @@ lcomp_test_int (const char *filename, int filetype, int channels, double margin)
        double                  scale, max_val ;
        int                             *orig, *data ;
 
+       get_unique_test_name (&filename, LCT_TEST_PREFIX) ;
        print_test_name ("lcomp_test_int", filename) ;
 
        datalen = BUFFER_SIZE / channels ;
@@ -854,7 +858,7 @@ lcomp_test_int (const char *filename, int filetype, int channels, double margin)
        data = data_buffer.i ;
        orig = orig_buffer.i ;
 
-       gen_signal_double (orig_buffer.d, max_val, channels, datalen) ;
+       gen_signal_double (orig_buffer.d, max_val, channels, (int) datalen) ;
 
        for (k = 0 ; k < channels * datalen ; k++)
                orig [k] = lrint (orig_buffer.d [k]) ;
@@ -906,7 +910,7 @@ lcomp_test_int (const char *filename, int filetype, int channels, double margin)
        for (k = 0 ; k < datalen ; k++)
        {       if (error_function (data [k] / scale, orig [k] / scale, margin))
                {       printf ("\nLine %d: Incorrect sample (#%d : %f should be %f).\n", __LINE__, k, data [k] / scale, orig [k] / scale) ;
-                       oct_save_int (orig, data, datalen) ;
+                       oct_save_int (orig, data, (int) datalen) ;
                        exit (1) ;
                        } ;
                half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ;
@@ -917,7 +921,7 @@ lcomp_test_int (const char *filename, int filetype, int channels, double margin)
                exit (1) ;
                } ;
 
-       if ((k = sf_readf_int (file, data, datalen)) != sfinfo.frames - datalen)
+       if ((k = (int) sf_readf_int (file, data, datalen)) != sfinfo.frames - datalen)
        {       printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__,
                        channels * sfinfo.frames - datalen, k) ;
                exit (1) ;
@@ -942,7 +946,7 @@ lcomp_test_int (const char *filename, int filetype, int channels, double margin)
 
        /* Now test sf_seek function. */
 
-       if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
+       if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0)
        {       printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
                exit (1) ;
                } ;
@@ -963,7 +967,7 @@ lcomp_test_int (const char *filename, int filetype, int channels, double margin)
        seekpos = BUFFER_SIZE / 10 ;
 
        /* Check seek from start of file. */
-       if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
+       if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos)
        {       printf ("Seek to start of file + %" PRId64 " failed (%d).\n", seekpos, k) ;
                exit (1) ;
                } ;
@@ -975,13 +979,13 @@ lcomp_test_int (const char *filename, int filetype, int channels, double margin)
                exit (1) ;
                } ;
 
-       if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
+       if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
        {       printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %" PRId64 ")\n", __LINE__, k, seekpos + 1) ;
                exit (1) ;
                } ;
 
        seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
-       k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
+       k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
        test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
        if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
        {       printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %" PRId64 ").\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ;
@@ -990,7 +994,7 @@ lcomp_test_int (const char *filename, int filetype, int channels, double margin)
 
        seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
        /* Check seek backward from current position. */
-       k = sf_seek (file, -20, SEEK_CUR) ;
+       k = (int) sf_seek (file, -20, SEEK_CUR) ;
        test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
        if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
        {       printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %" PRId64 ").\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ;
@@ -1000,13 +1004,13 @@ lcomp_test_int (const char *filename, int filetype, int channels, double margin)
        /* Check that read past end of file returns number of items. */
        sf_seek (file, sfinfo.frames, SEEK_SET) ;
 
-       if ((k = sf_readf_int (file, data, datalen)) != 0)
+       if ((k = (int) sf_readf_int (file, data, datalen)) != 0)
        {       printf ("\n\nLine %d: Return value from sf_readf_int past end of file incorrect (%d).\n", __LINE__, k) ;
                exit (1) ;
                } ;
 
        /* Check seek backward from end. */
-       if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
+       if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
        {       printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
                exit (1) ;
                } ;
@@ -1035,6 +1039,7 @@ lcomp_test_float (const char *filename, int filetype, int channels, double margi
        float                   *orig, *data ;
        double                  half_max_abs ;
 
+       get_unique_test_name (&filename, LCT_TEST_PREFIX) ;
        print_test_name ("lcomp_test_float", filename) ;
 
        datalen = BUFFER_SIZE / channels ;
@@ -1042,9 +1047,9 @@ lcomp_test_float (const char *filename, int filetype, int channels, double margi
        data = data_buffer.f ;
        orig = orig_buffer.f ;
 
-       gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
+       gen_signal_double (orig_buffer.d, 32000.0, channels, (int) datalen) ;
        for (k = 0 ; k < channels * datalen ; k++)
-               orig [k] = orig_buffer.d [k] ;
+               orig [k] = (float) orig_buffer.d [k] ;
 
        sfinfo.samplerate       = SAMPLE_RATE ;
        sfinfo.frames           = 123456789 ;   /* Ridiculous value. */
@@ -1100,7 +1105,7 @@ lcomp_test_float (const char *filename, int filetype, int channels, double margi
        for (k = 0 ; k < datalen ; k++)
        {       if (error_function (data [k], orig [k], margin))
                {       printf ("\nLine %d: Incorrect sample A (#%d : %f should be %f).\n", __LINE__, k, data [k], orig [k]) ;
-                       oct_save_float (orig, data, datalen) ;
+                       oct_save_float (orig, data, (int) datalen) ;
                        exit (1) ;
                        } ;
                half_max_abs = LCT_MAX (half_max_abs, fabs (0.5 * data [k])) ;
@@ -1111,7 +1116,7 @@ lcomp_test_float (const char *filename, int filetype, int channels, double margi
                exit (1) ;
                } ;
 
-       if ((k = sf_readf_float (file, data, datalen)) != sfinfo.frames - datalen)
+       if ((k = (int) sf_readf_float (file, data, datalen)) != sfinfo.frames - datalen)
        {       printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__,
                        channels * sfinfo.frames - datalen, k) ;
                exit (1) ;
@@ -1136,7 +1141,7 @@ lcomp_test_float (const char *filename, int filetype, int channels, double margi
 
        /* Now test sf_seek function. */
 
-       if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
+       if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0)
        {       printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
                exit (1) ;
                } ;
@@ -1157,7 +1162,7 @@ lcomp_test_float (const char *filename, int filetype, int channels, double margi
        seekpos = BUFFER_SIZE / 10 ;
 
        /* Check seek from start of file. */
-       if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
+       if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos)
        {       printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
                exit (1) ;
                } ;
@@ -1169,22 +1174,22 @@ lcomp_test_float (const char *filename, int filetype, int channels, double margi
                exit (1) ;
                } ;
 
-       if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
+       if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
        {       printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
                exit (1) ;
                } ;
 
-       seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
-       k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
+       seekpos = (int) sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
+       k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
        test_readf_float_or_die (file, 0, data, 1, __LINE__) ;
        if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
        {       printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_float failed (%f, %f) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ;
                exit (1) ;
                } ;
 
-       seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
+       seekpos = (int) sf_seek (file, 0, SEEK_CUR) - 20 ;
        /* Check seek backward from current position. */
-       k = sf_seek (file, -20, SEEK_CUR) ;
+       k = (int) sf_seek (file, -20, SEEK_CUR) ;
        test_readf_float_or_die (file, 0, data, 1, __LINE__) ;
        if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
        {       printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_float failed (%f, %f) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ;
@@ -1194,13 +1199,13 @@ lcomp_test_float (const char *filename, int filetype, int channels, double margi
        /* Check that read past end of file returns number of items. */
        sf_seek (file, sfinfo.frames, SEEK_SET) ;
 
-       if ((k = sf_readf_float (file, data, datalen)) != 0)
+       if ((k = (int) sf_readf_float (file, data, datalen)) != 0)
        {       printf ("\n\nLine %d: Return value from sf_readf_float past end of file incorrect (%d).\n", __LINE__, k) ;
                exit (1) ;
                } ;
 
        /* Check seek backward from end. */
-       if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
+       if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
        {       printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
                exit (1) ;
                } ;
@@ -1229,6 +1234,7 @@ lcomp_test_double (const char *filename, int filetype, int channels, double marg
        double                  *orig, *data ;
        double                  half_max_abs ;
 
+       get_unique_test_name (&filename, LCT_TEST_PREFIX) ;
        print_test_name ("lcomp_test_double", filename) ;
 
        datalen = BUFFER_SIZE / channels ;
@@ -1236,7 +1242,7 @@ lcomp_test_double (const char *filename, int filetype, int channels, double marg
        data = data_buffer.d ;
        orig = orig_buffer.d ;
 
-       gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
+       gen_signal_double (orig_buffer.d, 32000.0, channels, (int) datalen) ;
        for (k = 0 ; k < channels * datalen ; k++)
                orig [k] = orig_buffer.d [k] ;
 
@@ -1294,7 +1300,7 @@ lcomp_test_double (const char *filename, int filetype, int channels, double marg
        for (k = 0 ; k < datalen ; k++)
        {       if (error_function (data [k], orig [k], margin))
                {       printf ("\nLine %d: Incorrect sample A (#%d : %f should be %f).\n", __LINE__, k, data [k], orig [k]) ;
-                       oct_save_double (orig, data, datalen) ;
+                       oct_save_double (orig, data, (int) datalen) ;
                        exit (1) ;
                        } ;
                half_max_abs = LCT_MAX (half_max_abs, ABS (0.5 * data [k])) ;
@@ -1305,7 +1311,7 @@ lcomp_test_double (const char *filename, int filetype, int channels, double marg
                exit (1) ;
                } ;
 
-       if ((k = sf_readf_double (file, data, datalen)) != sfinfo.frames - datalen)
+       if ((k = (int) sf_readf_double (file, data, datalen)) != sfinfo.frames - datalen)
        {       printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__,
                        channels * sfinfo.frames - datalen, k) ;
                exit (1) ;
@@ -1330,7 +1336,7 @@ lcomp_test_double (const char *filename, int filetype, int channels, double marg
 
        /* Now test sf_seek function. */
 
-       if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
+       if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0)
        {       printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
                exit (1) ;
                } ;
@@ -1351,7 +1357,7 @@ lcomp_test_double (const char *filename, int filetype, int channels, double marg
        seekpos = BUFFER_SIZE / 10 ;
 
        /* Check seek from start of file. */
-       if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
+       if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos)
        {       printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
                exit (1) ;
                } ;
@@ -1363,22 +1369,22 @@ lcomp_test_double (const char *filename, int filetype, int channels, double marg
                exit (1) ;
                } ;
 
-       if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
+       if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
        {       printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
                exit (1) ;
                } ;
 
-       seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
-       k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
+       seekpos = (int) sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
+       k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
        test_readf_double_or_die (file, 0, data, 1, __LINE__) ;
        if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
        {       printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_double failed (%f, %f) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ;
                exit (1) ;
                } ;
 
-       seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
+       seekpos = (int) sf_seek (file, 0, SEEK_CUR) - 20 ;
        /* Check seek backward from current position. */
-       k = sf_seek (file, -20, SEEK_CUR) ;
+       k = (int) sf_seek (file, -20, SEEK_CUR) ;
        test_readf_double_or_die (file, 0, data, 1, __LINE__) ;
        if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
        {       printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_double failed (%f, %f) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ;
@@ -1388,13 +1394,13 @@ lcomp_test_double (const char *filename, int filetype, int channels, double marg
        /* Check that read past end of file returns number of items. */
        sf_seek (file, sfinfo.frames, SEEK_SET) ;
 
-       if ((k = sf_readf_double (file, data, datalen)) != 0)
+       if ((k = (int) sf_readf_double (file, data, datalen)) != 0)
        {       printf ("\n\nLine %d: Return value from sf_readf_double past end of file incorrect (%d).\n", __LINE__, k) ;
                exit (1) ;
                } ;
 
        /* Check seek backward from end. */
-       if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
+       if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
        {       printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
                exit (1) ;
                } ;
@@ -1424,6 +1430,8 @@ sdlcomp_test_short        (const char *filename, int filetype, int channels, double mar
        short                   *orig, *data, *smooth ;
 
 channels = 1 ;
+
+       get_unique_test_name (&filename, LCT_TEST_PREFIX) ;
        print_test_name ("sdlcomp_test_short", filename) ;
 
        datalen = BUFFER_SIZE ;
@@ -1432,9 +1440,9 @@ channels = 1 ;
        data = data_buffer.s ;
        smooth = smooth_buffer.s ;
 
-       gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
+       gen_signal_double (orig_buffer.d, 32000.0, channels, (int) datalen) ;
        for (k = 0 ; k < datalen ; k++)
-               orig [k] = lrint (orig_buffer.d [k]) ;
+               orig [k] = (short) lrint (orig_buffer.d [k]) ;
 
        sfinfo.samplerate       = SAMPLE_RATE ;
        sfinfo.frames           = 123456789 ;   /* Ridiculous value. */
@@ -1470,6 +1478,7 @@ channels = 1 ;
 
        if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file))
        {       sf_close (file) ;
+               unlink (filename) ;
                return ;
                } ;
 
@@ -1513,17 +1522,17 @@ channels = 1 ;
        test_readf_short_or_die (file, 0, data, datalen, __LINE__) ;
 
        memcpy (smooth, orig, datalen * sizeof (short)) ;
-       smoothed_diff_short (data, datalen) ;
-       smoothed_diff_short (smooth, datalen) ;
+       smoothed_diff_short (data, (unsigned int) datalen) ;
+       smoothed_diff_short (smooth, (unsigned int) datalen) ;
 
-       half_max_abs = 0.0 ;
+       half_max_abs = 0 ;
        for (k = 0 ; k < datalen ; k++)
        {       if (error_function (1.0 * data [k], 1.0 * smooth [k], margin))
                {       printf ("\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, data [k], smooth [k]) ;
-                       oct_save_short (orig, smooth, datalen) ;
+                       oct_save_short (orig, smooth, (int) datalen) ;
                        exit (1) ;
                        } ;
-               half_max_abs = LCT_MAX (half_max_abs, ABS (0.5 * data [k])) ;
+               half_max_abs = (int) (LCT_MAX (half_max_abs, ABS (0.5 * data [k]))) ;
                } ;
 
        if (half_max_abs < 1)
@@ -1531,7 +1540,7 @@ channels = 1 ;
                exit (1) ;
                } ;
 
-       if ((k = sf_read_short (file, data, datalen)) != sfinfo.frames - datalen)
+       if ((k = (int) sf_read_short (file, data, datalen)) != sfinfo.frames - datalen)
        {       printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ;
                exit (1) ;
                } ;
@@ -1546,7 +1555,7 @@ channels = 1 ;
 
        /* Now test sf_seek function. */
        if (sfinfo.seekable)
-       {       if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
+       {       if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0)
                {       printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
                        exit (1) ;
                        } ;
@@ -1554,9 +1563,9 @@ channels = 1 ;
                for (m = 0 ; m < 3 ; m++)
                {       test_readf_short_or_die (file, m, data, datalen / 7, __LINE__) ;
 
-                       smoothed_diff_short (data, datalen / 7) ;
+                       smoothed_diff_short (data, (unsigned int) (datalen / 7)) ;
                        memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (short)) ;
-                       smoothed_diff_short (smooth, datalen / 7) ;
+                       smoothed_diff_short (smooth, (unsigned int) (datalen / 7)) ;
 
                        for (k = 0 ; k < datalen / 7 ; k++)
                                if (error_function (1.0 * data [k], 1.0 * smooth [k], margin))
@@ -1571,7 +1580,7 @@ channels = 1 ;
                seekpos = BUFFER_SIZE / 10 ;
 
                /* Check seek from start of file. */
-               if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
+               if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos)
                {       printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
                        exit (1) ;
                        } ;
@@ -1582,22 +1591,22 @@ channels = 1 ;
                        exit (1) ;
                        } ;
 
-               if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
+               if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
                {       printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
                        exit (1) ;
                        } ;
 
-               seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
-               k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
+               seekpos = (int) sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
+               k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
                test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
                if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
                {       printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_read_short failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ;
                        exit (1) ;
                        } ;
 
-               seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
+               seekpos = (int) sf_seek (file, 0, SEEK_CUR) - 20 ;
                /* Check seek backward from current position. */
-               k = sf_seek (file, -20, SEEK_CUR) ;
+               k = (int) sf_seek (file, -20, SEEK_CUR) ;
                test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
                if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
                {       printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_read_short failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ;
@@ -1607,14 +1616,14 @@ channels = 1 ;
                /* Check that read past end of file returns number of items. */
                sf_seek (file, sfinfo.frames, SEEK_SET) ;
 
-               if ((k = sf_read_short (file, data, datalen)) != 0)
+               if ((k = (int) sf_read_short (file, data, datalen)) != 0)
                {       printf ("\n\nLine %d: Return value from sf_read_short past end of file incorrect (%d).\n", __LINE__, k) ;
                        exit (1) ;
                        } ;
 
                /* Check seek backward from end. */
 
-               if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
+               if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
                {       printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
                        exit (1) ;
                        } ;
@@ -1643,6 +1652,7 @@ sdlcomp_test_int  (const char *filename, int filetype, int channels, double margi
 
 channels = 1 ;
 
+       get_unique_test_name (&filename, LCT_TEST_PREFIX) ;
        print_test_name ("sdlcomp_test_int", filename) ;
 
        datalen = BUFFER_SIZE ;
@@ -1652,7 +1662,7 @@ channels = 1 ;
        data = data_buffer.i ;
        smooth = smooth_buffer.i ;
 
-       gen_signal_double (orig_buffer.d, 32000.0 * scale, channels, datalen) ;
+       gen_signal_double (orig_buffer.d, 32000.0 * scale, channels, (int) datalen) ;
        for (k = 0 ; k < datalen ; k++)
                orig [k] = lrint (orig_buffer.d [k]) ;
 
@@ -1690,6 +1700,7 @@ channels = 1 ;
 
        if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file))
        {       sf_close (file) ;
+               unlink (filename) ;
                return ;
                } ;
 
@@ -1729,14 +1740,14 @@ channels = 1 ;
        test_readf_int_or_die (file, 0, data, datalen, __LINE__) ;
 
        memcpy (smooth, orig, datalen * sizeof (int)) ;
-       smoothed_diff_int (data, datalen) ;
-       smoothed_diff_int (smooth, datalen) ;
+       smoothed_diff_int (data, (unsigned int) datalen) ;
+       smoothed_diff_int (smooth, (unsigned int) datalen) ;
 
        half_max_abs = abs (data [0] >> 16) ;
        for (k = 1 ; k < datalen ; k++)
        {       if (error_function (data [k] / scale, smooth [k] / scale, margin))
                {       printf ("\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, data [k], smooth [k]) ;
-                       oct_save_int (orig, smooth, datalen) ;
+                       oct_save_int (orig, smooth, (int) datalen) ;
                        exit (1) ;
                        } ;
                half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ;
@@ -1747,7 +1758,7 @@ channels = 1 ;
                exit (1) ;
                } ;
 
-       if ((k = sf_readf_int (file, data, datalen)) != sfinfo.frames - datalen)
+       if ((k = (int) sf_readf_int (file, data, datalen)) != sfinfo.frames - datalen)
        {       printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ;
                exit (1) ;
                } ;
@@ -1768,7 +1779,7 @@ channels = 1 ;
 
        /* Now test sf_seek function. */
        if (sfinfo.seekable)
-       {       if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
+       {       if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0)
                {       printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
                        exit (1) ;
                        } ;
@@ -1776,9 +1787,9 @@ channels = 1 ;
                for (m = 0 ; m < 3 ; m++)
                {       test_readf_int_or_die (file, m, data, datalen / 7, __LINE__) ;
 
-                       smoothed_diff_int (data, datalen / 7) ;
+                       smoothed_diff_int (data, (unsigned int) (datalen / 7)) ;
                        memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (int)) ;
-                       smoothed_diff_int (smooth, datalen / 7) ;
+                       smoothed_diff_int (smooth, (unsigned int) (datalen / 7)) ;
 
                        for (k = 0 ; k < datalen / 7 ; k++)
                                if (error_function (data [k] / scale, smooth [k] / scale, margin))
@@ -1793,7 +1804,7 @@ channels = 1 ;
                seekpos = BUFFER_SIZE / 10 ;
 
                /* Check seek from start of file. */
-               if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
+               if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos)
                {       printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
                        exit (1) ;
                        } ;
@@ -1804,22 +1815,22 @@ channels = 1 ;
                        exit (1) ;
                        } ;
 
-               if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
+               if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
                {       printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
                        exit (1) ;
                        } ;
 
-               seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
-               k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
+               seekpos = (int) sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
+               k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
                test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
                if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
                {       printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ;
                        exit (1) ;
                        } ;
 
-               seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
+               seekpos = (int) sf_seek (file, 0, SEEK_CUR) - 20 ;
                /* Check seek backward from current position. */
-               k = sf_seek (file, -20, SEEK_CUR) ;
+               k = (int) sf_seek (file, -20, SEEK_CUR) ;
                test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
                if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
                {       printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ;
@@ -1829,14 +1840,14 @@ channels = 1 ;
                /* Check that read past end of file returns number of items. */
                sf_seek (file, sfinfo.frames, SEEK_SET) ;
 
-               if ((k = sf_readf_int (file, data, datalen)) != 0)
+               if ((k = (int) sf_readf_int (file, data, datalen)) != 0)
                {       printf ("\n\nLine %d: Return value from sf_readf_int past end of file incorrect (%d).\n", __LINE__, k) ;
                        exit (1) ;
                        } ;
 
                /* Check seek backward from end. */
 
-               if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
+               if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
                {       printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
                        exit (1) ;
                        } ;
@@ -1865,6 +1876,7 @@ sdlcomp_test_float        (const char *filename, int filetype, int channels, double mar
 
 channels = 1 ;
 
+       get_unique_test_name (&filename, LCT_TEST_PREFIX) ;
        print_test_name ("sdlcomp_test_float", filename) ;
 
        switch ((filetype & SF_FORMAT_SUBMASK))
@@ -1896,9 +1908,9 @@ channels = 1 ;
        data = data_buffer.f ;
        smooth = smooth_buffer.f ;
 
-       gen_signal_double (orig_buffer.d, 32000.0 / scale, channels, datalen) ;
+       gen_signal_double (orig_buffer.d, 32000.0 / scale, channels, (int) datalen) ;
        for (k = 0 ; k < datalen ; k++)
-               orig [k] = orig_buffer.d [k] ;
+               orig [k] = (float) orig_buffer.d [k] ;
 
        sfinfo.samplerate       = SAMPLE_RATE ;
        sfinfo.frames           = 123456789 ;   /* Ridiculous value. */
@@ -1935,6 +1947,7 @@ channels = 1 ;
 
        if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file))
        {       sf_close (file) ;
+               unlink (filename) ;
                return ;
                } ;
 
@@ -1979,14 +1992,14 @@ channels = 1 ;
        test_read_float_or_die (file, 0, data, datalen, __LINE__) ;
 
        memcpy (smooth, orig, datalen * sizeof (float)) ;
-       smoothed_diff_float (data, datalen) ;
-       smoothed_diff_float (smooth, datalen) ;
+       smoothed_diff_float (data, (unsigned int) datalen) ;
+       smoothed_diff_float (smooth, (unsigned int) datalen) ;
 
        half_max_abs = fabs (data [0]) ;
        for (k = 1 ; k < datalen ; k++)
        {       if (error_function (data [k] * scale, smooth [k] * scale, margin))
                {       printf ("\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, (int) (data [k] * scale), (int) (smooth [k] * scale)) ;
-                       oct_save_float (orig, smooth, datalen) ;
+                       oct_save_float (orig, smooth, (int) datalen) ;
                        exit (1) ;
                        } ;
                half_max_abs = LCT_MAX (half_max_abs, ABS (0.5 * data [k] * scale)) ;
@@ -1998,7 +2011,7 @@ channels = 1 ;
                exit (1) ;
                } ;
 
-       if ((k = sf_read_float (file, data, datalen)) != sfinfo.frames - datalen)
+       if ((k = (int) sf_read_float (file, data, datalen)) != sfinfo.frames - datalen)
        {       printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ;
                exit (1) ;
                } ;
@@ -2013,7 +2026,7 @@ channels = 1 ;
 
        /* Now test sf_seek function. */
        if (sfinfo.seekable)
-       {       if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
+       {       if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0)
                {       printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
                        exit (1) ;
                        } ;
@@ -2021,9 +2034,9 @@ channels = 1 ;
                for (m = 0 ; m < 3 ; m++)
                {       test_read_float_or_die (file, 0, data, datalen / 7, __LINE__) ;
 
-                       smoothed_diff_float (data, datalen / 7) ;
+                       smoothed_diff_float (data, (unsigned int) (datalen / 7)) ;
                        memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (float)) ;
-                       smoothed_diff_float (smooth, datalen / 7) ;
+                       smoothed_diff_float (smooth, (unsigned int) (datalen / 7)) ;
 
                        for (k = 0 ; k < datalen / 7 ; k++)
                                if (error_function (data [k] * scale, smooth [k] * scale, margin))
@@ -2038,7 +2051,7 @@ channels = 1 ;
                seekpos = BUFFER_SIZE / 10 ;
 
                /* Check seek from start of file. */
-               if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
+               if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos)
                {       printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
                        exit (1) ;
                        } ;
@@ -2049,22 +2062,22 @@ channels = 1 ;
                        exit (1) ;
                        } ;
 
-               if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
+               if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
                {       printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
                        exit (1) ;
                        } ;
 
-               seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
-               k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
+               seekpos = (int) sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
+               k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
                test_read_float_or_die (file, 0, data, channels, __LINE__) ;
                if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin) || k != seekpos)
                {       printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_read_float failed (%d, %d) (%d, %d).\n", __LINE__, (int) (data [0] * scale), (int) (orig [seekpos * channels] * scale), k, seekpos + 1) ;
                        exit (1) ;
                        } ;
 
-               seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
+               seekpos = (int) sf_seek (file, 0, SEEK_CUR) - 20 ;
                /* Check seek backward from current position. */
-               k = sf_seek (file, -20, SEEK_CUR) ;
+               k = (int) sf_seek (file, -20, SEEK_CUR) ;
                test_read_float_or_die (file, 0, data, channels, __LINE__) ;
                if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin) || k != seekpos)
                {       printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_read_float failed (%d, %d) (%d, %d).\n", __LINE__, (int) (data [0] * scale), (int) (orig [seekpos * channels] * scale), k, seekpos) ;
@@ -2074,14 +2087,14 @@ channels = 1 ;
                /* Check that read past end of file returns number of items. */
                sf_seek (file, sfinfo.frames, SEEK_SET) ;
 
-               if ((k = sf_read_float (file, data, datalen)) != 0)
+               if ((k = (int) sf_read_float (file, data, datalen)) != 0)
                {       printf ("\n\nLine %d: Return value from sf_read_float past end of file incorrect (%d).\n", __LINE__, k) ;
                        exit (1) ;
                        } ;
 
                /* Check seek backward from end. */
 
-               if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
+               if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
                {       printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
                        exit (1) ;
                        } ;
@@ -2108,6 +2121,8 @@ sdlcomp_test_double       (const char *filename, int filetype, int channels, double ma
        double                  *orig, *data, *smooth, half_max_abs, scale ;
 
 channels = 1 ;
+
+       get_unique_test_name (&filename, LCT_TEST_PREFIX) ;
        print_test_name ("sdlcomp_test_double", filename) ;
 
        switch ((filetype & SF_FORMAT_SUBMASK))
@@ -2139,7 +2154,7 @@ channels = 1 ;
        data = data_buffer.d ;
        smooth = smooth_buffer.d ;
 
-       gen_signal_double (orig_buffer.d, 32000.0 / scale, channels, datalen) ;
+       gen_signal_double (orig_buffer.d, 32000.0 / scale, channels, (int) datalen) ;
 
        sfinfo.samplerate       = SAMPLE_RATE ;
        sfinfo.frames           = 123456789 ;   /* Ridiculous value. */
@@ -2175,6 +2190,7 @@ channels = 1 ;
 
        if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file))
        {       sf_close (file) ;
+               unlink (filename) ;
                return ;
                } ;
 
@@ -2221,14 +2237,14 @@ channels = 1 ;
        test_read_double_or_die (file, 0, data, datalen, __LINE__) ;
 
        memcpy (smooth, orig, datalen * sizeof (double)) ;
-       smoothed_diff_double (data, datalen) ;
-       smoothed_diff_double (smooth, datalen) ;
+       smoothed_diff_double (data, (unsigned int) datalen) ;
+       smoothed_diff_double (smooth, (unsigned int) datalen) ;
 
        half_max_abs = 0.0 ;
        for (k = 0 ; k < datalen ; k++)
        {       if (error_function (data [k] * scale, smooth [k] * scale, margin))
                {       printf ("\n\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, (int) (data [k] * scale), (int) (smooth [k] * scale)) ;
-                       oct_save_double (orig, smooth, datalen) ;
+                       oct_save_double (orig, smooth, (int) datalen) ;
                        exit (1) ;
                        } ;
                half_max_abs = LCT_MAX (half_max_abs, 0.5 * fabs (data [k] * scale)) ;
@@ -2239,7 +2255,7 @@ channels = 1 ;
                exit (1) ;
                } ;
 
-       if ((k = sf_read_double (file, data, datalen)) != sfinfo.frames - datalen)
+       if ((k = (int) sf_read_double (file, data, datalen)) != sfinfo.frames - datalen)
        {       printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ;
                exit (1) ;
                } ;
@@ -2254,7 +2270,7 @@ channels = 1 ;
 
        /* Now test sf_seek function. */
        if (sfinfo.seekable)
-       {       if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
+       {       if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0)
                {       printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
                        exit (1) ;
                        } ;
@@ -2262,9 +2278,9 @@ channels = 1 ;
                for (m = 0 ; m < 3 ; m++)
                {       test_read_double_or_die (file, m, data, datalen / 7, __LINE__) ;
 
-                       smoothed_diff_double (data, datalen / 7) ;
+                       smoothed_diff_double (data, (unsigned int) (datalen / 7)) ;
                        memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (double)) ;
-                       smoothed_diff_double (smooth, datalen / 7) ;
+                       smoothed_diff_double (smooth, (unsigned int) (datalen / 7)) ;
 
                        for (k = 0 ; k < datalen / 7 ; k++)
                                if (error_function (data [k] * scale, smooth [k] * scale, margin))
@@ -2279,7 +2295,7 @@ channels = 1 ;
                seekpos = BUFFER_SIZE / 10 ;
 
                /* Check seek from start of file. */
-               if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
+               if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos)
                {       printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
                        exit (1) ;
                        } ;
@@ -2290,22 +2306,22 @@ channels = 1 ;
                        exit (1) ;
                        } ;
 
-               if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
+               if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
                {       printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
                        exit (1) ;
                        } ;
 
-               seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
-               k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
+               seekpos = (int) sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
+               k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
                test_read_double_or_die (file, 0, data, channels, __LINE__) ;
                if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin) || k != seekpos)
                {       printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_read_double failed (%d, %d) (%d, %d).\n", __LINE__, (int) (data [0] * scale), (int) (orig [seekpos * channels] * scale), k, seekpos + 1) ;
                        exit (1) ;
                        } ;
 
-               seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
+               seekpos = (int) sf_seek (file, 0, SEEK_CUR) - 20 ;
                /* Check seek backward from current position. */
-               k = sf_seek (file, -20, SEEK_CUR) ;
+               k = (int) sf_seek (file, -20, SEEK_CUR) ;
                test_read_double_or_die (file, 0, data, channels, __LINE__) ;
                if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin) || k != seekpos)
                {       printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_read_double failed (%d, %d) (%d, %d).\n", __LINE__, (int) (data [0] * scale), (int) (orig [seekpos * channels] * scale), k, seekpos) ;
@@ -2315,14 +2331,14 @@ channels = 1 ;
                /* Check that read past end of file returns number of items. */
                sf_seek (file, sfinfo.frames, SEEK_SET) ;
 
-               if ((k = sf_read_double (file, data, datalen)) != 0)
+               if ((k = (int) sf_read_double (file, data, datalen)) != 0)
                {       printf ("\n\nLine %d: Return value from sf_read_double past end of file incorrect (%d).\n", __LINE__, k) ;
                        exit (1) ;
                        } ;
 
                /* Check seek backward from end. */
 
-               if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
+               if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
                {       printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
                        exit (1) ;
                        } ;
@@ -2348,6 +2364,7 @@ read_raw_test (const char *filename, int filetype, int channels)
        short                   *orig, *data ;
        int                             k ;
 
+       get_unique_test_name (&filename, LCT_TEST_PREFIX) ;
        print_test_name ("read_raw_test", filename) ;
 
        datalen = ARRAY_LEN (orig_buffer.s) / 2 ;
@@ -2355,9 +2372,9 @@ read_raw_test (const char *filename, int filetype, int channels)
        orig = orig_buffer.s ;
        data = data_buffer.s ;
 
-       gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
+       gen_signal_double (orig_buffer.d, 32000.0, channels, (int) datalen) ;
        for (k = 0 ; k < datalen ; k++)
-               orig [k] = lrint (orig_buffer.d [k]) ;
+               orig [k] = (short) lrint (orig_buffer.d [k]) ;
 
        sfinfo.samplerate       = SAMPLE_RATE ;
        sfinfo.frames           = 123456789 ;   /* Ridiculous value. */
@@ -2516,7 +2533,7 @@ smoothed_diff_float (float *data, unsigned int datalen)
 
        /* Calculate the smoothed sample-to-sample difference. */
        for (k = 0 ; k < datalen - 1 ; k++)
-       {       memory = 0.7 * memory + (1 - 0.7) * (data [k+1] - data [k]) ;
+       {       memory = (float) (0.7 * memory + (1 - 0.7) * (data [k+1] - data [k])) ;
                data [k] = memory ;
                } ;
        data [datalen-1] = data [datalen-2] ;
diff --git a/tests/mpeg_test.c b/tests/mpeg_test.c
new file mode 100644 (file)
index 0000000..fe7f53d
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+** Copyright (C) 2007-2019 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2019 John ffitch <jpff@codemist.co.uk>
+**
+** 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>
+#else
+#include "sf_unistd.h"
+#endif
+
+#include <math.h>
+
+#include       <sndfile.h>
+
+#include       "utils.h"
+
+#define        SAMPLE_RATE                     44100
+#define        DATA_LENGTH                     (SAMPLE_RATE / 8)
+
+typedef union
+{      double d [DATA_LENGTH] ;
+       float f [DATA_LENGTH] ;
+       int i [DATA_LENGTH] ;
+       short s [DATA_LENGTH] ;
+} BUFFER ;
+
+static BUFFER data_out ;
+static BUFFER data_in ;
+
+static void
+mpeg_short_test (void)
+{      const char * filename = "mpeg_short.mp3" ;
+
+       SNDFILE * file ;
+       SF_INFO sfinfo ;
+       short seek_data [10] ;
+       unsigned k ;
+
+       print_test_name ("mpeg_short_test", filename) ;
+
+       /* Generate float data. */
+       gen_windowed_sine_float (data_out.f, ARRAY_LEN (data_out.f), 1.0 * 0x7F00) ;
+
+       /* Convert to shorteger. */
+       for (k = 0 ; k < ARRAY_LEN (data_out.s) ; k++)
+               data_out.s [k] = lrintf (data_out.f [k]) ;
+
+       memset (&sfinfo, 0, sizeof (sfinfo)) ;
+
+       /* Set up output file type. */
+       sfinfo.format = SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III ;
+       sfinfo.channels = 1 ;
+       sfinfo.samplerate = SAMPLE_RATE ;
+
+       /* Write the output file. */
+       file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
+       test_write_short_or_die (file, 0, data_out.s, ARRAY_LEN (data_out.s), __LINE__) ;
+       sf_close (file) ;
+
+       /* Read the file in again. */
+       memset (&sfinfo, 0, sizeof (sfinfo)) ;
+
+       file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
+       test_read_short_or_die (file, 0, data_in.s, ARRAY_LEN (data_in.s), __LINE__) ;
+       sf_close (file) ;
+
+       puts ("ok") ;
+
+       /* Test seeking. */
+       print_test_name ("mpeg_seek_test", filename) ;
+
+       file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
+
+       test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
+       test_read_short_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
+       compare_short_or_die (seek_data, data_in.s + 10, ARRAY_LEN (seek_data), __LINE__) ;
+
+       /* Test seek to end of file. */
+       test_seek_or_die (file, 0, SEEK_END, sfinfo.frames, sfinfo.channels, __LINE__) ;
+
+       sf_close (file) ;
+
+       puts ("ok") ;
+
+       unlink (filename) ;
+} /* mpeg_short_test */
+
+static void
+mpeg_int_test (void)
+{      const char * filename = "mpeg_int.mp3" ;
+
+       SNDFILE * file ;
+       SF_INFO sfinfo ;
+       int seek_data [10] ;
+       unsigned k ;
+
+       print_test_name ("mpeg_int_test", filename) ;
+
+       /* Generate float data. */
+       gen_windowed_sine_float (data_out.f, ARRAY_LEN (data_out.f), 1.0 * 0x7FFF0000) ;
+
+       /* Convert to integer. */
+       for (k = 0 ; k < ARRAY_LEN (data_out.i) ; k++)
+               data_out.i [k] = lrintf (data_out.f [k]) ;
+
+       memset (&sfinfo, 0, sizeof (sfinfo)) ;
+
+       /* Set up output file type. */
+       sfinfo.format = SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III ;
+       sfinfo.channels = 1 ;
+       sfinfo.samplerate = SAMPLE_RATE ;
+
+       /* Write the output file. */
+       file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
+       test_write_int_or_die (file, 0, data_out.i, ARRAY_LEN (data_out.i), __LINE__) ;
+       sf_close (file) ;
+
+       /* Read the file in again. */
+       memset (&sfinfo, 0, sizeof (sfinfo)) ;
+
+       file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
+       test_read_int_or_die (file, 0, data_in.i, ARRAY_LEN (data_in.i), __LINE__) ;
+       sf_close (file) ;
+
+       puts ("ok") ;
+
+       /* Test seeking. */
+       print_test_name ("mpeg_seek_test", filename) ;
+
+       file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
+
+       test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
+       test_read_int_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
+       compare_int_or_die (seek_data, data_in.i + 10, ARRAY_LEN (seek_data), __LINE__) ;
+
+       sf_close (file) ;
+
+       puts ("ok") ;
+
+       unlink (filename) ;
+} /* mpeg_int_test */
+
+static void
+mpeg_float_test (void)
+{      const char * filename = "mpeg_float.mp3" ;
+
+       SNDFILE * file ;
+       SF_INFO sfinfo ;
+       float seek_data [10] ;
+
+       print_test_name ("mpeg_float_test", filename) ;
+
+       gen_windowed_sine_float (data_out.f, ARRAY_LEN (data_out.f), 0.95) ;
+
+       memset (&sfinfo, 0, sizeof (sfinfo)) ;
+
+       /* Set up output file type. */
+       sfinfo.format = SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III ;
+       sfinfo.channels = 1 ;
+       sfinfo.samplerate = SAMPLE_RATE ;
+
+       /* Write the output file. */
+       file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
+       test_write_float_or_die (file, 0, data_out.f, ARRAY_LEN (data_out.f), __LINE__) ;
+       sf_close (file) ;
+
+       /* Read the file in again. */
+       memset (&sfinfo, 0, sizeof (sfinfo)) ;
+
+       file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
+       test_read_float_or_die (file, 0, data_in.f, ARRAY_LEN (data_in.f), __LINE__) ;
+       sf_close (file) ;
+
+       puts ("ok") ;
+
+       /* Test seeking. */
+       print_test_name ("mpeg_seek_test", filename) ;
+
+       file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
+
+       test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
+       test_read_float_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
+       compare_float_or_die (seek_data, data_in.f + 10, ARRAY_LEN (seek_data), __LINE__) ;
+
+       sf_close (file) ;
+
+       puts ("ok") ;
+
+       unlink (filename) ;
+} /* mpeg_float_test */
+
+static void
+mpeg_double_test (void)
+{      const char * filename = "mpeg_double.mp3" ;
+
+       SNDFILE * file ;
+       SF_INFO sfinfo ;
+       double seek_data [10] ;
+
+       print_test_name ("mpeg_double_test", filename) ;
+
+       gen_windowed_sine_double (data_out.d, ARRAY_LEN (data_out.d), 0.95) ;
+
+       memset (&sfinfo, 0, sizeof (sfinfo)) ;
+
+       /* Set up output file type. */
+       sfinfo.format = SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III ;
+       sfinfo.channels = 1 ;
+       sfinfo.samplerate = SAMPLE_RATE ;
+
+       /* Write the output file. */
+       file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
+       test_write_double_or_die (file, 0, data_out.d, ARRAY_LEN (data_out.d), __LINE__) ;
+       sf_close (file) ;
+
+       /* Read the file in again. */
+       memset (&sfinfo, 0, sizeof (sfinfo)) ;
+
+       file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
+       test_read_double_or_die (file, 0, data_in.d, ARRAY_LEN (data_in.d), __LINE__) ;
+       sf_close (file) ;
+
+       puts ("ok") ;
+
+       /* Test seeking. */
+       print_test_name ("mpeg_seek_test", filename) ;
+
+       file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
+
+       test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
+       test_read_double_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
+       compare_double_or_die (seek_data, data_in.d + 10, ARRAY_LEN (seek_data), __LINE__) ;
+
+       sf_close (file) ;
+
+       puts ("ok") ;
+
+       unlink (filename) ;
+} /* mpeg_double_test */
+
+
+static void
+mpeg_stereo_seek_test (const char * filename, int format)
+{      static float data [SAMPLE_RATE] ;
+       static float stereo_out [SAMPLE_RATE * 2] ;
+
+       SNDFILE * file ;
+       SF_INFO sfinfo ;
+       sf_count_t pos ;
+       unsigned k ;
+
+       print_test_name (__func__, filename) ;
+
+       gen_windowed_sine_float (data, ARRAY_LEN (data), 0.95) ;
+       for (k = 0 ; k < ARRAY_LEN (data) ; k++)
+       {       stereo_out [2 * k] = data [k] ;
+               stereo_out [2 * k + 1] = data [ARRAY_LEN (data) - k - 1] ;
+               } ;
+
+       memset (&sfinfo, 0, sizeof (sfinfo)) ;
+
+       /* Set up output file type. */
+       sfinfo.format = format ;
+       sfinfo.channels = 2 ;
+       sfinfo.samplerate = SAMPLE_RATE ;
+
+       /* Write the output file. */
+       file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
+       test_write_float_or_die (file, 0, stereo_out, ARRAY_LEN (stereo_out), __LINE__) ;
+       sf_close (file) ;
+
+       /* Open file in again for reading. */
+       memset (&sfinfo, 0, sizeof (sfinfo)) ;
+       file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
+
+       /* Read in the whole file. */
+       test_read_float_or_die (file, 0, stereo_out, ARRAY_LEN (stereo_out), __LINE__) ;
+
+       /* Now hammer seeking code. */
+       test_seek_or_die (file, 234, SEEK_SET, 234, sfinfo.channels, __LINE__) ;
+       test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
+       compare_float_or_die (data, stereo_out + (234 * sfinfo.channels), 10, __LINE__) ;
+
+       test_seek_or_die (file, 442, SEEK_SET, 442, sfinfo.channels, __LINE__) ;
+       test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
+       compare_float_or_die (data, stereo_out + (442 * sfinfo.channels), 10, __LINE__) ;
+
+       test_seek_or_die (file, 12, SEEK_CUR, 442 + 10 + 12, sfinfo.channels, __LINE__) ;
+       test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
+       compare_float_or_die (data, stereo_out + ((442 + 10 + 12) * sfinfo.channels), 10, __LINE__) ;
+
+       test_seek_or_die (file, 12, SEEK_CUR, 442 + 20 + 24, sfinfo.channels, __LINE__) ;
+       test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
+       compare_float_or_die (data, stereo_out + ((442 + 20 + 24) * sfinfo.channels), 10, __LINE__) ;
+
+       pos = 500 - sfinfo.frames ;
+       test_seek_or_die (file, pos, SEEK_END, 500, sfinfo.channels, __LINE__) ;
+       test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
+       compare_float_or_die (data, stereo_out + (500 * sfinfo.channels), 10, __LINE__) ;
+
+       pos = 10 - sfinfo.frames ;
+       test_seek_or_die (file, pos, SEEK_END, 10, sfinfo.channels, __LINE__) ;
+       test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
+       compare_float_or_die (data, stereo_out + (10 * sfinfo.channels), 10, __LINE__) ;
+
+       sf_close (file) ;
+
+       puts ("ok") ;
+       unlink (filename) ;
+} /* mpeg_stereo_seek_test */
+
+
+int
+main (void)
+{
+       if (HAVE_MPEG)
+       {       mpeg_short_test () ;
+               mpeg_int_test () ;
+               mpeg_float_test () ;
+               mpeg_double_test () ;
+
+               mpeg_stereo_seek_test ("mpeg_seek.mp3", SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III) ;
+               }
+       else
+               puts ("    No MPEG tests because mpg123/lame support was not compiled in.") ;
+       return 0 ;
+} /* main */
+
index 502d15a..6906973 100644 (file)
@@ -161,7 +161,7 @@ multi_file_test (const char *filename, int *formats, int format_count)
                        printf ("This offset : %" PRId64 "\n", embed_info.offset + embed_info.length) ;
                        } ;
 
-               if (lseek (fd, embed_info.offset + embed_info.length, SEEK_SET) < 0)
+               if (lseek (fd, (long) (embed_info.offset + embed_info.length), SEEK_SET) < 0)
                {       printf ("\n\nLine %d: lseek failed : %s\n", __LINE__, strerror (errno)) ;
                        exit (1) ;
                        } ;
index 37532be..a850908 100644 (file)
@@ -62,7 +62,7 @@ ogg_opus_short_test (void)
 
        /* Convert to short. */
        for (k = 0 ; k < ARRAY_LEN (data_out.s) ; k++)
-               data_out.s [k] = lrintf (data_out.f [k]) ;
+               data_out.s [k] = (short) lrintf (data_out.f [k]) ;
 
        memset (&sfinfo, 0, sizeof (sfinfo)) ;
 
index ba3d899..dcc5ed1 100644 (file)
@@ -62,7 +62,7 @@ ogg_short_test (void)
 
        /* Convert to shorteger. */
        for (k = 0 ; k < ARRAY_LEN (data_out.s) ; k++)
-               data_out.s [k] = lrintf (data_out.f [k]) ;
+               data_out.s [k] = (short) lrintf (data_out.f [k]) ;
 
        memset (&sfinfo, 0, sizeof (sfinfo)) ;
 
index 651614a..1a9c67b 100644 (file)
@@ -185,7 +185,7 @@ stdin_test  (int typemajor, int count)
                } ;
 
        total = 0 ;
-       while ((k = sf_read_short (file, data + total, BUFFER_LEN - total)) > 0)
+       while ((k = (int) sf_read_short (file, data + total, BUFFER_LEN - total)) > 0)
                total += k ;
 
        if (total != count)
index a71ed64..e2cbe8d 100644 (file)
@@ -155,7 +155,7 @@ stdout_test (int typemajor, int count)
 
        while (total < count)
        {       this_write = (count - total > 1024) ? 1024 : count - total ;
-               if ((k = sf_write_short (file, data + total, this_write)) != this_write)
+               if ((k = (int) sf_write_short (file, data + total, this_write)) != this_write)
                {       fprintf (stderr, "sf_write_short # %d failed with short write (%d -> %d)\n", count, this_write, k) ;
                        exit (1) ;
                        } ;
index 70a0dfb..ab07df7 100644 (file)
@@ -37,6 +37,8 @@
 #define        BUFFER_LEN                      (1 << 10)
 #define LOG_BUFFER_SIZE                1024
 
+static const char STR_TEST_PREFIX[] = "str" ;
+
 static void    string_start_test (const char *filename, int typemajor) ;
 static void    string_start_end_test (const char *filename, int typemajor) ;
 static void    string_multi_set_test (const char *filename, int typemajor) ;
@@ -113,6 +115,14 @@ main (int argc, char *argv [])
                test_count++ ;
                } ;
 
+       if (do_all || ! strcmp (argv [1], "mpeg"))
+       {       if (HAVE_MPEG)
+                       string_start_test ("mpeg.mp3", SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III) ;
+               else
+                       puts ("    No MP3 tests because MPEG support was not compiled in.") ;
+               test_count++ ;
+               } ;
+
        if (do_all || ! strcmp (argv [1], "ogg"))
        {       if (HAVE_EXTERNAL_XIPH_LIBS)
                        string_start_test ("vorbis.oga", SF_FORMAT_OGG | SF_FORMAT_VORBIS) ;
@@ -195,7 +205,9 @@ static const char
        long_title      []      = "This is a very long and very boring title for this file",
        long_artist     []      = "The artist who kept on changing its name",
        genre           []      = "The genre",
-       trackno         []      = "Track three" ;
+       trackno         []      = "Track three",
+       id3v1_genre     []      = "Rock",
+       year            []      = "2001" ;
 
 
 static short   data_out [BUFFER_LEN] ;
@@ -207,6 +219,7 @@ string_start_end_test (const char *filename, int typemajor)
        SF_INFO         sfinfo ;
        int                     errors = 0 ;
 
+       get_unique_test_name (&filename, STR_TEST_PREFIX) ;
        print_test_name ("string_start_end_test", filename) ;
 
        memset (&sfinfo, 0, sizeof (sfinfo)) ;
@@ -356,6 +369,7 @@ string_start_test (const char *filename, int formattype)
        int                     errors = 0 ;
        int                     typemajor = SF_FORMAT_TYPEMASK & formattype ;
 
+       get_unique_test_name (&filename, STR_TEST_PREFIX) ;
        print_test_name ("string_start_test", filename) ;
 
        memset (&sfinfo, 0, sizeof (sfinfo)) ;
@@ -370,6 +384,7 @@ string_start_test (const char *filename, int formattype)
                        break ;
 
                case SF_FORMAT_OGG | SF_FORMAT_VORBIS :
+               case SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III :
                        break ;
 
                default :
@@ -386,9 +401,15 @@ string_start_test (const char *filename, int formattype)
        sf_set_string (file, SF_STR_ARTIST, artist) ;
        sf_set_string (file, SF_STR_COPYRIGHT, copyright) ;
        sf_set_string (file, SF_STR_COMMENT, comment) ;
-       sf_set_string (file, SF_STR_DATE, date) ;
        sf_set_string (file, SF_STR_ALBUM, album) ;
        sf_set_string (file, SF_STR_LICENSE, license) ;
+       if (typemajor == SF_FORMAT_MPEG)
+       {       sf_set_string (file, SF_STR_GENRE, id3v1_genre) ;
+               sf_set_string (file, SF_STR_DATE, year) ;
+               }
+       else
+       {       sf_set_string (file, SF_STR_DATE, date) ;
+               } ;
 
        /* Write data to file. */
        test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ;
@@ -411,24 +432,35 @@ string_start_test (const char *filename, int formattype)
                printf ("    Bad filename  : %s\n", cptr) ;
                } ;
 
-       cptr = sf_get_string (file, SF_STR_COPYRIGHT) ;
-       if (cptr == NULL || strcmp (copyright, cptr) != 0)
-       {       if (errors++ == 0)
-                       puts ("\n") ;
-               printf ("    Bad copyright : %s\n", cptr) ;
-               } ;
+       if (typemajor != SF_FORMAT_MPEG)
+       {       cptr = sf_get_string (file, SF_STR_COPYRIGHT) ;
+               if (cptr == NULL || strcmp (copyright, cptr) != 0)
+               {       if (errors++ == 0)
+                               puts ("\n") ;
+                       printf ("    Bad copyright : %s\n", cptr) ;
+                       } ;
 
-       cptr = sf_get_string (file, SF_STR_SOFTWARE) ;
-       if (cptr == NULL || strstr (cptr, software) != cptr)
-       {       if (errors++ == 0)
-                       puts ("\n") ;
-               printf ("    Bad software  : %s\n", cptr) ;
+               cptr = sf_get_string (file, SF_STR_SOFTWARE) ;
+               if (cptr == NULL || strstr (cptr, software) != cptr)
+               {       if (errors++ == 0)
+                               puts ("\n") ;
+                       printf ("    Bad software  : %s\n", cptr) ;
+                       } ;
+
+               if (cptr && str_count (cptr, "libsndfile") != 1)
+               {       if (errors++ == 0)
+                               puts ("\n") ;
+                       printf ("    Bad software  : %s\n", cptr) ;
+                       } ;
                } ;
 
-       if (cptr && str_count (cptr, "libsndfile") != 1)
-       {       if (errors++ == 0)
-                       puts ("\n") ;
-               printf ("    Bad software  : %s\n", cptr) ;
+       if (typemajor == SF_FORMAT_MPEG)
+       {       cptr = sf_get_string (file, SF_STR_GENRE) ;
+               if (cptr == NULL || strcmp (id3v1_genre, cptr) != 0)
+               {       if (errors++ == 0)
+                               puts ("\n") ;
+                       printf ("    Bad genre     : %s\n", cptr) ;
+                       } ;
                } ;
 
        cptr = sf_get_string (file, SF_STR_ARTIST) ;
@@ -445,13 +477,29 @@ string_start_test (const char *filename, int formattype)
                printf ("    Bad comment   : %s\n", cptr) ;
                } ;
 
-       if (typemajor != SF_FORMAT_AIFF)
-       {       cptr = sf_get_string (file, SF_STR_DATE) ;
-               if (cptr == NULL || strcmp (date, cptr) != 0)
-               {       if (errors++ == 0)
-                               puts ("\n") ;
-                       printf ("    Bad date      : %s\n", cptr) ;
-                       } ;
+       switch (typemajor)
+       {       case SF_FORMAT_AIFF :
+                       /* not supported */
+                       break ;
+
+               case SF_FORMAT_MPEG :
+                       /* id3 only supports years */
+                       cptr = sf_get_string (file, SF_STR_DATE) ;
+                       if (cptr == NULL || strcmp (year, cptr) != 0)
+                       {       if (errors++ == 0)
+                                       puts ("\n") ;
+                               printf ("    Bad date      : %s\n", cptr) ;
+                               } ;
+                       break ;
+
+               default :
+                       cptr = sf_get_string (file, SF_STR_DATE) ;
+                       if (cptr == NULL || strcmp (date, cptr) != 0)
+                       {       if (errors++ == 0)
+                                       puts ("\n") ;
+                               printf ("    Bad date      : %s\n", cptr) ;
+                               } ;
+                       break ;
                } ;
 
        if (typemajor != SF_FORMAT_WAV && typemajor != SF_FORMAT_AIFF)
@@ -463,13 +511,21 @@ string_start_test (const char *filename, int formattype)
                        } ;
                } ;
 
-       if (typemajor != SF_FORMAT_WAV && typemajor != SF_FORMAT_AIFF && typemajor != SF_FORMAT_RF64)
-       {       cptr = sf_get_string (file, SF_STR_LICENSE) ;
-               if (cptr == NULL || strcmp (license, cptr) != 0)
-               {       if (errors++ == 0)
-                               puts ("\n") ;
-                       printf ("    Bad license   : %s\n", cptr) ;
-                       } ;
+       switch (typemajor)
+       {       case SF_FORMAT_WAV :
+               case SF_FORMAT_AIFF :
+               case SF_FORMAT_RF64 :
+               case SF_FORMAT_MPEG :
+                       /* not supported */
+                       break ;
+
+               default:
+                       cptr = sf_get_string (file, SF_STR_LICENSE) ;
+                       if (cptr == NULL || strcmp (license, cptr) != 0)
+                       {       if (errors++ == 0)
+                                       puts ("\n") ;
+                               printf ("    Bad license   : %s\n", cptr) ;
+                               } ;
                } ;
 
        if (errors > 0)
@@ -497,6 +553,7 @@ string_multi_set_test (const char *filename, int typemajor)
        SF_INFO         sfinfo ;
        int                     count ;
 
+       get_unique_test_name (&filename, STR_TEST_PREFIX) ;
        print_test_name (__func__, filename) ;
 
        memset (&sfinfo, 0, sizeof (sfinfo)) ;
@@ -566,6 +623,7 @@ string_rdwr_test (const char *filename, int typemajor)
        sf_count_t frames ;
        const char * str ;
 
+       get_unique_test_name (&filename, STR_TEST_PREFIX) ;
        print_test_name (__func__, filename) ;
        create_short_sndfile (filename, typemajor | SF_FORMAT_PCM_16, 2) ;
 
@@ -618,6 +676,7 @@ string_short_rdwr_test (const char *filename, int typemajor)
        sf_count_t frames = BUFFER_LEN ;
        const char * str ;
 
+       get_unique_test_name (&filename, STR_TEST_PREFIX) ;
        print_test_name (__func__, filename) ;
 
        memset (&sfinfo, 0, sizeof (sfinfo)) ;
@@ -687,6 +746,7 @@ static void
 software_string_test (const char *filename)
 {      size_t k ;
 
+       get_unique_test_name (&filename, STR_TEST_PREFIX) ;
        print_test_name (__func__, filename) ;
 
        for (k = 0 ; k < 50 ; k++)
@@ -727,6 +787,7 @@ string_rdwr_grow_test (const char *filename, int typemajor)
        sf_count_t frames ;
        const char * str ;
 
+       get_unique_test_name (&filename, STR_TEST_PREFIX) ;
        print_test_name (__func__, filename) ;
 
        /* Create a file that contains some strings. Then open the file in RDWR mode and
@@ -785,6 +846,7 @@ string_header_update (const char *filename, int typemajor)
        const char * str ;
        const int GROW_BUFFER_AMOUNT = 4 ; /* this should be less than half the size of the string header */
 
+       get_unique_test_name (&filename, STR_TEST_PREFIX) ;
        print_test_name (__func__, filename) ;
 
        /* Create a short file. */
index b06a178..ab92f7c 100644 (file)
@@ -352,6 +352,15 @@ echo "----------------------------------------------------------------------"
 echo "  $sfversion passed tests on OPUS files."
 echo "----------------------------------------------------------------------"
 
+# mpeg-tests
+./tests/mpeg_test@EXEEXT@
+./tests/compression_size_test@EXEEXT@ mpeg
+./tests/string_test@EXEEXT@ mpeg
+
+echo "----------------------------------------------------------------------"
+echo "  $sfversion passed tests on MPEG files."
+echo "----------------------------------------------------------------------"
+
 # io-tests
 ./tests/stdio_test@EXEEXT@
 ./tests/pipe_test@EXEEXT@
index 9e0eba9..cf2084b 100644 (file)
@@ -49,7 +49,7 @@ main (void)
 
        print_test_name ("ulaw_test", "encoder") ;
 
-       filename = "test.raw" ;
+       filename = "ulaw_test.raw" ;
 
        sf_info_setup (&sfinfo, SF_FORMAT_RAW | SF_FORMAT_ULAW, 44100, 1) ;
 
index 7be35fa..c68e3a2 100644 (file)
@@ -104,6 +104,8 @@ void        count_open_files (void) ;
 void   increment_open_file_count (void) ;
 void   check_open_file_count_or_die (int lineno) ;
 
+void   get_unique_test_name (const char ** filename, const char * test) ;
+
 #ifdef SNDFILE_H
 
 static inline void
@@ -852,6 +854,15 @@ check_open_file_count_or_die (int lineno)
 } /* check_open_file_count_or_die */
 
 void
+get_unique_test_name (const char ** filename, const char * test)
+{      static char     buffer [1024] ;
+
+       snprintf (buffer, sizeof (buffer), "%s_%s", test, *filename) ;
+
+       *filename = buffer ;
+} /* get_unique_test_name */
+
+void
 write_mono_file (const char * filename, int format, int srate, float * output, int len)
 {      SNDFILE * file ;
        SF_INFO sfinfo ;
index 854bc30..b5f84ac 100644 (file)
@@ -216,7 +216,7 @@ vio_test (const char *fname, int format)
                fflush (stdout) ;
                puts (sf_strerror (NULL)) ;
 
-               dump_data_to_file (fname, vio_data.data, vio_data.length) ;
+               dump_data_to_file (fname, vio_data.data, (unsigned int) vio_data.length) ;
                exit (1) ;
                } ;
 
index af87e12..ed152f8 100644 (file)
@@ -42,6 +42,8 @@
 
 #define        SILLY_WRITE_COUNT       (234)
 
+static const char WRT_TEST_PREFIX[] = "wrt" ;
+
 [+ FOR data_type
 +]static void  pcm_test_[+ (get "type_name") +] (const char *str, int format, int long_file_ok) ;
 [+ ENDFOR data_type
@@ -446,6 +448,7 @@ pcm_test_[+ (get "type_name") +] (const char *filename, int format, int long_fil
        /* Sd2 files cannot be opened from an existing file descriptor. */
        allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
 
+       get_unique_test_name (&filename, WRT_TEST_PREFIX) ;
        print_test_name ("pcm_test_[+ (get "type_name") +]", filename) ;
 
        sfinfo.samplerate       = 44100 ;
@@ -1008,6 +1011,7 @@ empty_file_test (const char *filename, int format)
        /* Sd2 files cannot be opened from an existing file descriptor. */
        allow_fd = ((format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2) ? SF_FALSE : SF_TRUE ;
 
+       get_unique_test_name (&filename, WRT_TEST_PREFIX) ;
        print_test_name ("empty_file_test", filename) ;
 
        unlink (filename) ;
diff --git a/vcpkg.json b/vcpkg.json
new file mode 100644 (file)
index 0000000..a37a18b
--- /dev/null
@@ -0,0 +1,39 @@
+{
+    "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
+    "name": "libsndfile",
+    "description": "A library for reading and writing audio files",
+    "version-semver": "1.1.0",
+    "default-features": [
+        "external-libs",
+        "mpeg"
+    ],
+    "features": {
+        "external-libs": {
+            "description": "Enable FLAC, Vorbis, and Opus codecs",
+            "dependencies": [
+                "libvorbis",
+                "libflac",
+                "opus"
+            ]
+        },
+        "mpeg": {
+            "description": "Enable MPEG codecs",
+            "dependencies": [
+                "mpg123",
+                "mp3lame"
+            ]
+        },
+        "regtest": {
+            "description": "Build regtest",
+            "dependencies": [
+                "sqlite3"
+            ]
+        },
+        "experimental": {
+            "description": "Enable experimental code",
+            "dependencies": [
+                "speex"
+            ]
+        }
+    }
+}