libnyquist debuggable
This commit is contained in:
parent
c7a68277dc
commit
a61ac24170
|
|
@ -0,0 +1,287 @@
|
|||
#cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(LIBNYQUIST_ROOT ${CMAKE_CURRENT_LIST_DIR})
|
||||
set(CMAKE_MODULE_PATH ${LIBNYQUIST_ROOT}/cmake)
|
||||
|
||||
include(CXXhelpers)
|
||||
|
||||
option(BUILD_EXAMPLE "Build example application" OFF)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# libopus
|
||||
|
||||
if (BUILD_LIBOPUS)
|
||||
project(libopus)
|
||||
|
||||
file(GLOB third_opus_src
|
||||
"${LIBNYQUIST_ROOT}/third_party/opus/celt/*.c"
|
||||
"${LIBNYQUIST_ROOT}/third_party/opus/opusfile/src/*.c"
|
||||
"${LIBNYQUIST_ROOT}/third_party/opus/silk/*.c"
|
||||
"${LIBNYQUIST_ROOT}/third_party/opus/silk/float/*.c"
|
||||
)
|
||||
set(lib_opus_src
|
||||
"${LIBNYQUIST_ROOT}/third_party/opus/libopus/src/analysis.c"
|
||||
"${LIBNYQUIST_ROOT}/third_party/opus/libopus/src/mlp_data.c"
|
||||
"${LIBNYQUIST_ROOT}/third_party/opus/libopus/src/mlp.c"
|
||||
"${LIBNYQUIST_ROOT}/third_party/opus/libopus/src/opus_decoder.c"
|
||||
"${LIBNYQUIST_ROOT}/third_party/opus/libopus/src/opus_multistream_decoder.c"
|
||||
"${LIBNYQUIST_ROOT}/third_party/opus/libopus/src/opus_multistream_encoder.c"
|
||||
"${LIBNYQUIST_ROOT}/third_party/opus/libopus/src/opus.c"
|
||||
"${LIBNYQUIST_ROOT}/third_party/opus/libopus/src/repacketizer.c"
|
||||
)
|
||||
|
||||
add_library(libopus STATIC ${third_opus_src} ${lib_opus_src})
|
||||
|
||||
set_cxx_version(libopus)
|
||||
_set_compile_options(libopus)
|
||||
|
||||
if (WIN32)
|
||||
_disable_warning(4244)
|
||||
_disable_warning(4018)
|
||||
endif()
|
||||
|
||||
target_include_directories(libopus PRIVATE
|
||||
${LIBNYQUIST_ROOT}/third_party/libogg/include
|
||||
${LIBNYQUIST_ROOT}/third_party/opus/celt
|
||||
${LIBNYQUIST_ROOT}/third_party/opus/libopus/include
|
||||
${LIBNYQUIST_ROOT}/third_party/opus/opusfile/include
|
||||
${LIBNYQUIST_ROOT}/third_party/opus/opusfile/src/include
|
||||
${LIBNYQUIST_ROOT}/third_party/opus/silk
|
||||
${LIBNYQUIST_ROOT}/third_party/opus/silk/float)
|
||||
|
||||
if (MSVC_IDE)
|
||||
# hack to get around the "Debug" and "Release" directories cmake tries to add on Windows
|
||||
#set_target_properties(libnyquist PROPERTIES PREFIX "../")
|
||||
set_target_properties(libopus PROPERTIES IMPORT_PREFIX "../")
|
||||
endif()
|
||||
|
||||
target_compile_definitions(libopus PRIVATE OPUS_BUILD)
|
||||
target_compile_definitions(libopus PRIVATE USE_ALLOCA)
|
||||
|
||||
set_target_properties(libopus
|
||||
PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
)
|
||||
|
||||
set_target_properties(libopus PROPERTIES OUTPUT_NAME_DEBUG libopus_d)
|
||||
|
||||
install (TARGETS libopus
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
RUNTIME DESTINATION bin)
|
||||
|
||||
install (TARGETS libopus DESTINATION lib)
|
||||
|
||||
# folders
|
||||
|
||||
source_group(src FILES ${third_opus_src})
|
||||
endif()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# libwavpack
|
||||
|
||||
project(libwavpack)
|
||||
|
||||
if(MSVC)
|
||||
# Disable warning C4996 regarding fopen(), strcpy(), etc.
|
||||
_add_define("_CRT_SECURE_NO_WARNINGS")
|
||||
|
||||
# Disable warning C4996 regarding unchecked iterators for std::transform,
|
||||
# std::copy, std::equal, et al.
|
||||
_add_define("_SCL_SECURE_NO_WARNINGS")
|
||||
|
||||
# Make sure WinDef.h does not define min and max macros which
|
||||
# will conflict with std::min() and std::max().
|
||||
_add_define("NOMINMAX")
|
||||
endif()
|
||||
|
||||
add_definitions(${_NQR_CXX_DEFINITIONS})
|
||||
set(CMAKE_CXX_FLAGS "${_NQR_CXX_FLAGS} ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# file(GLOB third_wavpack_src "${LIBNYQUIST_ROOT}/third_party/wavpack/src/*")
|
||||
|
||||
# add_library(libwavpack STATIC ${third_wavpack_src})
|
||||
|
||||
# set_cxx_version(libwavpack)
|
||||
# _set_compile_options(libwavpack)
|
||||
|
||||
# if (WIN32)
|
||||
# _disable_warning(181)
|
||||
# _disable_warning(111)
|
||||
# _disable_warning(4267)
|
||||
# _disable_warning(4996)
|
||||
# _disable_warning(4244)
|
||||
# _disable_warning(4701)
|
||||
# _disable_warning(4702)
|
||||
# _disable_warning(4133)
|
||||
# _disable_warning(4100)
|
||||
# _disable_warning(4127)
|
||||
# _disable_warning(4206)
|
||||
# _disable_warning(4312)
|
||||
# _disable_warning(4505)
|
||||
# _disable_warning(4365)
|
||||
# _disable_warning(4005)
|
||||
# _disable_warning(4013)
|
||||
# _disable_warning(4334)
|
||||
# _disable_warning(4703)
|
||||
# endif()
|
||||
|
||||
# target_include_directories(libwavpack PRIVATE ${LIBNYQUIST_ROOT}/third_party/wavpack/include)
|
||||
|
||||
# if (MSVC_IDE)
|
||||
# set_target_properties(libwavpack PROPERTIES IMPORT_PREFIX "../")
|
||||
# endif()
|
||||
|
||||
# set_target_properties(libwavpack
|
||||
# PROPERTIES
|
||||
# LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||
# ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
# RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
# )
|
||||
|
||||
# set_target_properties(libwavpack PROPERTIES OUTPUT_NAME_DEBUG libwavpack_d)
|
||||
|
||||
# install(TARGETS libwavpack
|
||||
# LIBRARY DESTINATION lib
|
||||
# ARCHIVE DESTINATION lib
|
||||
# RUNTIME DESTINATION bin)
|
||||
|
||||
# install (TARGETS libwavpack DESTINATION lib)
|
||||
|
||||
# #-------------------------------------------------------------------------------
|
||||
|
||||
# # libnyquist static library
|
||||
|
||||
project(libnyquist)
|
||||
|
||||
file(GLOB nyquist_include "${LIBNYQUIST_ROOT}/include/libnyquist/*")
|
||||
file(GLOB nyquist_src "${LIBNYQUIST_ROOT}/src/*")
|
||||
file(GLOB wavpack_src "${LIBNYQUIST_ROOT}/third_party/wavpack/src/*")
|
||||
|
||||
add_library(libnyquist
|
||||
${nyquist_include}
|
||||
${nyquist_src}
|
||||
)
|
||||
|
||||
set_cxx_version(libnyquist)
|
||||
_set_compile_options(libnyquist)
|
||||
|
||||
if (WIN32)
|
||||
_disable_warning(4244)
|
||||
_disable_warning(4018)
|
||||
endif()
|
||||
|
||||
target_include_directories(libnyquist
|
||||
PUBLIC
|
||||
$<INSTALL_INTERFACE:include>
|
||||
$<BUILD_INTERFACE:${LIBNYQUIST_ROOT}/include>
|
||||
PRIVATE
|
||||
${LIBNYQUIST_ROOT}/include/libnyquist
|
||||
${LIBNYQUIST_ROOT}/third_party
|
||||
${LIBNYQUIST_ROOT}/third_party/FLAC/src/include
|
||||
${LIBNYQUIST_ROOT}/third_party/libogg/include
|
||||
${LIBNYQUIST_ROOT}/third_party/libvorbis/include
|
||||
${LIBNYQUIST_ROOT}/third_party/libvorbis/src
|
||||
${LIBNYQUIST_ROOT}/third_party/musepack/include
|
||||
${LIBNYQUIST_ROOT}/third_party/opus/celt
|
||||
${LIBNYQUIST_ROOT}/third_party/opus/libopus/include
|
||||
${LIBNYQUIST_ROOT}/third_party/opus/opusfile/include
|
||||
${LIBNYQUIST_ROOT}/third_party/opus/opusfile/src/include
|
||||
${LIBNYQUIST_ROOT}/third_party/opus/silk
|
||||
${LIBNYQUIST_ROOT}/third_party/opus/silk/float
|
||||
${LIBNYQUIST_ROOT}/third_party/wavpack/include
|
||||
${LIBNYQUIST_ROOT}/src
|
||||
)
|
||||
|
||||
if (MSVC_IDE)
|
||||
# hack to get around the "Debug" and "Release" directories cmake tries to add on Windows
|
||||
#set_target_properties(libnyquist PROPERTIES PREFIX "../")
|
||||
set_target_properties(libnyquist PROPERTIES IMPORT_PREFIX "../")
|
||||
endif()
|
||||
|
||||
set_target_properties(libnyquist PROPERTIES OUTPUT_NAME_DEBUG libnyquist_d)
|
||||
|
||||
set_target_properties(libnyquist
|
||||
PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
)
|
||||
|
||||
# target_link_libraries(libnyquist PRIVATE libwavpack)
|
||||
|
||||
install(TARGETS libnyquist
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
RUNTIME DESTINATION bin)
|
||||
|
||||
install(TARGETS libnyquist DESTINATION lib)
|
||||
|
||||
# folders
|
||||
source_group(src FILES ${nyquist_src})
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# libnyquist-examples
|
||||
|
||||
# if(BUILD_EXAMPLE)
|
||||
|
||||
# set(NQR_EXAMPLE_APP_NAME "libnyquist-examples")
|
||||
|
||||
# set(
|
||||
# EXAMPLE_SOURCES
|
||||
# ${LIBNYQUIST_ROOT}/examples/src/Main.cpp
|
||||
# ${LIBNYQUIST_ROOT}/examples/src/AudioDevice.cpp
|
||||
# ${LIBNYQUIST_ROOT}/examples/src/AudioDevice.h
|
||||
# ${LIBNYQUIST_ROOT}/examples/src/RingBuffer.h
|
||||
# ${LIBNYQUIST_ROOT}/third_party/rtaudio/RtAudio.cpp
|
||||
# ${LIBNYQUIST_ROOT}/third_party/rtaudio/RtAudio.h
|
||||
# )
|
||||
|
||||
# add_executable(${NQR_EXAMPLE_APP_NAME} ${EXAMPLE_SOURCES})
|
||||
|
||||
# if(WIN32)
|
||||
# target_compile_definitions(${NQR_EXAMPLE_APP_NAME} PRIVATE __WINDOWS_WASAPI__)
|
||||
# elseif(APPLE)
|
||||
# target_compile_definitions(${NQR_EXAMPLE_APP_NAME} PRIVATE __MACOSX_CORE__)
|
||||
# elseif(LIBNYQUIST_JACK)
|
||||
# target_compile_definitions(${NQR_EXAMPLE_APP_NAME} PRIVATE __UNIX_JACK__)
|
||||
# target_link_libraries(${NQR_EXAMPLE_APP_NAME} PRIVATE jack pthread)
|
||||
# elseif(LIBNYQUIST_PULSE)
|
||||
# target_compile_definitions(${NQR_EXAMPLE_APP_NAME} PRIVATE __LINUX_PULSE__)
|
||||
# target_link_libraries(${NQR_EXAMPLE_APP_NAME} PRIVATE pulse pthread)
|
||||
# elseif(LIBNYQUIST_ASOUND)
|
||||
# target_compile_definitions(${NQR_EXAMPLE_APP_NAME} PRIVATE __LINUX_ALSA__)
|
||||
# target_link_libraries(${NQR_EXAMPLE_APP_NAME} PRIVATE asound pthread)
|
||||
# else()
|
||||
# message(FATAL, "On Linux, one of LIBNYQUIST_JACK, LIBNYQUIST_PULSE, or LIBNYQUIST_ASOUND must be set.")
|
||||
# endif()
|
||||
|
||||
# target_include_directories(${NQR_EXAMPLE_APP_NAME} PRIVATE
|
||||
# ${LIBNYQUIST_ROOT}/examples/src
|
||||
# ${LIBNYQUIST_ROOT}/third_party
|
||||
# )
|
||||
# target_link_libraries(${NQR_EXAMPLE_APP_NAME} PRIVATE libnyquist)
|
||||
|
||||
# set_target_properties(${NQR_EXAMPLE_APP_NAME}
|
||||
# PROPERTIES
|
||||
# LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||
# ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
# RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
# )
|
||||
|
||||
# if(APPLE)
|
||||
# target_link_libraries(${NQR_EXAMPLE_APP_NAME} PRIVATE
|
||||
# "-framework AudioToolbox"
|
||||
# "-framework AudioUnit"
|
||||
# "-framework Accelerate"
|
||||
# "-framework CoreAudio"
|
||||
# "-framework Cocoa"
|
||||
# )
|
||||
# ENDIF(APPLE)
|
||||
|
||||
# endif()
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
This project is made available under the simplified 2-clause BSD license. See
|
||||
LICENSE for more information.
|
||||
|
||||
libnyquist incorporates third-party libraries from the following sources:
|
||||
|
||||
libcinder (2-Clause BSD)
|
||||
===============================================================================
|
||||
Copyright (c) 2010, The Cinder Project: http://libcinder.org All rights
|
||||
reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
WavPack (3-Clause BSD)
|
||||
===============================================================================
|
||||
Copyright (c) 1998 - 2015 Conifer Software All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Conifer Software nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Opus Codec (3-Clause BSD)
|
||||
===============================================================================
|
||||
Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic, Jean-Marc Valin, Timothy
|
||||
B. Terriberry, CSIRO, Gregory Maxwell, Mark Borgerding, Erik de Castro Lopo
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Internet Society, IETF or IETF Trust, nor the names
|
||||
of specific contributors, may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Opus is subject to the royalty-free patent licenses which are specified at:
|
||||
Xiph.Org Foundation: https://datatracker.ietf.org/ipr/1524/ Microsoft
|
||||
Corporation: https://datatracker.ietf.org/ipr/1914/ Broadcom Corporation:
|
||||
https://datatracker.ietf.org/ipr/1526/
|
||||
|
||||
FLAC Codec (3-Clause BSD)
|
||||
===============================================================================
|
||||
Copyright (C) 2000-2009 Josh Coalson Copyright (C) 2011-2014 Xiph.Org
|
||||
Foundation
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Libvorbis (3-Clause BSD)
|
||||
===============================================================================
|
||||
Copyright (c) 2002-2015 Xiph.org Foundation
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Libogg (3-Clause BSD)
|
||||
===============================================================================
|
||||
Copyright (c) 2002, Xiph.org Foundation
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
RtAudio (MIT-Compatible)
|
||||
===============================================================================
|
||||
Copyright (c) 2001-2014 Gary P. Scavone
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is asked to
|
||||
send the modifications to the original developer so that they can be
|
||||
incorporated into the canonical version. This is, however, not a binding
|
||||
provision of this license.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Musepack (3-Clause BSD)
|
||||
===============================================================================
|
||||
Copyright (c) 2005, The Musepack Development Team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
libmodplug (Public Domain)
|
||||
===============================================================================
|
||||
ModPlug-XMMS and libmodplug are now in the public domain.
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# Libnyquist
|
||||
|
||||
|
||||
Platform | Build Status |
|
||||
-------- | ------------ |
|
||||
Microsoft VS2017 x64 | [](https://ci.appveyor.com/project/ddiakopoulos/libnyquist) |
|
||||
Clang (OSX) & GCC (Linux) | [](https://travis-ci.org/ddiakopoulos/libnyquist) |
|
||||
|
||||
Libnyquist is a small C++11 library for reading sampled audio data from disk or memory. It is intended to be used an audio loading frontend for games, audio sequencers, music players, and more.
|
||||
|
||||
The library does not include patent or license encumbered formats (such as AAC). For portability, libnyquist does not link against platform-specific APIs like Windows Media Foundation or CoreAudio, and instead bundles the source code of reference decoders as an implementation detail.
|
||||
|
||||
Libnyquist is meant to be statically linked, which is not the case with other popular libraries like libsndfile (which is licensed under the LGPL). Furthermore, the library is not concerned with supporting very rare encodings (for instance, A-law PCM or the SND format).
|
||||
|
||||
While untested, there are no technical conditions that preclude compilation on other platforms with C++11 support (Android NDK r10e+, Linux, iOS, etc).
|
||||
|
||||
## Format Support
|
||||
|
||||
Regardless of input bit depth, the library produces a channel-interleaved float vector, normalized between [-1.0,+1.0]. At present, the library does not provide comprehensive resampling functionality.
|
||||
|
||||
* Wave (+ IMA-ADPCM encoding)
|
||||
* MP3
|
||||
* Ogg Vorbis
|
||||
* Ogg Opus
|
||||
* FLAC
|
||||
* WavPack
|
||||
* Musepack
|
||||
|
||||
## Known Issues & Bugs
|
||||
* See the Github issue tracker.
|
||||
|
||||
## License
|
||||
This library is released under the simplied 2 clause BSD license. All included dependencies have been released under identical or similarly permissive licenses.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# appveyor file
|
||||
# http://www.appveyor.com/docs/appveyor-yml
|
||||
|
||||
os: Visual Studio 2017
|
||||
|
||||
platform:
|
||||
- x64
|
||||
|
||||
build_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -G "Visual Studio 15 2017 Win64" ..
|
||||
- cmake --build . --config Release
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
# Install script for directory: E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist
|
||||
|
||||
# Set the install prefix
|
||||
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
set(CMAKE_INSTALL_PREFIX "C:/Program Files (x86)/libwavpack")
|
||||
endif()
|
||||
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
# Set the install configuration name.
|
||||
if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
if(BUILD_TYPE)
|
||||
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
||||
else()
|
||||
set(CMAKE_INSTALL_CONFIG_NAME "Release")
|
||||
endif()
|
||||
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
||||
endif()
|
||||
|
||||
# Set the component getting installed.
|
||||
if(NOT CMAKE_INSTALL_COMPONENT)
|
||||
if(COMPONENT)
|
||||
message(STATUS "Install component: \"${COMPONENT}\"")
|
||||
set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
||||
else()
|
||||
set(CMAKE_INSTALL_COMPONENT)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Is this installation the result of a crosscompile?
|
||||
if(NOT DEFINED CMAKE_CROSSCOMPILING)
|
||||
set(CMAKE_CROSSCOMPILING "FALSE")
|
||||
endif()
|
||||
|
||||
if("x${CMAKE_INSTALL_COMPONENT}x" STREQUAL "xUnspecifiedx" OR NOT CMAKE_INSTALL_COMPONENT)
|
||||
if("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Dd][Ee][Bb][Uu][Gg])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/Debug/libwavpack_d.lib")
|
||||
elseif("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Rr][Ee][Ll][Ee][Aa][Ss][Ee])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/Release/libwavpack.lib")
|
||||
elseif("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Mm][Ii][Nn][Ss][Ii][Zz][Ee][Rr][Ee][Ll])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/MinSizeRel/libwavpack.lib")
|
||||
elseif("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Rr][Ee][Ll][Ww][Ii][Tt][Hh][Dd][Ee][Bb][Ii][Nn][Ff][Oo])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/RelWithDebInfo/libwavpack.lib")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if("x${CMAKE_INSTALL_COMPONENT}x" STREQUAL "xUnspecifiedx" OR NOT CMAKE_INSTALL_COMPONENT)
|
||||
if("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Dd][Ee][Bb][Uu][Gg])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/Debug/libwavpack_d.lib")
|
||||
elseif("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Rr][Ee][Ll][Ee][Aa][Ss][Ee])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/Release/libwavpack.lib")
|
||||
elseif("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Mm][Ii][Nn][Ss][Ii][Zz][Ee][Rr][Ee][Ll])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/MinSizeRel/libwavpack.lib")
|
||||
elseif("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Rr][Ee][Ll][Ww][Ii][Tt][Hh][Dd][Ee][Bb][Ii][Nn][Ff][Oo])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/RelWithDebInfo/libwavpack.lib")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if("x${CMAKE_INSTALL_COMPONENT}x" STREQUAL "xUnspecifiedx" OR NOT CMAKE_INSTALL_COMPONENT)
|
||||
if("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Dd][Ee][Bb][Uu][Gg])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/Debug/libnyquist_d.lib")
|
||||
elseif("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Rr][Ee][Ll][Ee][Aa][Ss][Ee])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/Release/libnyquist.lib")
|
||||
elseif("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Mm][Ii][Nn][Ss][Ii][Zz][Ee][Rr][Ee][Ll])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/MinSizeRel/libnyquist.lib")
|
||||
elseif("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Rr][Ee][Ll][Ww][Ii][Tt][Hh][Dd][Ee][Bb][Ii][Nn][Ff][Oo])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/RelWithDebInfo/libnyquist.lib")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if("x${CMAKE_INSTALL_COMPONENT}x" STREQUAL "xUnspecifiedx" OR NOT CMAKE_INSTALL_COMPONENT)
|
||||
if("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Dd][Ee][Bb][Uu][Gg])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/Debug/libnyquist_d.lib")
|
||||
elseif("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Rr][Ee][Ll][Ee][Aa][Ss][Ee])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/Release/libnyquist.lib")
|
||||
elseif("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Mm][Ii][Nn][Ss][Ii][Zz][Ee][Rr][Ee][Ll])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/MinSizeRel/libnyquist.lib")
|
||||
elseif("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Rr][Ee][Ll][Ww][Ii][Tt][Hh][Dd][Ee][Bb][Ii][Nn][Ff][Oo])$")
|
||||
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE STATIC_LIBRARY FILES "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/bin/RelWithDebInfo/libnyquist.lib")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_INSTALL_COMPONENT)
|
||||
set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
|
||||
else()
|
||||
set(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
|
||||
endif()
|
||||
|
||||
string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT
|
||||
"${CMAKE_INSTALL_MANIFEST_FILES}")
|
||||
file(WRITE "E:/Engine/env_develop/cocos-engine/native/external/sources/LabSound/third_party/libnyquist/${CMAKE_INSTALL_MANIFEST}"
|
||||
"${CMAKE_INSTALL_MANIFEST_CONTENT}")
|
||||
|
|
@ -0,0 +1,393 @@
|
|||
/*
|
||||
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "Decoders.h"
|
||||
#include <cstring>
|
||||
#include <unordered_map>
|
||||
|
||||
using namespace nqr;
|
||||
|
||||
NyquistIO::NyquistIO() { BuildDecoderTable(); }
|
||||
NyquistIO::~NyquistIO() { }
|
||||
|
||||
void NyquistIO::Load(AudioData * data, const std::string & path)
|
||||
{
|
||||
if (IsFileSupported(path))
|
||||
{
|
||||
if (decoderTable.size())
|
||||
{
|
||||
auto fileExtension = ParsePathForExtension(path);
|
||||
auto decoder = GetDecoderForExtension(fileExtension);
|
||||
|
||||
try
|
||||
{
|
||||
decoder->LoadFromPath(data, path);
|
||||
}
|
||||
catch (const std::exception & e)
|
||||
{
|
||||
std::cerr << "NyquistIO::Load(" << path << ") caught internal exception: " << e.what() << std::endl;
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
else throw std::runtime_error("No available decoders.");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw UnsupportedExtensionEx();
|
||||
}
|
||||
}
|
||||
|
||||
void NyquistIO::Load(AudioData * data, const std::vector<uint8_t> & buffer)
|
||||
{
|
||||
|
||||
const std::map<std::vector<int16_t>, std::string> magic_map{
|
||||
{{ 'w', 'v', 'p', 'k' }, "wv" },
|
||||
{{ 'M', 'P', 'C', 'K' }, "mpc" },
|
||||
{{ 0xFF, 0xFB }, "mp3" }, // ÿû, mp3 without ID3 header
|
||||
{{ 'I', 'D', '3' }, "mp3" }, // mp3 with ID3 header
|
||||
{{ 'O', 'g', 'g', 'S' }, "ogg_or_vorbis" }, // see `match_ogg_subtype`
|
||||
{{ 'f', 'L', 'a', 'C' }, "flac" },
|
||||
{{ 0x52, 0x49, 0x46, 0x46, -0x1, -0x1, -0x1, -0x1, 0x57, 0x41, 0x56, 0x45 }, "wav" } // RIFF....WAVE
|
||||
};
|
||||
|
||||
auto match_magic = [](const uint8_t * data, const std::vector<int16_t> & magic)
|
||||
{
|
||||
for (int i = 0; i < magic.size(); ++i)
|
||||
{
|
||||
if (magic[i] != data[i] && magic[i] != -0x1) // -0x1 skips things that don't contribute to the magic number
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
auto match_ogg_subtype = [](const uint8_t * data)
|
||||
{
|
||||
std::string header; // arbitrarily read the first 64 bytes as ascii characters
|
||||
for (int i = 0; i < 64; ++i) header += data[i];
|
||||
|
||||
std::size_t found_opus = header.find("OpusHead");
|
||||
if (found_opus != std::string::npos) return "opus";
|
||||
|
||||
std::size_t found_vorbis = header.find("vorbis");
|
||||
if (found_vorbis != std::string::npos) return "ogg";
|
||||
|
||||
return "none";
|
||||
};
|
||||
|
||||
std::string ext = "none";
|
||||
|
||||
for (auto & filetype : magic_map)
|
||||
{
|
||||
if (match_magic(buffer.data(), filetype.first))
|
||||
{
|
||||
ext = filetype.second;
|
||||
}
|
||||
|
||||
if (ext == "ogg_or_vorbis")
|
||||
{
|
||||
ext = match_ogg_subtype(buffer.data());
|
||||
}
|
||||
}
|
||||
|
||||
NyquistIO::Load(data, ext, buffer);
|
||||
}
|
||||
|
||||
void NyquistIO::Load(AudioData * data, const std::string & extension, const std::vector<uint8_t> & buffer)
|
||||
{
|
||||
if (decoderTable.find(extension) == decoderTable.end())
|
||||
{
|
||||
throw UnsupportedExtensionEx();
|
||||
}
|
||||
|
||||
if (decoderTable.size())
|
||||
{
|
||||
auto decoder = GetDecoderForExtension(extension);
|
||||
try
|
||||
{
|
||||
decoder->LoadFromBuffer(data, buffer);
|
||||
}
|
||||
catch (const std::exception & e)
|
||||
{
|
||||
std::cerr << "caught internal loading exception: " << e.what() << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else throw std::runtime_error("fatal: no decoders available");
|
||||
}
|
||||
|
||||
bool NyquistIO::IsFileSupported(const std::string & path) const
|
||||
{
|
||||
auto fileExtension = ParsePathForExtension(path);
|
||||
if (decoderTable.find(fileExtension) == decoderTable.end()) return false;
|
||||
else return true;
|
||||
}
|
||||
|
||||
std::string NyquistIO::ParsePathForExtension(const std::string & path) const
|
||||
{
|
||||
if (path.find_last_of(".") != std::string::npos) return path.substr(path.find_last_of(".") + 1);
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
std::shared_ptr<BaseDecoder> NyquistIO::GetDecoderForExtension(const std::string & ext)
|
||||
{
|
||||
if (decoderTable.size()) return decoderTable[ext];
|
||||
else throw std::runtime_error("No available decoders.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NyquistIO::AddDecoderToTable(std::shared_ptr<nqr::BaseDecoder> decoder)
|
||||
{
|
||||
auto supportedExtensions = decoder->GetSupportedFileExtensions();
|
||||
|
||||
for (const auto ext : supportedExtensions)
|
||||
{
|
||||
if (decoderTable.count(ext) >= 1) throw std::runtime_error("decoder already exists for extension");
|
||||
decoderTable.insert(DecoderPair(ext, decoder));
|
||||
}
|
||||
}
|
||||
|
||||
void NyquistIO::BuildDecoderTable()
|
||||
{
|
||||
AddDecoderToTable(std::make_shared<WavDecoder>());
|
||||
AddDecoderToTable(std::make_shared<WavPackDecoder>());
|
||||
AddDecoderToTable(std::make_shared<FlacDecoder>());
|
||||
AddDecoderToTable(std::make_shared<VorbisDecoder>());
|
||||
AddDecoderToTable(std::make_shared<OpusDecoder>());
|
||||
AddDecoderToTable(std::make_shared<MusepackDecoder>());
|
||||
AddDecoderToTable(std::make_shared<Mp3Decoder>());
|
||||
}
|
||||
|
||||
NyquistFileBuffer nqr::ReadFile(const std::string & pathToFile)
|
||||
{
|
||||
//std::cout << "[Debug] Open: " << pathToFile << std::endl;
|
||||
FILE * audioFile = fopen(pathToFile.c_str(), "rb");
|
||||
|
||||
if (!audioFile)
|
||||
{
|
||||
throw std::runtime_error("file not found");
|
||||
}
|
||||
|
||||
fseek(audioFile, 0, SEEK_END);
|
||||
size_t lengthInBytes = ftell(audioFile);
|
||||
fseek(audioFile, 0, SEEK_SET);
|
||||
|
||||
// Allocate temporary buffer
|
||||
std::vector<uint8_t> fileBuffer(lengthInBytes);
|
||||
|
||||
size_t elementsRead = fread(fileBuffer.data(), 1, lengthInBytes, audioFile);
|
||||
|
||||
if (elementsRead == 0 || fileBuffer.size() < 64)
|
||||
{
|
||||
throw std::runtime_error("error reading file or file too small");
|
||||
}
|
||||
|
||||
NyquistFileBuffer data = {std::move(fileBuffer), elementsRead};
|
||||
|
||||
fclose(audioFile);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
// Src data is aligned to PCMFormat
|
||||
// @todo normalize?
|
||||
void nqr::ConvertToFloat32(float * dst, const uint8_t * src, const size_t N, PCMFormat f)
|
||||
{
|
||||
assert(f != PCM_END);
|
||||
|
||||
if (f == PCM_U8)
|
||||
{
|
||||
const uint8_t * dataPtr = reinterpret_cast<const uint8_t *>(src);
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
dst[i] = uint8_to_float32(dataPtr[i]);
|
||||
}
|
||||
else if (f == PCM_S8)
|
||||
{
|
||||
const int8_t * dataPtr = reinterpret_cast<const int8_t *>(src);
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
dst[i] = int8_to_float32(dataPtr[i]);
|
||||
}
|
||||
else if (f == PCM_16)
|
||||
{
|
||||
const int16_t * dataPtr = reinterpret_cast<const int16_t *>(src);
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
dst[i] = int16_to_float32(Read16(dataPtr[i]));
|
||||
}
|
||||
else if (f == PCM_24)
|
||||
{
|
||||
const uint8_t * dataPtr = reinterpret_cast<const uint8_t *>(src);
|
||||
size_t c = 0;
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
{
|
||||
int32_t sample = Pack(dataPtr[c], dataPtr[c+1], dataPtr[c+2]);
|
||||
dst[i] = int24_to_float32(sample); // Packed types don't need addtional endian helpers
|
||||
c += 3;
|
||||
}
|
||||
}
|
||||
else if (f == PCM_32)
|
||||
{
|
||||
const int32_t * dataPtr = reinterpret_cast<const int32_t *>(src);
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
dst[i] = int32_to_float32(Read32(dataPtr[i]));
|
||||
}
|
||||
|
||||
//@todo add int64 format
|
||||
|
||||
else if (f == PCM_FLT)
|
||||
{
|
||||
std::memcpy(dst, src, N * sizeof(float));
|
||||
/* const float * dataPtr = reinterpret_cast<const float *>(src);
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
dst[i] = (float) Read32(dataPtr[i]); */
|
||||
}
|
||||
else if (f == PCM_DBL)
|
||||
{
|
||||
const double * dataPtr = reinterpret_cast<const double *>(src);
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
dst[i] = (float) Read64(dataPtr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Src data is always aligned to 4 bytes (WavPack, primarily)
|
||||
void nqr::ConvertToFloat32(float * dst, const int32_t * src, const size_t N, PCMFormat f)
|
||||
{
|
||||
assert(f != PCM_END);
|
||||
|
||||
if (f == PCM_16)
|
||||
{
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
dst[i] = int16_to_float32(Read32(src[i]));
|
||||
}
|
||||
else if (f == PCM_24)
|
||||
{
|
||||
const uint8_t * dataPtr = reinterpret_cast<const uint8_t *>(src);
|
||||
size_t c = 0;
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
{
|
||||
int32_t sample = Pack(dataPtr[c], dataPtr[c+1], dataPtr[c+2]);
|
||||
dst[i] = int24_to_float32(sample);
|
||||
c += 4; // +4 for next 4 byte boundary
|
||||
}
|
||||
}
|
||||
else if (f == PCM_32)
|
||||
{
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
dst[i] = int32_to_float32(Read32(src[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void nqr::ConvertToFloat32(float * dst, const int16_t * src, const size_t N, PCMFormat f)
|
||||
{
|
||||
assert(f != PCM_END);
|
||||
if (f == PCM_16)
|
||||
{
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
dst[i] = int16_to_float32(Read16(src[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void nqr::ConvertFromFloat32(uint8_t * dst, const float * src, const size_t N, PCMFormat f, DitherType t)
|
||||
{
|
||||
assert(f != PCM_END);
|
||||
|
||||
Dither dither(t);
|
||||
|
||||
if (f == PCM_U8)
|
||||
{
|
||||
uint8_t * destPtr = reinterpret_cast<uint8_t *>(dst);
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
destPtr[i] = (uint8_t) dither(lroundf(float32_to_uint8(src[i])));
|
||||
}
|
||||
else if (f == PCM_S8)
|
||||
{
|
||||
int8_t * destPtr = reinterpret_cast<int8_t *>(dst);
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
destPtr[i] = (int8_t) dither(lroundf(float32_to_int8(src[i])));
|
||||
}
|
||||
else if (f == PCM_16)
|
||||
{
|
||||
int16_t * destPtr = reinterpret_cast<int16_t *>(dst);
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
destPtr[i] =(int16_t) dither(lroundf(float32_to_int16(src[i])));
|
||||
}
|
||||
else if (f == PCM_24)
|
||||
{
|
||||
uint8_t * destPtr = reinterpret_cast<uint8_t *>(dst);
|
||||
size_t c = 0;
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
{
|
||||
int32_t sample = (int32_t) dither(lroundf(float32_to_int24(src[i])));
|
||||
auto unpacked = Unpack(sample); // Handles endian swap
|
||||
destPtr[c] = unpacked[0];
|
||||
destPtr[c+1] = unpacked[1];
|
||||
destPtr[c+2] = unpacked[2];
|
||||
c += 3;
|
||||
}
|
||||
}
|
||||
else if (f == PCM_32)
|
||||
{
|
||||
int32_t * destPtr = reinterpret_cast<int32_t *>(dst);
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
destPtr[i] = (int32_t) dither(lroundf(float32_to_int32(src[i])));
|
||||
}
|
||||
}
|
||||
|
||||
int nqr::GetFormatBitsPerSample(PCMFormat f)
|
||||
{
|
||||
switch(f)
|
||||
{
|
||||
case PCM_U8:
|
||||
case PCM_S8:
|
||||
return 8;
|
||||
case PCM_16:
|
||||
return 16;
|
||||
case PCM_24:
|
||||
return 24;
|
||||
case PCM_32:
|
||||
case PCM_FLT:
|
||||
return 32;
|
||||
case PCM_64:
|
||||
case PCM_DBL:
|
||||
return 64;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PCMFormat nqr::MakeFormatForBits(int bits, bool floatingPt, bool isSigned)
|
||||
{
|
||||
switch(bits)
|
||||
{
|
||||
case 8: return (isSigned) ? PCM_S8 : PCM_U8;
|
||||
case 16: return PCM_16;
|
||||
case 24: return PCM_24;
|
||||
case 32: return (floatingPt) ? PCM_FLT : PCM_32;
|
||||
case 64: return (floatingPt) ? PCM_DBL : PCM_64;
|
||||
default: return PCM_END;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,442 @@
|
|||
/*
|
||||
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Encoders.h"
|
||||
#include <fstream>
|
||||
|
||||
using namespace nqr;
|
||||
|
||||
static inline void to_bytes(uint8_t value, char * arr)
|
||||
{
|
||||
arr[0] = (value) & 0xFF;
|
||||
}
|
||||
|
||||
static inline void to_bytes(uint16_t value, char * arr)
|
||||
{
|
||||
arr[0] = (value) & 0xFF;
|
||||
arr[1] = (value >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
static inline void to_bytes(uint32_t value, char * arr)
|
||||
{
|
||||
arr[0] = (value) & 0xFF;
|
||||
arr[1] = (value >> 8) & 0xFF;
|
||||
arr[2] = (value >> 16) & 0xFF;
|
||||
arr[3] = (value >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// Wave File Encoding //
|
||||
////////////////////////////
|
||||
|
||||
int nqr::encode_wav_to_disk(const EncoderParams p, const AudioData * d, const std::string & path)
|
||||
{
|
||||
if (!d->samples.size())
|
||||
return EncoderError::InsufficientSampleData;
|
||||
|
||||
// Cast away const because we know what we are doing (Hopefully?)
|
||||
float * sampleData = const_cast<float *>(d->samples.data());
|
||||
size_t sampleDataSize = d->samples.size();
|
||||
|
||||
std::vector<float> sampleDataOptionalMix;
|
||||
|
||||
if (sampleDataSize <= 32)
|
||||
{
|
||||
return EncoderError::InsufficientSampleData;
|
||||
}
|
||||
|
||||
if (d->channelCount < 1 || d->channelCount > 8)
|
||||
{
|
||||
return EncoderError::UnsupportedChannelConfiguration;
|
||||
}
|
||||
|
||||
// Handle Channel Mixing --
|
||||
|
||||
// Mono => Stereo
|
||||
if (d->channelCount == 1 && p.channelCount == 2)
|
||||
{
|
||||
sampleDataOptionalMix.resize(sampleDataSize * 2);
|
||||
MonoToStereo(sampleData, sampleDataOptionalMix.data(), sampleDataSize); // Mix
|
||||
|
||||
// Re-point data
|
||||
sampleData = sampleDataOptionalMix.data();
|
||||
sampleDataSize = sampleDataOptionalMix.size();
|
||||
}
|
||||
// Stereo => Mono
|
||||
else if (d->channelCount == 2 && p.channelCount == 1)
|
||||
{
|
||||
sampleDataOptionalMix.resize(sampleDataSize / 2);
|
||||
StereoToMono(sampleData, sampleDataOptionalMix.data(), sampleDataSize); // Mix
|
||||
|
||||
// Re-point data
|
||||
sampleData = sampleDataOptionalMix.data();
|
||||
sampleDataSize = sampleDataOptionalMix.size();
|
||||
}
|
||||
else if (d->channelCount == p.channelCount) { /* do nothing */ }
|
||||
else return EncoderError::UnsupportedChannelMix;
|
||||
|
||||
// -- End Channel Mixing
|
||||
|
||||
auto maxFileSizeInBytes = std::numeric_limits<uint32_t>::max();
|
||||
auto samplesSizeInBytes = (sampleDataSize * GetFormatBitsPerSample(p.targetFormat)) / 8;
|
||||
|
||||
// 64 arbitrary
|
||||
if ((samplesSizeInBytes - 64) >= maxFileSizeInBytes)
|
||||
{
|
||||
return EncoderError::BufferTooBig;
|
||||
}
|
||||
|
||||
// Don't support PC64 or PCDBL
|
||||
if (GetFormatBitsPerSample(p.targetFormat) > 32)
|
||||
{
|
||||
return EncoderError::UnsupportedBitdepth;
|
||||
}
|
||||
|
||||
std::ofstream fout(path.c_str(), std::ios::out | std::ios::binary);
|
||||
|
||||
if (!fout.is_open())
|
||||
{
|
||||
return EncoderError::FileIOError;
|
||||
}
|
||||
|
||||
char * chunkSizeBuff = new char[4];
|
||||
|
||||
// Initial size (this is changed after we're done writing the file)
|
||||
to_bytes(uint32_t(36), chunkSizeBuff);
|
||||
|
||||
// RIFF file header
|
||||
fout.write(GenerateChunkCodeChar('R', 'I', 'F', 'F'), 4);
|
||||
fout.write(chunkSizeBuff, 4);
|
||||
|
||||
fout.write(GenerateChunkCodeChar('W', 'A', 'V', 'E'), 4);
|
||||
|
||||
// Fmt header
|
||||
auto header = MakeWaveHeader(p, d->sampleRate);
|
||||
fout.write(reinterpret_cast<char*>(&header), sizeof(WaveChunkHeader));
|
||||
|
||||
auto sourceBits = GetFormatBitsPerSample(d->sourceFormat);
|
||||
auto targetBits = GetFormatBitsPerSample(p.targetFormat);
|
||||
|
||||
//@todo - channel mixing!
|
||||
|
||||
// Write out fact chunk
|
||||
if (p.targetFormat == PCM_FLT)
|
||||
{
|
||||
uint32_t four = 4;
|
||||
uint32_t dataSz = int(sampleDataSize / p.channelCount);
|
||||
fout.write(GenerateChunkCodeChar('f', 'a', 'c', 't'), 4);
|
||||
fout.write(reinterpret_cast<const char *>(&four), 4);
|
||||
fout.write(reinterpret_cast<const char *>(&dataSz), 4); // Number of samples (per channel)
|
||||
}
|
||||
|
||||
// Data header
|
||||
fout.write(GenerateChunkCodeChar('d', 'a', 't', 'a'), 4);
|
||||
|
||||
// + data chunk size
|
||||
to_bytes(uint32_t(samplesSizeInBytes), chunkSizeBuff);
|
||||
fout.write(chunkSizeBuff, 4);
|
||||
|
||||
if (targetBits <= sourceBits && p.targetFormat != PCM_FLT)
|
||||
{
|
||||
// At most need this number of bytes in our copy
|
||||
std::vector<uint8_t> samplesCopy(samplesSizeInBytes);
|
||||
ConvertFromFloat32(samplesCopy.data(), sampleData, sampleDataSize, p.targetFormat, p.dither);
|
||||
fout.write(reinterpret_cast<const char*>(samplesCopy.data()), samplesSizeInBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle PCFLT. Coming in from AudioData ensures we start with 32 bits, so we're fine
|
||||
// since we've also rejected formats with more than 32 bits above.
|
||||
fout.write(reinterpret_cast<const char*>(sampleData), samplesSizeInBytes);
|
||||
}
|
||||
|
||||
// Padding byte
|
||||
if (isOdd(samplesSizeInBytes))
|
||||
{
|
||||
const char * zero = "";
|
||||
fout.write(zero, 1);
|
||||
}
|
||||
|
||||
// Find size
|
||||
long totalSize = fout.tellp();
|
||||
|
||||
// Modify RIFF header
|
||||
fout.seekp(4);
|
||||
|
||||
// Total size of the file, less 8 bytes for the RIFF header
|
||||
to_bytes(uint32_t(totalSize - 8), chunkSizeBuff);
|
||||
|
||||
fout.write(chunkSizeBuff, 4);
|
||||
|
||||
delete[] chunkSizeBuff;
|
||||
|
||||
return EncoderError::NoError;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// Opus File Encoding //
|
||||
////////////////////////////
|
||||
|
||||
#include "opus/opusfile/include/opusfile.h"
|
||||
#include "ogg/ogg.h"
|
||||
|
||||
typedef std::pair<std::string, std::string> metadata_t;
|
||||
|
||||
class OggWriter
|
||||
{
|
||||
void write_to_ostream(bool flush)
|
||||
{
|
||||
while (ogg_stream_pageout(&oss, &page))
|
||||
{
|
||||
ostream->write(reinterpret_cast<char*>(page.header), static_cast<std::streamsize>(page.header_len));
|
||||
ostream->write(reinterpret_cast<char*>(page.body), static_cast<std::streamsize>(page.body_len));
|
||||
}
|
||||
if (flush && ogg_stream_flush(&oss, &page))
|
||||
{
|
||||
ostream->write(reinterpret_cast<char*>(page.header), static_cast<std::streamsize>(page.header_len));
|
||||
ostream->write(reinterpret_cast<char*>(page.body), static_cast<std::streamsize>(page.body_len));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<char> make_header(int channel_count, int preskip, long sample_rate, int gain)
|
||||
{
|
||||
std::vector<char> header;
|
||||
|
||||
std::array<char, 9> steam_count = { { 0x0, 0x1, 0x1, 0x2, 0x2, 0x3, 0x4, 0x5, 0x5 } };
|
||||
std::array<char, 9> coupled_streacount = { { 0x0, 0x0, 0x1, 0x1, 0x2, 0x2, 0x2, 0x2, 0x3 } };
|
||||
|
||||
std::array<char, 1> chan_map_1 = { { 0x0 } };
|
||||
std::array<char, 2> chan_map_2 = { { 0x0, 0x1 } };
|
||||
|
||||
std::array<char, 9> _preamble = { { 'O', 'p', 'u', 's', 'H', 'e', 'a', 'd', 0x1 } };
|
||||
std::array<char, 1> _channel_count;
|
||||
std::array<char, 2> _preskip;
|
||||
std::array<char, 4> _sample_rate;
|
||||
std::array<char, 2> _gain;
|
||||
std::array<char, 1> _channel_family = { { 0x1 } };
|
||||
|
||||
to_bytes(uint8_t(channel_count), _channel_count.data());
|
||||
to_bytes(uint16_t(preskip), _preskip.data());
|
||||
to_bytes(uint32_t(sample_rate), _sample_rate.data());
|
||||
to_bytes(uint16_t(gain), _gain.data());
|
||||
|
||||
header.insert(header.end(), _preamble.cbegin(), _preamble.cend());
|
||||
header.insert(header.end(), _channel_count.cbegin(), _channel_count.cend());
|
||||
header.insert(header.end(), _preskip.cbegin(), _preskip.cend());
|
||||
header.insert(header.end(), _sample_rate.cbegin(), _sample_rate.cend());
|
||||
header.insert(header.end(), _gain.cbegin(), _gain.cend());
|
||||
header.insert(header.end(), _channel_family.cbegin(), _channel_family.cend());
|
||||
header.push_back(steam_count[channel_count]);
|
||||
header.push_back(coupled_streacount[channel_count]);
|
||||
|
||||
switch (channel_count)
|
||||
{
|
||||
case 1: header.insert(header.end(), chan_map_1.cbegin(), chan_map_1.cend()); break;
|
||||
case 2: header.insert(header.end(), chan_map_2.cbegin(), chan_map_2.cend()); break;
|
||||
default: throw std::runtime_error("couldn't map channel data");
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
std::vector<char> make_tags(const std::string & vendor, const std::vector<metadata_t> & metadata)
|
||||
{
|
||||
std::vector<char> tags;
|
||||
|
||||
std::array<char, 8> _preamble = { { 'O', 'p', 'u', 's', 'T', 'a', 'g', 's' } };
|
||||
std::array<char, 4> _vendor_length;
|
||||
std::array<char, 4> _metadata_count;
|
||||
|
||||
to_bytes(uint32_t(vendor.size()), _vendor_length.data());
|
||||
to_bytes(uint32_t(metadata.size()), _metadata_count.data());
|
||||
|
||||
tags.insert(tags.end(), _preamble.cbegin(), _preamble.cend());
|
||||
tags.insert(tags.end(), _vendor_length.cbegin(), _vendor_length.cend());
|
||||
tags.insert(tags.end(), vendor.cbegin(), vendor.cend());
|
||||
tags.insert(tags.end(), _metadata_count.cbegin(), _metadata_count.cend());
|
||||
|
||||
// Process metadata.
|
||||
for (const auto & metadata_entry : metadata)
|
||||
{
|
||||
std::array<char, 4> _metadata_entry_length;
|
||||
std::string entry = metadata_entry.first + "=" + metadata_entry.second;
|
||||
to_bytes(uint32_t(entry.size()), _metadata_entry_length.data());
|
||||
tags.insert(tags.end(), _metadata_entry_length.cbegin(), _metadata_entry_length.cend());
|
||||
tags.insert(tags.end(), entry.cbegin(), entry.cend());
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
ogg_int64_t packet_number;
|
||||
ogg_int64_t granule;
|
||||
ogg_page page;
|
||||
ogg_stream_state oss;
|
||||
|
||||
int channel_count;
|
||||
long sample_rate;
|
||||
int bits_per_sample;
|
||||
std::ofstream * ostream;
|
||||
std::string description;
|
||||
std::vector<metadata_t> metadata;
|
||||
|
||||
public:
|
||||
|
||||
OggWriter(int channel_count, long sample_rate, int bits_per_sample, std::ofstream & stream, const std::vector<metadata_t> & md)
|
||||
{
|
||||
this->channel_count = channel_count;
|
||||
this->sample_rate = sample_rate;
|
||||
this->bits_per_sample = bits_per_sample;
|
||||
this->ostream = &stream;
|
||||
this->metadata = md;
|
||||
|
||||
int oggInitErr, packetErr;
|
||||
|
||||
ogg_packet header_packet;
|
||||
ogg_packet tags_packet;
|
||||
std::vector<char> header_vector;
|
||||
std::vector<char> tags_vector;
|
||||
|
||||
description = "Ogg";
|
||||
packet_number = 0;
|
||||
granule = 0;
|
||||
|
||||
// Validate parameters
|
||||
if (channel_count < 1 && channel_count > 255) throw std::runtime_error("Channel count must be between 1 and 255.");
|
||||
|
||||
// Initialize the Ogg stream.
|
||||
oggInitErr = ogg_stream_init(&oss, 12345);
|
||||
if (oggInitErr) throw std::runtime_error("Could not initialize the Ogg stream state.");
|
||||
|
||||
// Initialize the header packet.
|
||||
header_vector = make_header(channel_count, 3840, sample_rate, 0);
|
||||
header_packet.packet = reinterpret_cast<unsigned char*>(header_vector.data());
|
||||
header_packet.bytes = header_vector.size();
|
||||
header_packet.b_o_s = 1;
|
||||
header_packet.e_o_s = 0;
|
||||
header_packet.granulepos = 0;
|
||||
header_packet.packetno = packet_number++;
|
||||
|
||||
// Initialize tags
|
||||
tags_vector = make_tags("libnyquist", metadata);
|
||||
tags_packet.packet = reinterpret_cast<unsigned char*>(tags_vector.data());
|
||||
tags_packet.bytes = tags_vector.size();
|
||||
tags_packet.b_o_s = 0;
|
||||
tags_packet.e_o_s = 0;
|
||||
tags_packet.granulepos = 0;
|
||||
tags_packet.packetno = packet_number++;
|
||||
|
||||
// Write header page
|
||||
packetErr = ogg_stream_packetin(&oss, &header_packet);
|
||||
if (packetErr) throw std::runtime_error("Could not write header packet to the Ogg stream.");
|
||||
write_to_ostream(true);
|
||||
|
||||
// Write tags page
|
||||
packetErr = ogg_stream_packetin(&oss, &tags_packet);
|
||||
if (packetErr) throw std::runtime_error("Could not write tags packet to the Ogg stream.");
|
||||
write_to_ostream(true);
|
||||
}
|
||||
|
||||
~OggWriter()
|
||||
{
|
||||
write_to_ostream(true);
|
||||
ogg_stream_clear(&oss);
|
||||
}
|
||||
|
||||
bool write(char * data, std::streamsize length, size_t sampleCount, bool end)
|
||||
{
|
||||
int err;
|
||||
ogg_packet packet;
|
||||
|
||||
granule += sampleCount;
|
||||
|
||||
packet.packet = reinterpret_cast<unsigned char*>(data);
|
||||
packet.bytes = static_cast<long>(length);
|
||||
packet.b_o_s = 0;
|
||||
packet.e_o_s = end ? 1 : 0;
|
||||
packet.granulepos = granule;
|
||||
packet.packetno = packet_number++;
|
||||
|
||||
err = ogg_stream_packetin(&oss, &packet);
|
||||
|
||||
if (err) throw std::runtime_error("could not write packet to stream");
|
||||
|
||||
write_to_ostream(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#define OPUS_MAX_PACKET_SIZE (1024 * 8)
|
||||
#define OPUS_FRAME_SIZE 960
|
||||
|
||||
// Opus only supports a 48k samplerate...
|
||||
// This encoder only supports mono for the time being
|
||||
int nqr::encode_opus_to_disk(const EncoderParams p, const AudioData * d, const std::string & path)
|
||||
{
|
||||
assert(d->samples.size() > 0);
|
||||
//assert(d->sampleRate == 48000);
|
||||
|
||||
float * sampleData = const_cast<float *>(d->samples.data());
|
||||
const size_t sampleDataSize = d->samples.size();
|
||||
|
||||
int opus_error;
|
||||
OpusEncoder * enc;
|
||||
enc = opus_encoder_create(48000, 1, OPUS_APPLICATION_AUDIO, &opus_error);
|
||||
if (!enc) throw std::runtime_error("opus_encoder_create caused an error!");
|
||||
|
||||
std::ofstream fout(path.c_str(), std::ios::out | std::ios::binary);
|
||||
|
||||
std::vector<metadata_t> oggMetadata = { { "artist", "dimitri" } };
|
||||
OggWriter writer(d->channelCount, d->sampleRate, GetFormatBitsPerSample(d->sourceFormat), fout, oggMetadata);
|
||||
|
||||
std::vector<uint8_t> outBuffer(OPUS_MAX_PACKET_SIZE);
|
||||
|
||||
int framesToEncode = (sampleDataSize / OPUS_FRAME_SIZE) - 1; // fixme
|
||||
|
||||
while (framesToEncode >= 0)
|
||||
{
|
||||
auto encoded_size = opus_encode_float(enc, sampleData, OPUS_FRAME_SIZE, outBuffer.data(), OPUS_MAX_PACKET_SIZE);
|
||||
|
||||
if (encoded_size < 0)
|
||||
{
|
||||
std::cerr << "Bad Opus Status: " << encoded_size << std::endl;
|
||||
return EncoderError::FileIOError;
|
||||
}
|
||||
|
||||
writer.write((char*)outBuffer.data(), encoded_size, OPUS_FRAME_SIZE, (framesToEncode == 0) ? true : false);
|
||||
|
||||
framesToEncode--;
|
||||
sampleData += OPUS_FRAME_SIZE;
|
||||
}
|
||||
|
||||
fout.close();
|
||||
|
||||
opus_encoder_destroy(enc);
|
||||
|
||||
return EncoderError::NoError;
|
||||
}
|
||||
|
||||
#undef OPUS_MAX_PACKET_SIZE
|
||||
|
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Decoders.h"
|
||||
|
||||
// http://lists.xiph.org/pipermail/flac-dev/2012-March/003276.html
|
||||
#define FLAC__NO_DLL
|
||||
|
||||
#include "FLAC/all.h"
|
||||
#include "FLAC/stream_decoder.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace nqr;
|
||||
|
||||
// FLAC is a big-endian format. All values are unsigned.
|
||||
class FlacDecoderInternal
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
FlacDecoderInternal(AudioData * d, const std::string & filepath) : d(d)
|
||||
{
|
||||
decoderInternal = FLAC__stream_decoder_new();
|
||||
|
||||
FLAC__stream_decoder_set_metadata_respond(decoderInternal, FLAC__METADATA_TYPE_STREAMINFO);
|
||||
|
||||
//@todo: check if OGG flac
|
||||
bool initialized = FLAC__stream_decoder_init_file(decoderInternal,
|
||||
filepath.c_str(),
|
||||
s_writeCallback,
|
||||
s_metadataCallback,
|
||||
s_errorCallback,
|
||||
this) == FLAC__STREAM_DECODER_INIT_STATUS_OK;
|
||||
|
||||
FLAC__stream_decoder_set_md5_checking(decoderInternal, true);
|
||||
|
||||
if (initialized)
|
||||
{
|
||||
// Find the size and allocate memory
|
||||
FLAC__stream_decoder_process_until_end_of_metadata(decoderInternal);
|
||||
|
||||
// Read memory out into our temporary internalBuffer
|
||||
FLAC__stream_decoder_process_until_end_of_stream(decoderInternal);
|
||||
|
||||
// Presently unneeded, but useful for reference
|
||||
// FLAC__ChannelAssignment channelAssignment = FLAC__stream_decoder_get_channel_assignment(decoderInternal);
|
||||
|
||||
// Fill out remaining user data
|
||||
d->lengthSeconds = (float) numSamples / (float) d->sampleRate;
|
||||
|
||||
auto totalSamples = numSamples * d->channelCount;
|
||||
|
||||
// Next, process internal buffer into the user-visible samples array
|
||||
ConvertToFloat32(d->samples.data(), internalBuffer.data(), totalSamples, d->sourceFormat);
|
||||
}
|
||||
else throw std::runtime_error("Unable to initialize FLAC decoder");
|
||||
}
|
||||
|
||||
FlacDecoderInternal(AudioData * d, const std::vector<uint8_t> & memory) : d(d), data(std::move(memory)), dataPos(0)
|
||||
{
|
||||
decoderInternal = FLAC__stream_decoder_new();
|
||||
|
||||
FLAC__stream_decoder_set_metadata_respond(decoderInternal, FLAC__METADATA_TYPE_STREAMINFO);
|
||||
|
||||
bool initialized = FLAC__stream_decoder_init_stream(
|
||||
decoderInternal,
|
||||
read_callback,
|
||||
seek_callback,
|
||||
tell_callback,
|
||||
length_callback,
|
||||
eof_callback,
|
||||
s_writeCallback,
|
||||
s_metadataCallback,
|
||||
s_errorCallback,
|
||||
this
|
||||
) == FLAC__STREAM_DECODER_INIT_STATUS_OK;
|
||||
|
||||
FLAC__stream_decoder_set_md5_checking(decoderInternal, true);
|
||||
|
||||
if (initialized)
|
||||
{
|
||||
// Find the size and allocate memory
|
||||
FLAC__stream_decoder_process_until_end_of_metadata(decoderInternal);
|
||||
|
||||
// Read memory out into our temporary internalBuffer
|
||||
FLAC__stream_decoder_process_until_end_of_stream(decoderInternal);
|
||||
|
||||
// Presently unneeded, but useful for reference
|
||||
// FLAC__ChannelAssignment channelAssignment = FLAC__stream_decoder_get_channel_assignment(decoderInternal);
|
||||
|
||||
// Fill out remaining user data
|
||||
d->lengthSeconds = (float) numSamples / (float) d->sampleRate;
|
||||
|
||||
auto totalSamples = numSamples * d->channelCount;
|
||||
|
||||
// Next, process internal buffer into the user-visible samples array
|
||||
ConvertToFloat32(d->samples.data(), internalBuffer.data(), totalSamples, d->sourceFormat);
|
||||
}
|
||||
else throw std::runtime_error("Unable to initialize FLAC decoder");
|
||||
}
|
||||
|
||||
~FlacDecoderInternal()
|
||||
{
|
||||
if (decoderInternal)
|
||||
{
|
||||
FLAC__stream_decoder_finish(decoderInternal);
|
||||
FLAC__stream_decoder_delete(decoderInternal);
|
||||
}
|
||||
}
|
||||
|
||||
void processMetadata(const FLAC__StreamMetadata_StreamInfo & info)
|
||||
{
|
||||
// Currently the reference encoder and decoders only support up to 24 bits per sample.
|
||||
d->sampleRate = info.sample_rate;
|
||||
d->channelCount = info.channels; // Assert 1 to 8
|
||||
d->sourceFormat = MakeFormatForBits(info.bits_per_sample, false, true);
|
||||
d->frameSize = info.channels * info.bits_per_sample;
|
||||
|
||||
const size_t bytesPerSample = GetFormatBitsPerSample(d->sourceFormat) / 8;
|
||||
|
||||
numSamples = (size_t) info.total_samples;
|
||||
|
||||
internalBuffer.resize(numSamples * info.channels * bytesPerSample); // as array of bytes
|
||||
d->samples.resize(numSamples * info.channels); // as audio samples in float32
|
||||
}
|
||||
|
||||
///////////////////////
|
||||
// libflac callbacks //
|
||||
///////////////////////
|
||||
|
||||
static FLAC__StreamDecoderWriteStatus s_writeCallback(const FLAC__StreamDecoder *, const FLAC__Frame* frame, const FLAC__int32 * const buffer[], void * userPtr)
|
||||
{
|
||||
FlacDecoderInternal * decoder = reinterpret_cast<FlacDecoderInternal *>(userPtr);
|
||||
const size_t bytesPerSample = GetFormatBitsPerSample(decoder->d->sourceFormat) / 8;
|
||||
auto dataPtr = decoder->internalBuffer.data();
|
||||
|
||||
for (uint32_t i = 0; i < frame->header.blocksize; i++)
|
||||
{
|
||||
for (int j = 0; j < decoder->d->channelCount; j++)
|
||||
{
|
||||
std::memcpy(dataPtr + decoder->bufferPosition, &buffer[j][i], bytesPerSample);
|
||||
decoder->bufferPosition += bytesPerSample;
|
||||
}
|
||||
}
|
||||
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
static void s_metadataCallback (const FLAC__StreamDecoder *, const FLAC__StreamMetadata * metadata, void * userPtr)
|
||||
{
|
||||
static_cast<FlacDecoderInternal*>(userPtr)->processMetadata(metadata->data.stream_info);
|
||||
}
|
||||
|
||||
static void s_errorCallback (const FLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus status, void *)
|
||||
{
|
||||
throw std::runtime_error("FLAC decode exception " + std::string(FLAC__StreamDecoderErrorStatusString[status]));
|
||||
}
|
||||
|
||||
static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
|
||||
{
|
||||
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
|
||||
size_t readLength = std::min<size_t>(*bytes, decoderInternal->data.size() - decoderInternal->dataPos);
|
||||
|
||||
if (readLength > 0)
|
||||
{
|
||||
std::memcpy(buffer, decoderInternal->data.data(), readLength);
|
||||
decoderInternal->dataPos += readLength;
|
||||
*bytes = readLength;
|
||||
if (decoderInternal->dataPos < decoderInternal->data.size()) return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
|
||||
else return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
||||
}
|
||||
else return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
||||
}
|
||||
|
||||
static FLAC__StreamDecoderSeekStatus seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
|
||||
{
|
||||
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
|
||||
size_t newPos = std::min<size_t>(absolute_byte_offset, decoderInternal->data.size() - decoderInternal->dataPos);
|
||||
decoderInternal->dataPos = newPos;
|
||||
return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
|
||||
}
|
||||
|
||||
static FLAC__StreamDecoderTellStatus tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
|
||||
{
|
||||
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
|
||||
*absolute_byte_offset = decoderInternal->dataPos;
|
||||
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
|
||||
}
|
||||
|
||||
static FLAC__StreamDecoderLengthStatus length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
|
||||
{
|
||||
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
|
||||
*stream_length = decoderInternal->data.size();
|
||||
return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
|
||||
}
|
||||
|
||||
static FLAC__bool eof_callback(const FLAC__StreamDecoder *decoder, void *client_data)
|
||||
{
|
||||
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
|
||||
return decoderInternal->dataPos == decoderInternal->data.size();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
NO_COPY(FlacDecoderInternal);
|
||||
|
||||
FLAC__StreamDecoder * decoderInternal;
|
||||
std::vector<uint8_t> data;
|
||||
size_t dataPos;
|
||||
size_t bufferPosition = 0;
|
||||
size_t numSamples = 0;
|
||||
|
||||
AudioData * d;
|
||||
|
||||
std::vector<uint8_t> internalBuffer;
|
||||
};
|
||||
|
||||
//////////////////////
|
||||
// Public Interface //
|
||||
//////////////////////
|
||||
|
||||
void FlacDecoder::LoadFromPath(AudioData * data, const std::string & path)
|
||||
{
|
||||
FlacDecoderInternal decoder(data, path);
|
||||
}
|
||||
|
||||
void FlacDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
|
||||
{
|
||||
FlacDecoderInternal decoder(data, memory);
|
||||
}
|
||||
|
||||
std::vector<std::string> FlacDecoder::GetSupportedFileExtensions()
|
||||
{
|
||||
return {"flac"};
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#undef VERSION
|
||||
#define VERSION "1.3.1"
|
||||
|
||||
#define FLAC__NO_DLL 1
|
||||
#define FLAC__USE_VISIBILITY_ATTR 1
|
||||
|
||||
#if (_MSC_VER)
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 181 111 4267 4996 4244 4701 4702 4133 4100 4127 4206 4312 4505 4365 4005 4013 4334)
|
||||
#ifndef _WIN32
|
||||
#define _WIN32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
#define FLAC__SYS_DARWIN 1
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX (size_t) (-1)
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshadow"
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-register"
|
||||
#endif
|
||||
|
||||
#if CPU_X86
|
||||
#ifdef __i386__
|
||||
#define FLAC__CPU_IA32 1
|
||||
#endif
|
||||
#ifdef __x86_64__
|
||||
#define FLAC__CPU_X86_64 1
|
||||
#endif
|
||||
#define FLAC__HAS_X86INTRIN 1
|
||||
#endif
|
||||
|
||||
// Ensure libflac can use non-standard <stdint> types
|
||||
#undef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS 1
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
#define flac_max(a,b) ((a) > (b) ? a : b)
|
||||
#define flac_min(a,b) ((a) < (b) ? a : b)
|
||||
#elif defined(_MSC_VER)
|
||||
#include <stdlib.h>
|
||||
#define flac_max(a,b) __max(a,b)
|
||||
#define flac_min(a,b) __min(a,b)
|
||||
#endif
|
||||
|
||||
#define HAVE_LROUND 1
|
||||
|
||||
#include "FLAC/all.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include "FLAC/src/win_utf8_io.c"
|
||||
#endif
|
||||
|
||||
#include "FLAC/src/bitmath.c"
|
||||
#include "FLAC/src/bitreader.c"
|
||||
#include "FLAC/src/bitwriter.c"
|
||||
#include "FLAC/src/cpu.c"
|
||||
#include "FLAC/src/crc.c"
|
||||
#include "FLAC/src/fixed.c"
|
||||
#include "FLAC/src/float.c"
|
||||
#include "FLAC/src/format.c"
|
||||
#include "FLAC/src/lpc.c"
|
||||
#include "FLAC/src/md5.c"
|
||||
#include "FLAC/src/memory.c"
|
||||
#include "FLAC/src/stream_decoder.c"
|
||||
#include "FLAC/src/window.c"
|
||||
|
||||
#undef VERSION
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if (_MSC_VER)
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Decoders.h"
|
||||
|
||||
using namespace nqr;
|
||||
|
||||
#include "mpc/mpcdec.h"
|
||||
#include "mpc/reader.h"
|
||||
#include "musepack/libmpcdec/decoder.h"
|
||||
#include "musepack/libmpcdec/internal.h"
|
||||
|
||||
#define MINIMP3_FLOAT_OUTPUT
|
||||
#define MINIMP3_IMPLEMENTATION
|
||||
#include "minimp3/minimp3.h"
|
||||
#include "minimp3/minimp3_ex.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
void mp3_decode_internal(AudioData * d, const std::vector<uint8_t> & fileData)
|
||||
{
|
||||
mp3dec_t mp3d;
|
||||
mp3dec_file_info_t info;
|
||||
mp3dec_load_buf(&mp3d, (const uint8_t*)fileData.data(), fileData.size(), &info, 0, 0);
|
||||
|
||||
d->sampleRate = info.hz;
|
||||
d->channelCount = info.channels;
|
||||
d->sourceFormat = MakeFormatForBits(32, true, false);
|
||||
d->lengthSeconds = ((float)info.samples / (float)d->channelCount) / (float)d->sampleRate;
|
||||
|
||||
if (info.samples == 0) throw std::runtime_error("mp3: could not read any data");
|
||||
|
||||
d->samples.resize(info.samples);
|
||||
std::memcpy(d->samples.data(), info.buffer, sizeof(float) * info.samples);
|
||||
|
||||
delete info.buffer;
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
// Public Interface //
|
||||
//////////////////////
|
||||
|
||||
void Mp3Decoder::LoadFromPath(AudioData * data, const std::string & path)
|
||||
{
|
||||
auto fileBuffer = nqr::ReadFile(path);
|
||||
mp3_decode_internal(data, fileBuffer.buffer);
|
||||
}
|
||||
|
||||
void Mp3Decoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
|
||||
{
|
||||
mp3_decode_internal(data, memory);
|
||||
}
|
||||
|
||||
std::vector<std::string> Mp3Decoder::GetSupportedFileExtensions()
|
||||
{
|
||||
return {"mp3"};
|
||||
}
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Decoders.h"
|
||||
|
||||
using namespace nqr;
|
||||
|
||||
#include "mpc/mpcdec.h"
|
||||
#include "mpc/reader.h"
|
||||
#include "musepack/libmpcdec/decoder.h"
|
||||
#include "musepack/libmpcdec/internal.h"
|
||||
|
||||
class MusepackInternal
|
||||
{
|
||||
|
||||
static const uint32_t STDIO_MAGIC = 0xF36D656D;
|
||||
|
||||
// Methods borrowed from r-lyeh (https://github.com/r-lyeh) (zlib)
|
||||
struct mpc_reader_state
|
||||
{
|
||||
unsigned char *p_file;
|
||||
unsigned char *p_begin, *p_end;
|
||||
mpc_bool_t is_seekable;
|
||||
mpc_int32_t magic;
|
||||
};
|
||||
|
||||
static mpc_int32_t read_mem(mpc_reader *p_reader, void *ptr, mpc_int32_t size)
|
||||
{
|
||||
mpc_reader_state *p_mem = (mpc_reader_state*) p_reader->data;
|
||||
if (p_mem->magic != STDIO_MAGIC) return MPC_STATUS_FAIL;
|
||||
mpc_int32_t max = mpc_int32_t(p_mem->p_end - p_mem->p_file);
|
||||
if (size >= max) size = max;
|
||||
memcpy((unsigned char *)ptr, p_mem->p_file, size);
|
||||
p_mem->p_file += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
static mpc_bool_t seek_mem(mpc_reader *p_reader, mpc_int32_t offset)
|
||||
{
|
||||
mpc_reader_state *p_mem = (mpc_reader_state*) p_reader->data;
|
||||
if (p_mem->magic != STDIO_MAGIC) return MPC_FALSE;
|
||||
if (!p_mem->is_seekable) return MPC_FALSE;
|
||||
p_mem->p_file = p_mem->p_begin + offset;
|
||||
if(p_mem->p_file < p_mem->p_begin) return MPC_FALSE;
|
||||
if(p_mem->p_file >= p_mem->p_end ) return MPC_FALSE;
|
||||
return MPC_TRUE;
|
||||
}
|
||||
|
||||
static mpc_int32_t tell_mem(mpc_reader *p_reader)
|
||||
{
|
||||
mpc_reader_state *p_mem = (mpc_reader_state*) p_reader->data;
|
||||
if(p_mem->magic != STDIO_MAGIC) return MPC_STATUS_FAIL;
|
||||
return mpc_int32_t(p_mem->p_file - p_mem->p_begin);
|
||||
}
|
||||
|
||||
static mpc_int32_t get_size_mem(mpc_reader *p_reader)
|
||||
{
|
||||
mpc_reader_state *p_mem = (mpc_reader_state*) p_reader->data;
|
||||
if (p_mem->magic != STDIO_MAGIC) return MPC_STATUS_FAIL;
|
||||
return mpc_int32_t(p_mem->p_end - p_mem->p_begin);
|
||||
}
|
||||
|
||||
static mpc_bool_t canseek_mem(mpc_reader *p_reader)
|
||||
{
|
||||
mpc_reader_state *p_mem = (mpc_reader_state*) p_reader->data;
|
||||
if (p_mem->magic != STDIO_MAGIC) return MPC_FALSE;
|
||||
return p_mem->is_seekable;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// Musepack is a purely variable bitrate format and does not work at a constant bitrate.
|
||||
MusepackInternal(AudioData * d, const std::vector<uint8_t> & fileData) : d(d)
|
||||
{
|
||||
decoderMemory = std::make_shared<mpc_reader_state>();
|
||||
|
||||
decoderMemory->magic = STDIO_MAGIC;
|
||||
decoderMemory->p_file = (unsigned char *) fileData.data();
|
||||
decoderMemory->p_begin = (unsigned char *) fileData.data();
|
||||
decoderMemory->p_end = (unsigned char *) fileData.data() + fileData.size();
|
||||
decoderMemory->is_seekable = MPC_TRUE;
|
||||
|
||||
reader.data = decoderMemory.get();
|
||||
reader.canseek = canseek_mem;
|
||||
reader.get_size = get_size_mem;
|
||||
reader.read = read_mem;
|
||||
reader.seek = seek_mem;
|
||||
reader.tell = tell_mem;
|
||||
|
||||
mpcDemux = mpc_demux_init(&reader);
|
||||
if (!mpcDemux) throw std::runtime_error("could not initialize mpc demuxer");
|
||||
|
||||
mpc_demux_get_info(mpcDemux, &streamInfo);
|
||||
|
||||
d->sampleRate = (int) streamInfo.sample_freq;
|
||||
d->channelCount = streamInfo.channels;
|
||||
d->sourceFormat = MakeFormatForBits(32, true, false);
|
||||
d->lengthSeconds = (double) mpc_streaminfo_get_length(&streamInfo);
|
||||
|
||||
auto totalSamples = size_t(mpc_streaminfo_get_length_samples(&streamInfo));
|
||||
d->samples.reserve(totalSamples * d->channelCount + (MPC_DECODER_BUFFER_LENGTH / sizeof(MPC_SAMPLE_FORMAT))); // demux writes in chunks
|
||||
d->samples.resize(totalSamples * d->channelCount);
|
||||
|
||||
if (!readInternal())
|
||||
throw std::runtime_error("could not read any data");
|
||||
}
|
||||
|
||||
size_t readInternal()
|
||||
{
|
||||
mpc_status err = MPC_STATUS_OK;
|
||||
size_t totalSamplesRead = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
mpc_frame_info frame;
|
||||
frame.buffer = d->samples.data() + totalSamplesRead;
|
||||
|
||||
err = mpc_demux_decode(mpcDemux, &frame);
|
||||
if (frame.bits == -1 || err != MPC_STATUS_OK) break;
|
||||
|
||||
totalSamplesRead += (frame.samples * streamInfo.channels);
|
||||
}
|
||||
|
||||
if (err != MPC_STATUS_OK)
|
||||
std::cerr << "An internal error occured in mpc_demux_decode" << std::endl;
|
||||
|
||||
return totalSamplesRead;
|
||||
}
|
||||
|
||||
~MusepackInternal()
|
||||
{
|
||||
if (mpcDemux) mpc_demux_exit(mpcDemux);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
mpc_streaminfo streamInfo;
|
||||
mpc_reader_t reader;
|
||||
mpc_decoder decoder;
|
||||
mpc_demux * mpcDemux;
|
||||
|
||||
std::shared_ptr<mpc_reader_state> decoderMemory;
|
||||
|
||||
NO_MOVE(MusepackInternal);
|
||||
|
||||
AudioData * d;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////
|
||||
// Public Interface //
|
||||
//////////////////////
|
||||
|
||||
void MusepackDecoder::LoadFromPath(AudioData * data, const std::string & path)
|
||||
{
|
||||
auto fileBuffer = nqr::ReadFile(path);
|
||||
MusepackInternal decoder(data, fileBuffer.buffer);
|
||||
}
|
||||
|
||||
void MusepackDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
|
||||
{
|
||||
MusepackInternal decoder(data, memory);
|
||||
}
|
||||
|
||||
std::vector<std::string> MusepackDecoder::GetSupportedFileExtensions()
|
||||
{
|
||||
return {"mpc", "mpp"};
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if (_MSC_VER)
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 181 111 4267 4996 4244 4701 4702 4133 4100 4127 4206 4312 4505 4365 4005 4013 4334)
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshadow"
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-register"
|
||||
#endif
|
||||
|
||||
#include "musepack/libmpcdec/huffman.c"
|
||||
#include "musepack/libmpcdec/requant.c"
|
||||
#include "musepack/libmpcdec/streaminfo.c"
|
||||
#include "musepack/libmpcdec/synth_filter.c"
|
||||
#include "musepack/libmpcdec/crc32.c"
|
||||
#include "musepack/libmpcdec/mpc_reader.c"
|
||||
#include "musepack/libmpcdec/mpc_decoder.c"
|
||||
#include "musepack/libmpcdec/mpc_demux.c"
|
||||
#include "musepack/libmpcdec/mpc_bits_reader.c"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if (_MSC_VER)
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Decoders.h"
|
||||
#include "opus/opusfile/include/opusfile.h"
|
||||
|
||||
using namespace nqr;
|
||||
|
||||
static const int OPUS_SAMPLE_RATE = 48000;
|
||||
|
||||
// Opus is a general-purpose codec designed to replace Vorbis at some point. Primarily, it's a low
|
||||
// delay format making it suitable for high-quality, real time streaming. It's not really
|
||||
// an archival format or something designed for heavy DSP post-processing since
|
||||
// it's fundamentally limited to encode/decode at 48khz.
|
||||
// https://mf4.xiph.org/jenkins/view/opus/job/opusfile-unix/ws/doc/html/index.html
|
||||
|
||||
class OpusDecoderInternal
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
OpusDecoderInternal(AudioData * d, const std::vector<uint8_t> & fileData) : d(d)
|
||||
{
|
||||
/* @todo proper steaming support + classes
|
||||
const opus_callbacks = {
|
||||
.read = s_readCallback,
|
||||
.seek = s_seekCallback,
|
||||
.tell = s_tellCallback,
|
||||
.close = nullptr
|
||||
};
|
||||
*/
|
||||
|
||||
int err;
|
||||
|
||||
fileHandle = op_test_memory(fileData.data(), fileData.size(), &err);
|
||||
|
||||
if (!fileHandle)
|
||||
{
|
||||
std::cerr << errorAsString(err) << std::endl;
|
||||
throw std::runtime_error("File is not a valid ogg vorbis file");
|
||||
}
|
||||
|
||||
if (auto r = op_test_open(fileHandle) != 0)
|
||||
{
|
||||
std::cerr << errorAsString(r) << std::endl;
|
||||
throw std::runtime_error("Could not open file");
|
||||
}
|
||||
|
||||
const OpusHead * header = op_head(fileHandle, 0);
|
||||
|
||||
// int originalSampleRate = header->input_sample_rate;
|
||||
|
||||
d->sampleRate = OPUS_SAMPLE_RATE;
|
||||
d->channelCount = (uint32_t) header->channel_count;
|
||||
d->sourceFormat = MakeFormatForBits(32, true, false);
|
||||
d->lengthSeconds = double(getLengthInSeconds());
|
||||
d->frameSize = (uint32_t) header->channel_count * GetFormatBitsPerSample(d->sourceFormat);
|
||||
|
||||
// Samples in a single channel
|
||||
auto totalSamples = size_t(getTotalSamples());
|
||||
|
||||
d->samples.resize(totalSamples * d->channelCount);
|
||||
|
||||
if (!readInternal(totalSamples))
|
||||
throw std::runtime_error("could not read any data");
|
||||
}
|
||||
|
||||
~OpusDecoderInternal()
|
||||
{
|
||||
op_free(fileHandle);
|
||||
}
|
||||
|
||||
size_t readInternal(size_t requestedFrameCount, size_t frameOffset = 0)
|
||||
{
|
||||
float * buffer = (float *) d->samples.data();
|
||||
size_t framesRemaining = requestedFrameCount;
|
||||
size_t totalFramesRead = 0;
|
||||
|
||||
while(0 < framesRemaining)
|
||||
{
|
||||
int framesRead = op_read_float(fileHandle, buffer, (int)(framesRemaining * d->channelCount), nullptr);
|
||||
|
||||
// EOF
|
||||
if(!framesRead)
|
||||
break;
|
||||
|
||||
if (framesRead < 0)
|
||||
{
|
||||
std::cerr << "Opus decode error: " << framesRead << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer += framesRead * d->channelCount;
|
||||
|
||||
totalFramesRead += framesRead;
|
||||
framesRemaining -= framesRead;
|
||||
}
|
||||
|
||||
return totalFramesRead;
|
||||
}
|
||||
|
||||
std::string errorAsString(int opusErrorCode)
|
||||
{
|
||||
switch(opusErrorCode)
|
||||
{
|
||||
case OP_FALSE: return "A request did not succeed";
|
||||
case OP_EOF: return "End of File Reached";
|
||||
case OP_HOLE: return "There was a hole in the page sequence numbers (e.g., a page was corrupt or missing).";
|
||||
case OP_EREAD: return "An underlying read, seek, or tell operation failed when it should have succeeded.";
|
||||
case OP_EFAULT: return "A NULL pointer was passed where one was unexpected, or an internal memory allocation failed, or an internal library error was encountered.";
|
||||
case OP_EIMPL: return "The stream used a feature that is not implemented, such as an unsupported channel family. ";
|
||||
case OP_EINVAL: return "One or more parameters to a function were invalid. ";
|
||||
case OP_ENOTFORMAT: return "A purported Ogg Opus stream did not begin with an Ogg page, a purported header packet did not start with one of the required strings";
|
||||
case OP_EBADHEADER: return "A required header packet was not properly formatted, contained illegal values, or was missing altogether.";
|
||||
case OP_EVERSION: return "The ID header contained an unrecognized version number.";
|
||||
case OP_ENOTAUDIO: return "Not Audio";
|
||||
case OP_EBADPACKET: return "An audio packet failed to decode properly.";
|
||||
case OP_EBADLINK: return "We failed to find data we had seen before, or the bitstream structure was sufficiently malformed that seeking to the target destination was impossible.";
|
||||
case OP_ENOSEEK: return "An operation that requires seeking was requested on an unseekable stream.";
|
||||
case OP_EBADTIMESTAMP: return "The first or last granule position of a link failed basic validity checks.";
|
||||
default: return "Unknown Error";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// opus callbacks //
|
||||
////////////////////
|
||||
|
||||
private:
|
||||
|
||||
NO_MOVE(OpusDecoderInternal);
|
||||
|
||||
OggOpusFile * fileHandle;
|
||||
|
||||
AudioData * d;
|
||||
|
||||
inline int64_t getTotalSamples() const { return int64_t(op_pcm_total(const_cast<OggOpusFile *>(fileHandle), -1)); }
|
||||
inline int64_t getLengthInSeconds() const { return uint64_t(getTotalSamples() / OPUS_SAMPLE_RATE); }
|
||||
inline int64_t getCurrentSample() const { return int64_t(op_pcm_tell(const_cast<OggOpusFile *>(fileHandle))); }
|
||||
|
||||
};
|
||||
|
||||
//////////////////////
|
||||
// Public Interface //
|
||||
//////////////////////
|
||||
|
||||
void nqr::OpusDecoder::LoadFromPath(AudioData * data, const std::string & path)
|
||||
{
|
||||
auto fileBuffer = nqr::ReadFile(path);
|
||||
OpusDecoderInternal decoder(data, fileBuffer.buffer);
|
||||
}
|
||||
|
||||
void nqr::OpusDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
|
||||
{
|
||||
OpusDecoderInternal decoder(data, memory);
|
||||
}
|
||||
|
||||
std::vector<std::string> nqr::OpusDecoder::GetSupportedFileExtensions()
|
||||
{
|
||||
return {"opus"};
|
||||
}
|
||||
|
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// https://dxr.mozilla.org/mozilla-central/source/media/libopus
|
||||
|
||||
#if (_MSC_VER)
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 181 111 4267 4996 4244 4701 4702 4133 4100 4127 4206 4312 4505 4365 4005 4013 4334 4703)
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshadow"
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-register"
|
||||
#endif
|
||||
|
||||
#undef HAVE_CONFIG_H
|
||||
|
||||
#define USE_ALLOCA 1
|
||||
#define OPUS_BUILD 1
|
||||
|
||||
/* Enable SSE functions, if compiled with SSE/SSE2 (note that AMD64 implies SSE2) */
|
||||
#if defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1))
|
||||
#define __SSE__ 1
|
||||
#endif
|
||||
|
||||
//////////
|
||||
// CELT //
|
||||
//////////
|
||||
|
||||
#include "opus/celt/arch.h"
|
||||
#include "opus/celt/bands.h"
|
||||
#include "opus/celt/celt.h"
|
||||
#include "opus/celt/celt_lpc.h"
|
||||
#include "opus/celt/cwrs.h"
|
||||
#include "opus/celt/ecintrin.h"
|
||||
#include "opus/celt/entcode.h"
|
||||
#include "opus/celt/entdec.h"
|
||||
#include "opus/celt/entenc.h"
|
||||
#include "opus/celt/float_cast.h"
|
||||
#include "opus/celt/kiss_fft.h"
|
||||
#include "opus/celt/laplace.h"
|
||||
#include "opus/celt/mathops.h"
|
||||
#include "opus/celt/mdct.h"
|
||||
#include "opus/celt/mfrngcod.h"
|
||||
#include "opus/celt/modes.h"
|
||||
#include "opus/celt/os_support.h"
|
||||
#include "opus/celt/pitch.h"
|
||||
#include "opus/celt/quant_bands.h"
|
||||
#include "opus/celt/rate.h"
|
||||
#include "opus/celt/stack_alloc.h"
|
||||
#include "opus/celt/vq.h"
|
||||
#include "opus/celt/_kiss_fft_guts.h"
|
||||
|
||||
#include "opus/celt/bands.c"
|
||||
#include "opus/celt/celt.c"
|
||||
#include "opus/celt/celt_lpc.c"
|
||||
#include "opus/celt/cwrs.c"
|
||||
#include "opus/celt/entcode.c"
|
||||
#include "opus/celt/entdec.c"
|
||||
#include "opus/celt/entenc.c"
|
||||
#include "opus/celt/kiss_fft.c"
|
||||
#include "opus/celt/laplace.c"
|
||||
#include "opus/celt/mathops.c"
|
||||
#include "opus/celt/mdct.c"
|
||||
#include "opus/celt/modes.c"
|
||||
#include "opus/celt/pitch.c"
|
||||
#include "opus/celt/quant_bands.c"
|
||||
#include "opus/celt/rate.c"
|
||||
#include "opus/celt/vq.c"
|
||||
|
||||
//#define opus_custom_encoder_get_size opus_custom_encoder_get_size_alt
|
||||
#include "opus/celt/celt_decoder.c"
|
||||
#include "opus/celt/celt_encoder.c"
|
||||
|
||||
/////////////////
|
||||
// SILK Common //
|
||||
/////////////////
|
||||
|
||||
#include "opus_types.h"
|
||||
|
||||
#include "opus/silk/control.h"
|
||||
#include "opus/silk/debug.h"
|
||||
#include "opus/silk/define.h"
|
||||
#include "opus/silk/errors.h"
|
||||
#include "opus/silk/MacroCount.h"
|
||||
#include "opus/silk/MacroDebug.h"
|
||||
#include "opus/silk/macros.h"
|
||||
#include "opus/silk/main.h"
|
||||
#include "opus/silk/pitch_est_defines.h"
|
||||
#include "opus/silk/PLC.h"
|
||||
#include "opus/silk/resampler_private.h"
|
||||
#include "opus/silk/resampler_rom.h"
|
||||
#include "opus/silk/resampler_structs.h"
|
||||
#include "opus/silk/API.h"
|
||||
#include "opus/silk/SigProc_FIX.h"
|
||||
#include "opus/silk/structs.h"
|
||||
#include "opus/silk/tables.h"
|
||||
#include "opus/silk/tuning_parameters.h"
|
||||
#include "opus/silk/typedef.h"
|
||||
|
||||
#include "opus/silk/A2NLSF.c"
|
||||
#include "opus/silk/ana_filt_bank_1.c"
|
||||
#include "opus/silk/biquad_alt.c"
|
||||
#include "opus/silk/bwexpander.c"
|
||||
#include "opus/silk/bwexpander_32.c"
|
||||
#include "opus/silk/check_control_input.c"
|
||||
#include "opus/silk/CNG.c"
|
||||
#include "opus/silk/code_signs.c"
|
||||
#include "opus/silk/control_audio_bandwidth.c"
|
||||
#include "opus/silk/control_codec.c"
|
||||
#include "opus/silk/control_SNR.c"
|
||||
#include "opus/silk/debug.c"
|
||||
#include "opus/silk/decoder_set_fs.c"
|
||||
#include "opus/silk/decode_core.c"
|
||||
#include "opus/silk/decode_frame.c"
|
||||
#include "opus/silk/decode_indices.c"
|
||||
#include "opus/silk/decode_parameters.c"
|
||||
#include "opus/silk/decode_pitch.c"
|
||||
#include "opus/silk/decode_pulses.c"
|
||||
#include "opus/silk/dec_API.c"
|
||||
#include "opus/silk/encode_indices.c"
|
||||
#include "opus/silk/encode_pulses.c"
|
||||
#include "opus/silk/enc_API.c"
|
||||
#include "opus/silk/gain_quant.c"
|
||||
#include "opus/silk/HP_variable_cutoff.c"
|
||||
#include "opus/silk/init_decoder.c"
|
||||
#include "opus/silk/init_encoder.c"
|
||||
#include "opus/silk/inner_prod_aligned.c"
|
||||
#include "opus/silk/interpolate.c"
|
||||
#include "opus/silk/lin2log.c"
|
||||
#include "opus/silk/log2lin.c"
|
||||
#include "opus/silk/LPC_analysis_filter.c"
|
||||
#include "opus/silk/LPC_inv_pred_gain.c"
|
||||
#include "opus/silk/LP_variable_cutoff.c"
|
||||
#include "opus/silk/NLSF2A.c"
|
||||
#include "opus/silk/NLSF_decode.c"
|
||||
#include "opus/silk/NLSF_del_dec_quant.c"
|
||||
#include "opus/silk/NLSF_encode.c"
|
||||
#include "opus/silk/NLSF_stabilize.c"
|
||||
#include "opus/silk/NLSF_unpack.c"
|
||||
#include "opus/silk/NLSF_VQ.c"
|
||||
#include "opus/silk/NLSF_VQ_weights_laroia.c"
|
||||
#include "opus/silk/NSQ.c"
|
||||
#include "opus/silk/NSQ_del_dec.c"
|
||||
#include "opus/silk/pitch_est_tables.c"
|
||||
#include "opus/silk/PLC.c"
|
||||
#include "opus/silk/process_NLSFs.c"
|
||||
#include "opus/silk/quant_LTP_gains.c"
|
||||
#include "opus/silk/resampler.c"
|
||||
#include "opus/silk/resampler_down2.c"
|
||||
#include "opus/silk/resampler_down2_3.c"
|
||||
#include "opus/silk/resampler_private_AR2.c"
|
||||
#include "opus/silk/resampler_private_down_FIR.c"
|
||||
#include "opus/silk/resampler_private_IIR_FIR.c"
|
||||
#include "opus/silk/resampler_private_up2_HQ.c"
|
||||
#include "opus/silk/resampler_rom.c"
|
||||
#include "opus/silk/shell_coder.c"
|
||||
#include "opus/silk/sigm_Q15.c"
|
||||
#include "opus/silk/sort.c"
|
||||
#include "opus/silk/stereo_decode_pred.c"
|
||||
#include "opus/silk/stereo_encode_pred.c"
|
||||
#include "opus/silk/stereo_find_predictor.c"
|
||||
#include "opus/silk/stereo_LR_to_MS.c"
|
||||
#include "opus/silk/stereo_MS_to_LR.c"
|
||||
#include "opus/silk/stereo_quant_pred.c"
|
||||
#include "opus/silk/sum_sqr_shift.c"
|
||||
#include "opus/silk/tables_gain.c"
|
||||
#include "opus/silk/tables_LTP.c"
|
||||
#include "opus/silk/tables_NLSF_CB_NB_MB.c"
|
||||
#include "opus/silk/tables_NLSF_CB_WB.c"
|
||||
#include "opus/silk/tables_other.c"
|
||||
#include "opus/silk/tables_pitch_lag.c"
|
||||
#include "opus/silk/tables_pulses_per_block.c"
|
||||
#include "opus/silk/table_LSF_cos.c"
|
||||
#include "opus/silk/VAD.c"
|
||||
#include "opus/silk/VQ_WMat_EC.c"
|
||||
|
||||
////////////////
|
||||
// SILK Float //
|
||||
////////////////
|
||||
|
||||
#include "opus/silk/float/main_FLP.h"
|
||||
#include "opus/silk/float/SigProc_FLP.h"
|
||||
#include "opus/silk/float/structs_FLP.h"
|
||||
|
||||
#include "opus/silk/float/apply_sine_window_FLP.c"
|
||||
#include "opus/silk/float/autocorrelation_FLP.c"
|
||||
#include "opus/silk/float/burg_modified_FLP.c"
|
||||
#include "opus/silk/float/bwexpander_FLP.c"
|
||||
#include "opus/silk/float/corrMatrix_FLP.c"
|
||||
#include "opus/silk/float/encode_frame_FLP.c"
|
||||
#include "opus/silk/float/energy_FLP.c"
|
||||
#include "opus/silk/float/find_LPC_FLP.c"
|
||||
#include "opus/silk/float/find_LTP_FLP.c"
|
||||
#include "opus/silk/float/find_pitch_lags_FLP.c"
|
||||
#include "opus/silk/float/find_pred_coefs_FLP.c"
|
||||
#include "opus/silk/float/inner_product_FLP.c"
|
||||
#include "opus/silk/float/k2a_FLP.c"
|
||||
#include "opus/silk/float/levinsondurbin_FLP.c"
|
||||
#include "opus/silk/float/LPC_analysis_filter_FLP.c"
|
||||
#include "opus/silk/float/LPC_inv_pred_gain_FLP.c"
|
||||
#include "opus/silk/float/LTP_analysis_filter_FLP.c"
|
||||
#include "opus/silk/float/LTP_scale_ctrl_FLP.c"
|
||||
#include "opus/silk/float/noise_shape_analysis_FLP.c"
|
||||
#include "opus/silk/float/pitch_analysis_core_FLP.c"
|
||||
#include "opus/silk/float/prefilter_FLP.c"
|
||||
#include "opus/silk/float/process_gains_FLP.c"
|
||||
#include "opus/silk/float/regularize_correlations_FLP.c"
|
||||
#include "opus/silk/float/residual_energy_FLP.c"
|
||||
#include "opus/silk/float/scale_copy_vector_FLP.c"
|
||||
#include "opus/silk/float/scale_vector_FLP.c"
|
||||
#include "opus/silk/float/schur_FLP.c"
|
||||
#include "opus/silk/float/solve_LS_FLP.c"
|
||||
#include "opus/silk/float/sort_FLP.c"
|
||||
#include "opus/silk/float/warped_autocorrelation_FLP.c"
|
||||
#include "opus/silk/float/wrappers_FLP.c"
|
||||
|
||||
/////////////
|
||||
// LibOpus //
|
||||
/////////////
|
||||
|
||||
#include "opus/libopus/src/opus.c"
|
||||
#include "opus/libopus/src/opus_decoder.c"
|
||||
#include "opus/libopus/src/opus_encoder.c"
|
||||
#include "opus/libopus/src/opus_multistream.c"
|
||||
#include "opus/libopus/src/opus_multistream_decoder.c"
|
||||
#include "opus/libopus/src/opus_multistream_encoder.c"
|
||||
#include "opus/libopus/src/repacketizer.c"
|
||||
|
||||
#include "opus/libopus/src/analysis.c"
|
||||
#include "opus/libopus/src/mlp.c"
|
||||
#include "opus/libopus/src/mlp_data.c"
|
||||
|
||||
//////////////
|
||||
// Opusfile //
|
||||
//////////////
|
||||
|
||||
#include "opus/opusfile/src/http.c"
|
||||
#include "opus/opusfile/src/info.c"
|
||||
#include "opus/opusfile/src/internal.c"
|
||||
#include "opus/opusfile/src/opusfile.c"
|
||||
#include "opus/opusfile/src/stream.c"
|
||||
#include "opus/opusfile/src/wincerts.c"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if (_MSC_VER)
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Decoders.h"
|
||||
#include "libvorbis/include/vorbis/vorbisfile.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
using namespace nqr;
|
||||
|
||||
class VorbisDecoderInternal
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
VorbisDecoderInternal(AudioData * d, const std::vector<uint8_t> & memory) : d(d)
|
||||
{
|
||||
void * data = const_cast<uint8_t*>(memory.data());
|
||||
|
||||
ogg_file t;
|
||||
t.curPtr = t.filePtr = static_cast<char*>(data);
|
||||
t.fileSize = memory.size();
|
||||
|
||||
fileHandle = new OggVorbis_File;
|
||||
memset(fileHandle, 0, sizeof(OggVorbis_File));
|
||||
|
||||
ov_callbacks callbacks;
|
||||
callbacks.read_func = AR_readOgg;
|
||||
callbacks.seek_func = AR_seekOgg;
|
||||
callbacks.close_func = AR_closeOgg;
|
||||
callbacks.tell_func = AR_tellOgg;
|
||||
|
||||
loadAudioData(&t, callbacks);
|
||||
}
|
||||
|
||||
VorbisDecoderInternal(AudioData * d, std::string filepath) : d(d)
|
||||
{
|
||||
fileHandle = new OggVorbis_File();
|
||||
FILE * f = fopen(filepath.c_str(), "rb");
|
||||
if (!f) throw std::runtime_error("Can't open file");
|
||||
loadAudioData(f, OV_CALLBACKS_DEFAULT);
|
||||
}
|
||||
|
||||
~VorbisDecoderInternal()
|
||||
{
|
||||
ov_clear(fileHandle);
|
||||
}
|
||||
|
||||
size_t readInternal(size_t requestedFrameCount, size_t frameOffset = 0)
|
||||
{
|
||||
//@todo support offset
|
||||
|
||||
float **buffer = nullptr;
|
||||
size_t framesRemaining = requestedFrameCount;
|
||||
size_t totalFramesRead = 0;
|
||||
int bitstream = 0;
|
||||
|
||||
while(0 < framesRemaining)
|
||||
{
|
||||
int64_t framesRead = ov_read_float(fileHandle, &buffer, std::min(2048, (int) framesRemaining), &bitstream);
|
||||
|
||||
// end of file
|
||||
if(!framesRead) break;
|
||||
|
||||
// Probably OV_HOLE, OV_EBADLINK, OV_EINVAL. @todo - log warning here.
|
||||
if (framesRead < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < framesRead; ++i)
|
||||
{
|
||||
for(int ch = 0; ch < d->channelCount; ch++)
|
||||
{
|
||||
d->samples[totalFramesRead] = buffer[ch][i];
|
||||
totalFramesRead++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return totalFramesRead;
|
||||
}
|
||||
|
||||
std::string errorAsString(int ovErrorCode)
|
||||
{
|
||||
switch(ovErrorCode)
|
||||
{
|
||||
case OV_FALSE: return "OV_FALSE";
|
||||
case OV_EOF: return "OV_EOF";
|
||||
case OV_HOLE: return "OV_HOLE";
|
||||
case OV_EREAD: return "OV_EREAD";
|
||||
case OV_EFAULT: return "OV_EFAULT";
|
||||
case OV_EIMPL: return "OV_EIMPL";
|
||||
case OV_EINVAL: return "OV_EINVAL";
|
||||
case OV_ENOTVORBIS: return "OV_ENOTVORBIS";
|
||||
case OV_EBADHEADER: return "OV_EBADHEADER";
|
||||
case OV_EVERSION: return "OV_EVERSION";
|
||||
case OV_ENOTAUDIO: return "OV_ENOTAUDIO";
|
||||
case OV_EBADPACKET: return "OV_EBADPACKET";
|
||||
case OV_EBADLINK: return "OV_EBADLINK";
|
||||
case OV_ENOSEEK: return "OV_ENOSEEK";
|
||||
default: return "OV_UNKNOWN_ERROR";
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
// vorbis callbacks //
|
||||
//////////////////////
|
||||
|
||||
//@todo: implement streaming support
|
||||
|
||||
private:
|
||||
|
||||
struct ogg_file
|
||||
{
|
||||
char* curPtr;
|
||||
char* filePtr;
|
||||
size_t fileSize;
|
||||
};
|
||||
|
||||
NO_COPY(VorbisDecoderInternal);
|
||||
|
||||
OggVorbis_File * fileHandle;
|
||||
AudioData * d;
|
||||
|
||||
inline int64_t getTotalSamples() const { return int64_t(ov_pcm_total(const_cast<OggVorbis_File *>(fileHandle), -1)); }
|
||||
inline int64_t getLengthInSeconds() const { return int64_t(ov_time_total(const_cast<OggVorbis_File *>(fileHandle), -1)); }
|
||||
inline int64_t getCurrentSample() const { return int64_t(ov_pcm_tell(const_cast<OggVorbis_File *>(fileHandle))); }
|
||||
|
||||
static size_t AR_readOgg(void* dst, size_t size1, size_t size2, void* fh)
|
||||
{
|
||||
ogg_file* of = reinterpret_cast<ogg_file*>(fh);
|
||||
size_t len = size1 * size2;
|
||||
if ( of->curPtr + len > of->filePtr + of->fileSize )
|
||||
{
|
||||
len = of->filePtr + of->fileSize - of->curPtr;
|
||||
}
|
||||
memcpy( dst, of->curPtr, len );
|
||||
of->curPtr += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
static int AR_seekOgg(void * fh, ogg_int64_t to, int type)
|
||||
{
|
||||
ogg_file * of = reinterpret_cast<ogg_file*>(fh);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case SEEK_CUR: of->curPtr += to; break;
|
||||
case SEEK_END: of->curPtr = of->filePtr + of->fileSize - to; break;
|
||||
case SEEK_SET: of->curPtr = of->filePtr + to; break;
|
||||
default: return -1;
|
||||
}
|
||||
|
||||
if (of->curPtr < of->filePtr)
|
||||
{
|
||||
of->curPtr = of->filePtr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (of->curPtr > of->filePtr + of->fileSize)
|
||||
{
|
||||
of->curPtr = of->filePtr + of->fileSize;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int AR_closeOgg(void * fh)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long AR_tellOgg(void * fh)
|
||||
{
|
||||
ogg_file * of = reinterpret_cast<ogg_file*>(fh);
|
||||
return (of->curPtr - of->filePtr);
|
||||
}
|
||||
|
||||
void loadAudioData(void *source, ov_callbacks callbacks)
|
||||
{
|
||||
if (auto r = ov_test_callbacks(source, fileHandle, nullptr, 0, callbacks) != 0)
|
||||
{
|
||||
std::cerr << errorAsString(r) << std::endl;
|
||||
throw std::runtime_error("File is not a valid ogg vorbis file");
|
||||
}
|
||||
|
||||
if (auto r = ov_test_open(fileHandle) != 0)
|
||||
{
|
||||
std::cerr << errorAsString(r) << std::endl;
|
||||
throw std::runtime_error("ov_test_open failed");
|
||||
}
|
||||
|
||||
// Don't need to fclose() after an open -- vorbis does this internally
|
||||
|
||||
vorbis_info * ovInfo = ov_info(fileHandle, -1);
|
||||
|
||||
if (ovInfo == nullptr) throw std::runtime_error("Reading metadata failed");
|
||||
|
||||
if (auto r = ov_streams(fileHandle) != 1)
|
||||
{
|
||||
std::cerr << errorAsString(r) << std::endl;
|
||||
throw std::runtime_error( "Unsupported: file contains multiple bitstreams");
|
||||
}
|
||||
|
||||
d->sampleRate = int(ovInfo->rate);
|
||||
d->channelCount = ovInfo->channels;
|
||||
d->sourceFormat = MakeFormatForBits(32, true, false);
|
||||
d->lengthSeconds = double(getLengthInSeconds());
|
||||
d->frameSize = ovInfo->channels * GetFormatBitsPerSample(d->sourceFormat);
|
||||
|
||||
// Samples in a single channel
|
||||
auto totalSamples = size_t(getTotalSamples());
|
||||
|
||||
d->samples.resize(totalSamples * d->channelCount);
|
||||
|
||||
if (!readInternal(totalSamples)) throw std::runtime_error("could not read any data");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//////////////////////
|
||||
// Public Interface //
|
||||
//////////////////////
|
||||
|
||||
void VorbisDecoder::LoadFromPath(AudioData * data, const std::string & path)
|
||||
{
|
||||
VorbisDecoderInternal decoder(data, path);
|
||||
}
|
||||
|
||||
void VorbisDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
|
||||
{
|
||||
VorbisDecoderInternal decoder(data, memory);
|
||||
}
|
||||
|
||||
std::vector<std::string> VorbisDecoder::GetSupportedFileExtensions()
|
||||
{
|
||||
return {"ogg"};
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if (_MSC_VER)
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 181 111 4267 4996 4244 4701 4702 4133 4100 4127 4206 4312 4505 4365 4005 4013 4334)
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshadow"
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-register"
|
||||
#endif
|
||||
|
||||
#include "libvorbis/include/vorbis/vorbisenc.h"
|
||||
#include "libvorbis/include/vorbis/codec.h"
|
||||
#include "libvorbis/include/vorbis/vorbisfile.h"
|
||||
|
||||
#include "libogg/src/bitwise.c"
|
||||
#include "libogg/src/framing.c"
|
||||
|
||||
#include "libvorbis/src/analysis.c"
|
||||
#include "libvorbis/src/bitrate.c"
|
||||
#include "libvorbis/src/block.c"
|
||||
#include "libvorbis/src/codebook.c"
|
||||
#include "libvorbis/src/envelope.c"
|
||||
#include "libvorbis/src/floor0.c"
|
||||
#include "libvorbis/src/floor1.c"
|
||||
#include "libvorbis/src/info.c"
|
||||
#include "libvorbis/src/lpc.c"
|
||||
#include "libvorbis/src/lsp.c"
|
||||
#include "libvorbis/src/mapping0.c"
|
||||
#include "libvorbis/src/psy.c"
|
||||
#include "libvorbis/src/registry.c"
|
||||
#include "libvorbis/src/res0.c"
|
||||
#include "libvorbis/src/sharedbook.c"
|
||||
#include "libvorbis/src/smallft.c"
|
||||
#include "libvorbis/src/synthesis.c"
|
||||
#include "libvorbis/src/vorbisenc.c"
|
||||
#include "libvorbis/src/vorbisfile.c"
|
||||
#include "libvorbis/src/window.c"
|
||||
#include "libvorbis/src/mdct.c"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if (_MSC_VER)
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
|
@ -0,0 +1,326 @@
|
|||
/*
|
||||
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Decoders.h"
|
||||
#include <cstring>
|
||||
|
||||
using namespace nqr;
|
||||
|
||||
struct ADPCMState
|
||||
{
|
||||
int frame_size;
|
||||
int firstDataBlockByte;
|
||||
int dataSize;
|
||||
int currentByte;
|
||||
const uint8_t * inBuffer;
|
||||
};
|
||||
|
||||
static const int ima_index_table[16] =
|
||||
{
|
||||
-1, -1, -1, -1, // +0 / +3 : - the step
|
||||
2, 4, 6, 8, // +4 / +7 : + the step
|
||||
-1, -1, -1, -1, // -0 / -3 : - the step
|
||||
2, 4, 6, 8, // -4 / -7 : + the step
|
||||
};
|
||||
|
||||
static inline int ima_clamp_index(int index)
|
||||
{
|
||||
if (index < 0) return 0;
|
||||
else if (index > 88) return 88;
|
||||
return index;
|
||||
}
|
||||
|
||||
static inline int16_t ima_clamp_predict(int16_t predict)
|
||||
{
|
||||
if (predict < -32768) return -32768;
|
||||
else if (predict > 32767) return 32767;
|
||||
return predict;
|
||||
}
|
||||
|
||||
static const int ima_step_table[89] =
|
||||
{
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34,
|
||||
37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
|
||||
157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494,
|
||||
544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552,
|
||||
1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026,
|
||||
4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
|
||||
11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623,
|
||||
27086, 29794, 32767
|
||||
};
|
||||
|
||||
// Decodes an IMA ADPCM nibble to a 16 bit pcm sample
|
||||
static inline int16_t decode_nibble(uint8_t nibble, int16_t & p, int & s)
|
||||
{
|
||||
// Compute a delta to add to the predictor value
|
||||
int diff = ima_step_table[s] >> 3;
|
||||
if (nibble & 4) diff += ima_step_table[s];
|
||||
if (nibble & 2) diff += ima_step_table[s] >> 1;
|
||||
if (nibble & 1) diff += ima_step_table[s] >> 2;
|
||||
|
||||
// Sign
|
||||
if (nibble & 8) diff = -diff;
|
||||
|
||||
// Add delta
|
||||
p += diff;
|
||||
|
||||
s += ima_index_table[nibble];
|
||||
s = ima_clamp_index(s);
|
||||
|
||||
return ima_clamp_predict(p);
|
||||
}
|
||||
|
||||
void decode_ima_adpcm(ADPCMState & state, int16_t * outBuffer, uint32_t num_channels)
|
||||
{
|
||||
const uint8_t * data = state.inBuffer;
|
||||
|
||||
// Loop over the interleaved channels
|
||||
for (uint32_t ch = 0; ch < num_channels; ch++)
|
||||
{
|
||||
const int byteOffset = ch * 4;
|
||||
|
||||
// Header Structure:
|
||||
// Byte0: packed low byte of the initial predictor
|
||||
// Byte1: packed high byte of the initial predictor
|
||||
// Byte2: initial step index
|
||||
// Byte3: Reserved empty value
|
||||
int16_t predictor = ((int16_t)data[byteOffset + 1] << 8) | data[byteOffset];
|
||||
int stepIndex = data[byteOffset + 2];
|
||||
|
||||
uint8_t reserved = data[byteOffset + 3];
|
||||
if (reserved != 0) throw std::runtime_error("adpcm decode error");
|
||||
|
||||
int byteIdx = num_channels * 4 + byteOffset; //the byte index of the first data word for this channel
|
||||
int idx = ch;
|
||||
|
||||
// Decode nibbles of the remaining data
|
||||
while (byteIdx < state.frame_size)
|
||||
{
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
outBuffer[idx] = decode_nibble(data[byteIdx] & 0xf, predictor, stepIndex); // low nibble
|
||||
idx += num_channels;
|
||||
outBuffer[idx] = decode_nibble(data[byteIdx] >> 4, predictor, stepIndex); // high nibble
|
||||
idx += num_channels;
|
||||
byteIdx++;
|
||||
}
|
||||
byteIdx += (num_channels - 1) << 2; // Jump to the next data word for the current channel
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
// Public Interface //
|
||||
//////////////////////
|
||||
|
||||
void WavDecoder::LoadFromPath(AudioData * data, const std::string & path)
|
||||
{
|
||||
auto fileBuffer = nqr::ReadFile(path);
|
||||
return LoadFromBuffer(data, fileBuffer.buffer);
|
||||
}
|
||||
|
||||
void WavDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
|
||||
{
|
||||
//////////////////////
|
||||
// Read RIFF Header //
|
||||
//////////////////////
|
||||
|
||||
//@todo swap methods for rifx
|
||||
|
||||
RiffChunkHeader riffHeader = {};
|
||||
memcpy(&riffHeader, memory.data(), 12);
|
||||
|
||||
// Files should be 2-byte aligned
|
||||
// @tofix: enforce this
|
||||
// bool usePaddingShort = ((riffHeader.file_size % sizeof(uint16_t)) == 1) ? true : false;
|
||||
|
||||
// Check RIFF
|
||||
if (riffHeader.id_riff != GenerateChunkCode('R', 'I', 'F', 'F'))
|
||||
{
|
||||
// Check RIFX + FFIR
|
||||
if (riffHeader.id_riff == GenerateChunkCode('R', 'I', 'F', 'X') || riffHeader.id_riff == GenerateChunkCode('F', 'F', 'I', 'R'))
|
||||
{
|
||||
// We're not RIFF, and we don't match RIFX or FFIR either
|
||||
throw std::runtime_error("libnyquist doesn't support big endian files");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("bad RIFF/RIFX/FFIR file header");
|
||||
}
|
||||
}
|
||||
|
||||
if (riffHeader.id_wave != GenerateChunkCode('W', 'A', 'V', 'E')) throw std::runtime_error("bad WAVE header");
|
||||
|
||||
auto expectedSize = (memory.size() - riffHeader.file_size);
|
||||
if (expectedSize != sizeof(uint32_t) * 2)
|
||||
{
|
||||
throw std::runtime_error("declared size of file less than file size"); //@todo warning instead of runtime_error
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
// Read WAVE Header //
|
||||
//////////////////////
|
||||
|
||||
auto WaveChunkInfo = ScanForChunk(memory, GenerateChunkCode('f', 'm', 't', ' '));
|
||||
|
||||
if (WaveChunkInfo.offset == 0) throw std::runtime_error("couldn't find fmt chunk");
|
||||
|
||||
assert(WaveChunkInfo.size == 16 || WaveChunkInfo.size == 18 || WaveChunkInfo.size == 20 || WaveChunkInfo.size == 40);
|
||||
|
||||
WaveChunkHeader wavHeader = {};
|
||||
memcpy(&wavHeader, memory.data() + WaveChunkInfo.offset, sizeof(WaveChunkHeader));
|
||||
|
||||
if (wavHeader.chunk_size < 16)
|
||||
throw std::runtime_error("format chunk too small");
|
||||
|
||||
//@todo validate wav header (sane sample rate, bit depth, etc)
|
||||
|
||||
data->channelCount = wavHeader.channel_count;
|
||||
data->sampleRate = wavHeader.sample_rate;
|
||||
data->frameSize = wavHeader.frame_size;
|
||||
|
||||
auto bit_depth = wavHeader.bit_depth;
|
||||
switch (bit_depth)
|
||||
{
|
||||
case 4: data->sourceFormat = PCMFormat::PCM_16; break; // for IMA ADPCM
|
||||
case 8: data->sourceFormat = PCMFormat::PCM_U8; break;
|
||||
case 16: data->sourceFormat = PCMFormat::PCM_16; break;
|
||||
case 24: data->sourceFormat = PCMFormat::PCM_24; break;
|
||||
case 32: data->sourceFormat = (wavHeader.format == WaveFormatCode::FORMAT_IEEE) ? PCMFormat::PCM_FLT : PCMFormat::PCM_32; break;
|
||||
case 64: data->sourceFormat = (wavHeader.format == WaveFormatCode::FORMAT_IEEE) ? PCMFormat::PCM_DBL : PCMFormat::PCM_64; break;
|
||||
}
|
||||
|
||||
//std::cout << wavHeader << std::endl;
|
||||
|
||||
bool scanForFact = false;
|
||||
bool grabExtensibleData = false;
|
||||
bool adpcmEncoded = false;
|
||||
|
||||
if (wavHeader.format == WaveFormatCode::FORMAT_IEEE)
|
||||
{
|
||||
scanForFact = true;
|
||||
}
|
||||
else if (wavHeader.format == WaveFormatCode::FORMAT_IMA_ADPCM)
|
||||
{
|
||||
adpcmEncoded = true;
|
||||
scanForFact = true;
|
||||
}
|
||||
else if (wavHeader.format == WaveFormatCode::FORMAT_EXT)
|
||||
{
|
||||
// Used when (1) PCM data has more than 16 bits; (2) channels > 2; (3) bits/sample !== container size; (4) channel/speaker mapping specified;
|
||||
scanForFact = true;
|
||||
grabExtensibleData = true;
|
||||
}
|
||||
else if (wavHeader.format == WaveFormatCode::FORMAT_UNKNOWN)
|
||||
{
|
||||
throw std::runtime_error("unknown wave format");
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// Read Additional Chunks //
|
||||
////////////////////////////
|
||||
|
||||
FactChunk factChunk;
|
||||
if (scanForFact)
|
||||
{
|
||||
auto FactChunkInfo = ScanForChunk(memory, GenerateChunkCode('f', 'a', 'c', 't'));
|
||||
if (FactChunkInfo.size)
|
||||
memcpy(&factChunk, memory.data() + FactChunkInfo.offset, sizeof(FactChunk));
|
||||
}
|
||||
|
||||
if (grabExtensibleData)
|
||||
{
|
||||
ExtensibleData extData = {};
|
||||
memcpy(&extData, memory.data() + WaveChunkInfo.offset + sizeof(WaveChunkHeader), sizeof(ExtensibleData));
|
||||
// extData can be compared against the multi-channel masks defined in the header
|
||||
// eg. extData.channel_mask == SPEAKER_5POINT1
|
||||
}
|
||||
|
||||
//@todo smpl chunk could be useful
|
||||
|
||||
/////////////////////
|
||||
// Read Bext Chunk //
|
||||
/////////////////////
|
||||
|
||||
auto BextChunkInfo = ScanForChunk(memory, GenerateChunkCode('b', 'e', 'x', 't'));
|
||||
BextChunk bextChunk = {};
|
||||
|
||||
if (BextChunkInfo.size)
|
||||
{
|
||||
memcpy(&bextChunk, memory.data() + BextChunkInfo.offset, sizeof(BextChunk));
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
// Read DATA Chunk //
|
||||
/////////////////////
|
||||
|
||||
auto DataChunkInfo = ScanForChunk(memory, GenerateChunkCode('d', 'a', 't', 'a'));
|
||||
|
||||
if (DataChunkInfo.offset == 0)
|
||||
throw std::runtime_error("couldn't find data chunk");
|
||||
|
||||
DataChunkInfo.offset += 2 * sizeof(uint32_t); // ignore the header and size fields
|
||||
|
||||
if (adpcmEncoded)
|
||||
{
|
||||
ADPCMState s;
|
||||
s.frame_size = wavHeader.frame_size;
|
||||
s.firstDataBlockByte = 0;
|
||||
s.dataSize = DataChunkInfo.size;
|
||||
s.currentByte = 0;
|
||||
s.inBuffer = const_cast<uint8_t*>(memory.data() + DataChunkInfo.offset);
|
||||
|
||||
size_t totalSamples = (factChunk.sample_length * wavHeader.channel_count); // Samples per channel times channel count
|
||||
std::vector<int16_t> adpcm_pcm16(totalSamples * 2, 0); // Each frame decodes into twice as many pcm samples
|
||||
|
||||
uint32_t frameOffset = 0;
|
||||
uint32_t frameCount = DataChunkInfo.size / s.frame_size;
|
||||
|
||||
for (uint32_t i = 0; i < frameCount; ++i)
|
||||
{
|
||||
decode_ima_adpcm(s, adpcm_pcm16.data() + frameOffset, wavHeader.channel_count);
|
||||
s.inBuffer += s.frame_size;
|
||||
frameOffset += (s.frame_size * 2) - (8 * wavHeader.channel_count);
|
||||
}
|
||||
|
||||
data->lengthSeconds = ((float) totalSamples / (float) wavHeader.sample_rate) / wavHeader.channel_count;
|
||||
data->samples.resize(totalSamples);
|
||||
ConvertToFloat32(data->samples.data(), adpcm_pcm16.data(), totalSamples, data->sourceFormat);
|
||||
}
|
||||
else
|
||||
{
|
||||
data->lengthSeconds = ((float) DataChunkInfo.size / (float) wavHeader.sample_rate) / wavHeader.frame_size;
|
||||
size_t totalSamples = (DataChunkInfo.size / wavHeader.frame_size) * wavHeader.channel_count;
|
||||
data->samples.resize(totalSamples);
|
||||
ConvertToFloat32(data->samples.data(), memory.data() + DataChunkInfo.offset, totalSamples, data->sourceFormat);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> WavDecoder::GetSupportedFileExtensions()
|
||||
{
|
||||
return {"wav", "wave"};
|
||||
}
|
||||
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Decoders.h"
|
||||
#include "wavpack.h"
|
||||
#include <string.h>
|
||||
#include <cstring>
|
||||
|
||||
using namespace nqr;
|
||||
|
||||
class WavPackInternal
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
WavPackInternal(AudioData * d, const std::string & path) : d(d)
|
||||
{
|
||||
char errorStr[128];
|
||||
context = WavpackOpenFileInput(path.c_str(), errorStr, OPEN_WVC | OPEN_NORMALIZE, 0);
|
||||
|
||||
if (!context) throw std::runtime_error("Not a WavPack file");
|
||||
|
||||
auto totalSamples = size_t(WavpackGetNumSamples(context));
|
||||
|
||||
decode(totalSamples);
|
||||
}
|
||||
|
||||
WavPackInternal(AudioData * d, const std::vector<uint8_t> & memory) : d(d)
|
||||
{
|
||||
char errorStr[128];
|
||||
context = WavpackOpenRawDecoder((void *) memory.data(), memory.size(), nullptr, 0, 0, errorStr, OPEN_WVC | OPEN_NORMALIZE, 0);
|
||||
|
||||
// Since we are using OpenRawDecoder, WavpackGetNumSamples won't work.
|
||||
// Instead, find the first block and get totalSamples from its header.
|
||||
WavpackHeader wph;
|
||||
auto headerOffset = readNextHeader(memory, &wph, 0);
|
||||
|
||||
if (!context || headerOffset == -1)
|
||||
{
|
||||
throw std::runtime_error("Not a WavPack file");
|
||||
}
|
||||
|
||||
auto totalSamples = wph.total_samples;
|
||||
|
||||
decode(totalSamples);
|
||||
}
|
||||
|
||||
~WavPackInternal()
|
||||
{
|
||||
WavpackCloseFile(context);
|
||||
}
|
||||
|
||||
size_t readInternal(size_t requestedFrameCount, size_t frameOffset = 0)
|
||||
{
|
||||
size_t framesRemaining = requestedFrameCount;
|
||||
size_t totalFramesRead = 0;
|
||||
|
||||
// The samples returned are handled differently based on the file's mode
|
||||
int mode = WavpackGetMode(context);
|
||||
|
||||
while (0 < framesRemaining)
|
||||
{
|
||||
uint32_t framesRead = -1;
|
||||
|
||||
if (MODE_FLOAT & mode)
|
||||
{
|
||||
// Since it's float, we can decode directly into our buffer as a huge blob
|
||||
framesRead = WavpackUnpackSamples(context, reinterpret_cast<int32_t*>(&d->samples.data()[0]), uint32_t(d->samples.size() / d->channelCount));
|
||||
}
|
||||
|
||||
else if(MODE_LOSSLESS & mode)
|
||||
{
|
||||
// Lossless files will be handed off as integers
|
||||
framesRead = WavpackUnpackSamples(context, internalBuffer.data(), uint32_t(internalBuffer.size() / d->channelCount));
|
||||
}
|
||||
|
||||
// EOF
|
||||
//if (framesRead == 0) break;
|
||||
|
||||
totalFramesRead += framesRead;
|
||||
framesRemaining -= framesRead;
|
||||
}
|
||||
|
||||
return totalFramesRead;
|
||||
}
|
||||
|
||||
private:
|
||||
void decode(size_t totalSamples) {
|
||||
auto bitdepth = WavpackGetBitsPerSample(context);
|
||||
|
||||
d->sampleRate = WavpackGetSampleRate(context);
|
||||
d->channelCount = WavpackGetNumChannels(context);
|
||||
d->lengthSeconds = double(totalSamples / WavpackGetSampleRate(context));
|
||||
d->frameSize = d->channelCount * bitdepth;
|
||||
|
||||
//@todo support channel masks
|
||||
// WavpackGetChannelMask
|
||||
|
||||
int mode = WavpackGetMode(context);
|
||||
bool isFloatingPoint = (MODE_FLOAT & mode);
|
||||
|
||||
d->sourceFormat = MakeFormatForBits(bitdepth, isFloatingPoint, false);
|
||||
|
||||
d->samples.resize(totalSamples * d->channelCount);
|
||||
|
||||
if (!isFloatingPoint)
|
||||
internalBuffer.resize(totalSamples * d->channelCount);
|
||||
|
||||
if (!readInternal(totalSamples))
|
||||
throw std::runtime_error("could not read any data");
|
||||
|
||||
// Next, process internal buffer into the user-visible samples array
|
||||
if (!isFloatingPoint)
|
||||
ConvertToFloat32(d->samples.data(), internalBuffer.data(), totalSamples * d->channelCount, d->sourceFormat);
|
||||
}
|
||||
|
||||
int64_t readNextHeader(const std::vector<uint8_t> & memory, WavpackHeader *wphdr, size_t startOffset) {
|
||||
/// Based on read_next_header function in wavpack's openutils.c.
|
||||
/// This will find the position of the next WavPack header in the given vector, at or after startOffset.
|
||||
/// If a header is found, it will write the header to *wphdr and return the position of its first byte in the vector.
|
||||
/// Otherwise, it will return -1.
|
||||
unsigned char* sp;
|
||||
|
||||
for (size_t i = startOffset; i < memory.size(); i++) {
|
||||
sp = const_cast<unsigned char *>(memory.data() + i);
|
||||
|
||||
auto headerStartPoint = sp;
|
||||
|
||||
if (*sp++ == 'w' && *sp == 'v' && *++sp == 'p' && *++sp == 'k' &&
|
||||
!(*++sp & 1) && sp [2] < 16 && !sp [3] && (sp [2] || sp [1] || *sp >= 24) && sp [5] == 4 &&
|
||||
sp [4] >= (MIN_STREAM_VERS & 0xff) && sp [4] <= (MAX_STREAM_VERS & 0xff) && sp [18] < 3 && !sp [19]) {
|
||||
|
||||
memcpy (wphdr, headerStartPoint, sizeof (*wphdr));
|
||||
WavpackLittleEndianToNative (wphdr, (char*)WavpackHeaderFormat);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
NO_MOVE(WavPackInternal);
|
||||
|
||||
//WavpackStreamReader streamReader; //@todo: streaming support
|
||||
|
||||
WavpackContext * context; //@todo unique_ptr
|
||||
|
||||
AudioData * d;
|
||||
|
||||
std::vector<int32_t> internalBuffer;
|
||||
|
||||
inline int64_t getTotalSamples() const { return WavpackGetNumSamples(context); }
|
||||
inline int64_t getLengthInSeconds() const { return getTotalSamples() / WavpackGetSampleRate(context); }
|
||||
|
||||
};
|
||||
|
||||
//////////////////////
|
||||
// Public Interface //
|
||||
//////////////////////
|
||||
|
||||
void WavPackDecoder::LoadFromPath(AudioData * data, const std::string & path)
|
||||
{
|
||||
WavPackInternal decoder(data, path);
|
||||
}
|
||||
|
||||
void WavPackDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
|
||||
{
|
||||
WavPackInternal decoder(data, memory);
|
||||
}
|
||||
|
||||
std::vector<std::string> WavPackDecoder::GetSupportedFileExtensions()
|
||||
{
|
||||
return {"wv"};
|
||||
}
|
||||
|
|
@ -0,0 +1,371 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__ALL_H
|
||||
#define FLAC__ALL_H
|
||||
|
||||
#include "export.h"
|
||||
|
||||
#include "assert.h"
|
||||
#include "callback.h"
|
||||
#include "format.h"
|
||||
#include "metadata.h"
|
||||
#include "ordinals.h"
|
||||
#include "stream_decoder.h"
|
||||
#include "stream_encoder.h"
|
||||
|
||||
/** \mainpage
|
||||
*
|
||||
* \section intro Introduction
|
||||
*
|
||||
* This is the documentation for the FLAC C and C++ APIs. It is
|
||||
* highly interconnected; this introduction should give you a top
|
||||
* level idea of the structure and how to find the information you
|
||||
* need. As a prerequisite you should have at least a basic
|
||||
* knowledge of the FLAC format, documented
|
||||
* <A HREF="../format.html">here</A>.
|
||||
*
|
||||
* \section c_api FLAC C API
|
||||
*
|
||||
* The FLAC C API is the interface to libFLAC, a set of structures
|
||||
* describing the components of FLAC streams, and functions for
|
||||
* encoding and decoding streams, as well as manipulating FLAC
|
||||
* metadata in files. The public include files will be installed
|
||||
* in your include area (for example /usr/include/FLAC/...).
|
||||
*
|
||||
* By writing a little code and linking against libFLAC, it is
|
||||
* relatively easy to add FLAC support to another program. The
|
||||
* library is licensed under <A HREF="../license.html">Xiph's BSD license</A>.
|
||||
* Complete source code of libFLAC as well as the command-line
|
||||
* encoder and plugins is available and is a useful source of
|
||||
* examples.
|
||||
*
|
||||
* Aside from encoders and decoders, libFLAC provides a powerful
|
||||
* metadata interface for manipulating metadata in FLAC files. It
|
||||
* allows the user to add, delete, and modify FLAC metadata blocks
|
||||
* and it can automatically take advantage of PADDING blocks to avoid
|
||||
* rewriting the entire FLAC file when changing the size of the
|
||||
* metadata.
|
||||
*
|
||||
* libFLAC usually only requires the standard C library and C math
|
||||
* library. In particular, threading is not used so there is no
|
||||
* dependency on a thread library. However, libFLAC does not use
|
||||
* global variables and should be thread-safe.
|
||||
*
|
||||
* libFLAC also supports encoding to and decoding from Ogg FLAC.
|
||||
* However the metadata editing interfaces currently have limited
|
||||
* read-only support for Ogg FLAC files.
|
||||
*
|
||||
* \section cpp_api FLAC C++ API
|
||||
*
|
||||
* The FLAC C++ API is a set of classes that encapsulate the
|
||||
* structures and functions in libFLAC. They provide slightly more
|
||||
* functionality with respect to metadata but are otherwise
|
||||
* equivalent. For the most part, they share the same usage as
|
||||
* their counterparts in libFLAC, and the FLAC C API documentation
|
||||
* can be used as a supplement. The public include files
|
||||
* for the C++ API will be installed in your include area (for
|
||||
* example /usr/include/FLAC++/...).
|
||||
*
|
||||
* libFLAC++ is also licensed under
|
||||
* <A HREF="../license.html">Xiph's BSD license</A>.
|
||||
*
|
||||
* \section getting_started Getting Started
|
||||
*
|
||||
* A good starting point for learning the API is to browse through
|
||||
* the <A HREF="modules.html">modules</A>. Modules are logical
|
||||
* groupings of related functions or classes, which correspond roughly
|
||||
* to header files or sections of header files. Each module includes a
|
||||
* detailed description of the general usage of its functions or
|
||||
* classes.
|
||||
*
|
||||
* From there you can go on to look at the documentation of
|
||||
* individual functions. You can see different views of the individual
|
||||
* functions through the links in top bar across this page.
|
||||
*
|
||||
* If you prefer a more hands-on approach, you can jump right to some
|
||||
* <A HREF="../documentation_example_code.html">example code</A>.
|
||||
*
|
||||
* \section porting_guide Porting Guide
|
||||
*
|
||||
* Starting with FLAC 1.1.3 a \link porting Porting Guide \endlink
|
||||
* has been introduced which gives detailed instructions on how to
|
||||
* port your code to newer versions of FLAC.
|
||||
*
|
||||
* \section embedded_developers Embedded Developers
|
||||
*
|
||||
* libFLAC has grown larger over time as more functionality has been
|
||||
* included, but much of it may be unnecessary for a particular embedded
|
||||
* implementation. Unused parts may be pruned by some simple editing of
|
||||
* src/libFLAC/Makefile.am. In general, the decoders, encoders, and
|
||||
* metadata interface are all independent from each other.
|
||||
*
|
||||
* It is easiest to just describe the dependencies:
|
||||
*
|
||||
* - All modules depend on the \link flac_format Format \endlink module.
|
||||
* - The decoders and encoders depend on the bitbuffer.
|
||||
* - The decoder is independent of the encoder. The encoder uses the
|
||||
* decoder because of the verify feature, but this can be removed if
|
||||
* not needed.
|
||||
* - Parts of the metadata interface require the stream decoder (but not
|
||||
* the encoder).
|
||||
* - Ogg support is selectable through the compile time macro
|
||||
* \c FLAC__HAS_OGG.
|
||||
*
|
||||
* For example, if your application only requires the stream decoder, no
|
||||
* encoder, and no metadata interface, you can remove the stream encoder
|
||||
* and the metadata interface, which will greatly reduce the size of the
|
||||
* library.
|
||||
*
|
||||
* Also, there are several places in the libFLAC code with comments marked
|
||||
* with "OPT:" where a #define can be changed to enable code that might be
|
||||
* faster on a specific platform. Experimenting with these can yield faster
|
||||
* binaries.
|
||||
*/
|
||||
|
||||
/** \defgroup porting Porting Guide for New Versions
|
||||
*
|
||||
* This module describes differences in the library interfaces from
|
||||
* version to version. It assists in the porting of code that uses
|
||||
* the libraries to newer versions of FLAC.
|
||||
*
|
||||
* One simple facility for making porting easier that has been added
|
||||
* in FLAC 1.1.3 is a set of \c #defines in \c export.h of each
|
||||
* library's includes (e.g. \c include/FLAC/export.h). The
|
||||
* \c #defines mirror the libraries'
|
||||
* <A HREF="http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning">libtool version numbers</A>,
|
||||
* e.g. in libFLAC there are \c FLAC_API_VERSION_CURRENT,
|
||||
* \c FLAC_API_VERSION_REVISION, and \c FLAC_API_VERSION_AGE.
|
||||
* These can be used to support multiple versions of an API during the
|
||||
* transition phase, e.g.
|
||||
*
|
||||
* \code
|
||||
* #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
|
||||
* legacy code
|
||||
* #else
|
||||
* new code
|
||||
* #endif
|
||||
* \endcode
|
||||
*
|
||||
* The the source will work for multiple versions and the legacy code can
|
||||
* easily be removed when the transition is complete.
|
||||
*
|
||||
* Another available symbol is FLAC_API_SUPPORTS_OGG_FLAC (defined in
|
||||
* include/FLAC/export.h), which can be used to determine whether or not
|
||||
* the library has been compiled with support for Ogg FLAC. This is
|
||||
* simpler than trying to call an Ogg init function and catching the
|
||||
* error.
|
||||
*/
|
||||
|
||||
/** \defgroup porting_1_1_2_to_1_1_3 Porting from FLAC 1.1.2 to 1.1.3
|
||||
* \ingroup porting
|
||||
*
|
||||
* \brief
|
||||
* This module describes porting from FLAC 1.1.2 to FLAC 1.1.3.
|
||||
*
|
||||
* The main change between the APIs in 1.1.2 and 1.1.3 is that they have
|
||||
* been simplified. First, libOggFLAC has been merged into libFLAC and
|
||||
* libOggFLAC++ has been merged into libFLAC++. Second, both the three
|
||||
* decoding layers and three encoding layers have been merged into a
|
||||
* single stream decoder and stream encoder. That is, the functionality
|
||||
* of FLAC__SeekableStreamDecoder and FLAC__FileDecoder has been merged
|
||||
* into FLAC__StreamDecoder, and FLAC__SeekableStreamEncoder and
|
||||
* FLAC__FileEncoder into FLAC__StreamEncoder. Only the
|
||||
* FLAC__StreamDecoder and FLAC__StreamEncoder remain. What this means
|
||||
* is there is now a single API that can be used to encode or decode
|
||||
* streams to/from native FLAC or Ogg FLAC and the single API can work
|
||||
* on both seekable and non-seekable streams.
|
||||
*
|
||||
* Instead of creating an encoder or decoder of a certain layer, now the
|
||||
* client will always create a FLAC__StreamEncoder or
|
||||
* FLAC__StreamDecoder. The old layers are now differentiated by the
|
||||
* initialization function. For example, for the decoder,
|
||||
* FLAC__stream_decoder_init() has been replaced by
|
||||
* FLAC__stream_decoder_init_stream(). This init function takes
|
||||
* callbacks for the I/O, and the seeking callbacks are optional. This
|
||||
* allows the client to use the same object for seekable and
|
||||
* non-seekable streams. For decoding a FLAC file directly, the client
|
||||
* can use FLAC__stream_decoder_init_file() and pass just a filename
|
||||
* and fewer callbacks; most of the other callbacks are supplied
|
||||
* internally. For situations where fopen()ing by filename is not
|
||||
* possible (e.g. Unicode filenames on Windows) the client can instead
|
||||
* open the file itself and supply the FILE* to
|
||||
* FLAC__stream_decoder_init_FILE(). The init functions now returns a
|
||||
* FLAC__StreamDecoderInitStatus instead of FLAC__StreamDecoderState.
|
||||
* Since the callbacks and client data are now passed to the init
|
||||
* function, the FLAC__stream_decoder_set_*_callback() functions and
|
||||
* FLAC__stream_decoder_set_client_data() are no longer needed. The
|
||||
* rest of the calls to the decoder are the same as before.
|
||||
*
|
||||
* There are counterpart init functions for Ogg FLAC, e.g.
|
||||
* FLAC__stream_decoder_init_ogg_stream(). All the rest of the calls
|
||||
* and callbacks are the same as for native FLAC.
|
||||
*
|
||||
* As an example, in FLAC 1.1.2 a seekable stream decoder would have
|
||||
* been set up like so:
|
||||
*
|
||||
* \code
|
||||
* FLAC__SeekableStreamDecoder *decoder = FLAC__seekable_stream_decoder_new();
|
||||
* if(decoder == NULL) do_something;
|
||||
* FLAC__seekable_stream_decoder_set_md5_checking(decoder, true);
|
||||
* [... other settings ...]
|
||||
* FLAC__seekable_stream_decoder_set_read_callback(decoder, my_read_callback);
|
||||
* FLAC__seekable_stream_decoder_set_seek_callback(decoder, my_seek_callback);
|
||||
* FLAC__seekable_stream_decoder_set_tell_callback(decoder, my_tell_callback);
|
||||
* FLAC__seekable_stream_decoder_set_length_callback(decoder, my_length_callback);
|
||||
* FLAC__seekable_stream_decoder_set_eof_callback(decoder, my_eof_callback);
|
||||
* FLAC__seekable_stream_decoder_set_write_callback(decoder, my_write_callback);
|
||||
* FLAC__seekable_stream_decoder_set_metadata_callback(decoder, my_metadata_callback);
|
||||
* FLAC__seekable_stream_decoder_set_error_callback(decoder, my_error_callback);
|
||||
* FLAC__seekable_stream_decoder_set_client_data(decoder, my_client_data);
|
||||
* if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) do_something;
|
||||
* \endcode
|
||||
*
|
||||
* In FLAC 1.1.3 it is like this:
|
||||
*
|
||||
* \code
|
||||
* FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new();
|
||||
* if(decoder == NULL) do_something;
|
||||
* FLAC__stream_decoder_set_md5_checking(decoder, true);
|
||||
* [... other settings ...]
|
||||
* if(FLAC__stream_decoder_init_stream(
|
||||
* decoder,
|
||||
* my_read_callback,
|
||||
* my_seek_callback, // or NULL
|
||||
* my_tell_callback, // or NULL
|
||||
* my_length_callback, // or NULL
|
||||
* my_eof_callback, // or NULL
|
||||
* my_write_callback,
|
||||
* my_metadata_callback, // or NULL
|
||||
* my_error_callback,
|
||||
* my_client_data
|
||||
* ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
|
||||
* \endcode
|
||||
*
|
||||
* or you could do;
|
||||
*
|
||||
* \code
|
||||
* [...]
|
||||
* FILE *file = fopen("somefile.flac","rb");
|
||||
* if(file == NULL) do_somthing;
|
||||
* if(FLAC__stream_decoder_init_FILE(
|
||||
* decoder,
|
||||
* file,
|
||||
* my_write_callback,
|
||||
* my_metadata_callback, // or NULL
|
||||
* my_error_callback,
|
||||
* my_client_data
|
||||
* ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
|
||||
* \endcode
|
||||
*
|
||||
* or just:
|
||||
*
|
||||
* \code
|
||||
* [...]
|
||||
* if(FLAC__stream_decoder_init_file(
|
||||
* decoder,
|
||||
* "somefile.flac",
|
||||
* my_write_callback,
|
||||
* my_metadata_callback, // or NULL
|
||||
* my_error_callback,
|
||||
* my_client_data
|
||||
* ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
|
||||
* \endcode
|
||||
*
|
||||
* Another small change to the decoder is in how it handles unparseable
|
||||
* streams. Before, when the decoder found an unparseable stream
|
||||
* (reserved for when the decoder encounters a stream from a future
|
||||
* encoder that it can't parse), it changed the state to
|
||||
* \c FLAC__STREAM_DECODER_UNPARSEABLE_STREAM. Now the decoder instead
|
||||
* drops sync and calls the error callback with a new error code
|
||||
* \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM. This is
|
||||
* more robust. If your error callback does not discriminate on the the
|
||||
* error state, your code does not need to be changed.
|
||||
*
|
||||
* The encoder now has a new setting:
|
||||
* FLAC__stream_encoder_set_apodization(). This is for setting the
|
||||
* method used to window the data before LPC analysis. You only need to
|
||||
* add a call to this function if the default is not suitable. There
|
||||
* are also two new convenience functions that may be useful:
|
||||
* FLAC__metadata_object_cuesheet_calculate_cddb_id() and
|
||||
* FLAC__metadata_get_cuesheet().
|
||||
*
|
||||
* The \a bytes parameter to FLAC__StreamDecoderReadCallback,
|
||||
* FLAC__StreamEncoderReadCallback, and FLAC__StreamEncoderWriteCallback
|
||||
* is now \c size_t instead of \c unsigned.
|
||||
*/
|
||||
|
||||
/** \defgroup porting_1_1_3_to_1_1_4 Porting from FLAC 1.1.3 to 1.1.4
|
||||
* \ingroup porting
|
||||
*
|
||||
* \brief
|
||||
* This module describes porting from FLAC 1.1.3 to FLAC 1.1.4.
|
||||
*
|
||||
* There were no changes to any of the interfaces from 1.1.3 to 1.1.4.
|
||||
* There was a slight change in the implementation of
|
||||
* FLAC__stream_encoder_set_metadata(); the function now makes a copy
|
||||
* of the \a metadata array of pointers so the client no longer needs
|
||||
* to maintain it after the call. The objects themselves that are
|
||||
* pointed to by the array are still not copied though and must be
|
||||
* maintained until the call to FLAC__stream_encoder_finish().
|
||||
*/
|
||||
|
||||
/** \defgroup porting_1_1_4_to_1_2_0 Porting from FLAC 1.1.4 to 1.2.0
|
||||
* \ingroup porting
|
||||
*
|
||||
* \brief
|
||||
* This module describes porting from FLAC 1.1.4 to FLAC 1.2.0.
|
||||
*
|
||||
* There were only very minor changes to the interfaces from 1.1.4 to 1.2.0.
|
||||
* In libFLAC, \c FLAC__format_sample_rate_is_subset() was added.
|
||||
* In libFLAC++, \c FLAC::Decoder::Stream::get_decode_position() was added.
|
||||
*
|
||||
* Finally, value of the constant \c FLAC__FRAME_HEADER_RESERVED_LEN
|
||||
* has changed to reflect the conversion of one of the reserved bits
|
||||
* into active use. It used to be \c 2 and now is \c 1. However the
|
||||
* FLAC frame header length has not changed, so to skip the proper
|
||||
* number of bits, use \c FLAC__FRAME_HEADER_RESERVED_LEN +
|
||||
* \c FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN
|
||||
*/
|
||||
|
||||
/** \defgroup flac FLAC C API
|
||||
*
|
||||
* The FLAC C API is the interface to libFLAC, a set of structures
|
||||
* describing the components of FLAC streams, and functions for
|
||||
* encoding and decoding streams, as well as manipulating FLAC
|
||||
* metadata in files.
|
||||
*
|
||||
* You should start with the format components as all other modules
|
||||
* are dependent on it.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__ASSERT_H
|
||||
#define FLAC__ASSERT_H
|
||||
|
||||
/* we need this since some compilers (like MSVC) leave assert()s on release code (and we don't want to use their ASSERT) */
|
||||
#ifdef DEBUG
|
||||
#include <assert.h>
|
||||
#define FLAC__ASSERT(x) assert(x)
|
||||
#define FLAC__ASSERT_DECLARATION(x) x
|
||||
#else
|
||||
#define FLAC__ASSERT(x)
|
||||
#define FLAC__ASSERT_DECLARATION(x)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2004-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__CALLBACK_H
|
||||
#define FLAC__CALLBACK_H
|
||||
|
||||
#include "ordinals.h"
|
||||
#include <stdlib.h> /* for size_t */
|
||||
|
||||
/** \file include/FLAC/callback.h
|
||||
*
|
||||
* \brief
|
||||
* This module defines the structures for describing I/O callbacks
|
||||
* to the other FLAC interfaces.
|
||||
*
|
||||
* See the detailed documentation for callbacks in the
|
||||
* \link flac_callbacks callbacks \endlink module.
|
||||
*/
|
||||
|
||||
/** \defgroup flac_callbacks FLAC/callback.h: I/O callback structures
|
||||
* \ingroup flac
|
||||
*
|
||||
* \brief
|
||||
* This module defines the structures for describing I/O callbacks
|
||||
* to the other FLAC interfaces.
|
||||
*
|
||||
* The purpose of the I/O callback functions is to create a common way
|
||||
* for the metadata interfaces to handle I/O.
|
||||
*
|
||||
* Originally the metadata interfaces required filenames as the way of
|
||||
* specifying FLAC files to operate on. This is problematic in some
|
||||
* environments so there is an additional option to specify a set of
|
||||
* callbacks for doing I/O on the FLAC file, instead of the filename.
|
||||
*
|
||||
* In addition to the callbacks, a FLAC__IOHandle type is defined as an
|
||||
* opaque structure for a data source.
|
||||
*
|
||||
* The callback function prototypes are similar (but not identical) to the
|
||||
* stdio functions fread, fwrite, fseek, ftell, feof, and fclose. If you use
|
||||
* stdio streams to implement the callbacks, you can pass fread, fwrite, and
|
||||
* fclose anywhere a FLAC__IOCallback_Read, FLAC__IOCallback_Write, or
|
||||
* FLAC__IOCallback_Close is required, and a FILE* anywhere a FLAC__IOHandle
|
||||
* is required. \warning You generally CANNOT directly use fseek or ftell
|
||||
* for FLAC__IOCallback_Seek or FLAC__IOCallback_Tell since on most systems
|
||||
* these use 32-bit offsets and FLAC requires 64-bit offsets to deal with
|
||||
* large files. You will have to find an equivalent function (e.g. ftello),
|
||||
* or write a wrapper. The same is true for feof() since this is usually
|
||||
* implemented as a macro, not as a function whose address can be taken.
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** This is the opaque handle type used by the callbacks. Typically
|
||||
* this is a \c FILE* or address of a file descriptor.
|
||||
*/
|
||||
typedef void* FLAC__IOHandle;
|
||||
|
||||
/** Signature for the read callback.
|
||||
* The signature and semantics match POSIX fread() implementations
|
||||
* and can generally be used interchangeably.
|
||||
*
|
||||
* \param ptr The address of the read buffer.
|
||||
* \param size The size of the records to be read.
|
||||
* \param nmemb The number of records to be read.
|
||||
* \param handle The handle to the data source.
|
||||
* \retval size_t
|
||||
* The number of records read.
|
||||
*/
|
||||
typedef size_t (*FLAC__IOCallback_Read) (void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle);
|
||||
|
||||
/** Signature for the write callback.
|
||||
* The signature and semantics match POSIX fwrite() implementations
|
||||
* and can generally be used interchangeably.
|
||||
*
|
||||
* \param ptr The address of the write buffer.
|
||||
* \param size The size of the records to be written.
|
||||
* \param nmemb The number of records to be written.
|
||||
* \param handle The handle to the data source.
|
||||
* \retval size_t
|
||||
* The number of records written.
|
||||
*/
|
||||
typedef size_t (*FLAC__IOCallback_Write) (const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle);
|
||||
|
||||
/** Signature for the seek callback.
|
||||
* The signature and semantics mostly match POSIX fseek() WITH ONE IMPORTANT
|
||||
* EXCEPTION: the offset is a 64-bit type whereas fseek() is generally 'long'
|
||||
* and 32-bits wide.
|
||||
*
|
||||
* \param handle The handle to the data source.
|
||||
* \param offset The new position, relative to \a whence
|
||||
* \param whence \c SEEK_SET, \c SEEK_CUR, or \c SEEK_END
|
||||
* \retval int
|
||||
* \c 0 on success, \c -1 on error.
|
||||
*/
|
||||
typedef int (*FLAC__IOCallback_Seek) (FLAC__IOHandle handle, FLAC__int64 offset, int whence);
|
||||
|
||||
/** Signature for the tell callback.
|
||||
* The signature and semantics mostly match POSIX ftell() WITH ONE IMPORTANT
|
||||
* EXCEPTION: the offset is a 64-bit type whereas ftell() is generally 'long'
|
||||
* and 32-bits wide.
|
||||
*
|
||||
* \param handle The handle to the data source.
|
||||
* \retval FLAC__int64
|
||||
* The current position on success, \c -1 on error.
|
||||
*/
|
||||
typedef FLAC__int64 (*FLAC__IOCallback_Tell) (FLAC__IOHandle handle);
|
||||
|
||||
/** Signature for the EOF callback.
|
||||
* The signature and semantics mostly match POSIX feof() but WATCHOUT:
|
||||
* on many systems, feof() is a macro, so in this case a wrapper function
|
||||
* must be provided instead.
|
||||
*
|
||||
* \param handle The handle to the data source.
|
||||
* \retval int
|
||||
* \c 0 if not at end of file, nonzero if at end of file.
|
||||
*/
|
||||
typedef int (*FLAC__IOCallback_Eof) (FLAC__IOHandle handle);
|
||||
|
||||
/** Signature for the close callback.
|
||||
* The signature and semantics match POSIX fclose() implementations
|
||||
* and can generally be used interchangeably.
|
||||
*
|
||||
* \param handle The handle to the data source.
|
||||
* \retval int
|
||||
* \c 0 on success, \c EOF on error.
|
||||
*/
|
||||
typedef int (*FLAC__IOCallback_Close) (FLAC__IOHandle handle);
|
||||
|
||||
/** A structure for holding a set of callbacks.
|
||||
* Each FLAC interface that requires a FLAC__IOCallbacks structure will
|
||||
* describe which of the callbacks are required. The ones that are not
|
||||
* required may be set to NULL.
|
||||
*
|
||||
* If the seek requirement for an interface is optional, you can signify that
|
||||
* a data sorce is not seekable by setting the \a seek field to \c NULL.
|
||||
*/
|
||||
typedef struct {
|
||||
FLAC__IOCallback_Read read;
|
||||
FLAC__IOCallback_Write write;
|
||||
FLAC__IOCallback_Seek seek;
|
||||
FLAC__IOCallback_Tell tell;
|
||||
FLAC__IOCallback_Eof eof;
|
||||
FLAC__IOCallback_Close close;
|
||||
} FLAC__IOCallbacks;
|
||||
|
||||
/* \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__EXPORT_H
|
||||
#define FLAC__EXPORT_H
|
||||
|
||||
/** \file include/FLAC/export.h
|
||||
*
|
||||
* \brief
|
||||
* This module contains #defines and symbols for exporting function
|
||||
* calls, and providing version information and compiled-in features.
|
||||
*
|
||||
* See the \link flac_export export \endlink module.
|
||||
*/
|
||||
|
||||
/** \defgroup flac_export FLAC/export.h: export symbols
|
||||
* \ingroup flac
|
||||
*
|
||||
* \brief
|
||||
* This module contains #defines and symbols for exporting function
|
||||
* calls, and providing version information and compiled-in features.
|
||||
*
|
||||
* If you are compiling with MSVC and will link to the static library
|
||||
* (libFLAC.lib) you should define FLAC__NO_DLL in your project to
|
||||
* make sure the symbols are exported properly.
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
#if defined(FLAC__NO_DLL)
|
||||
#define FLAC_API
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
#ifdef FLAC_API_EXPORTS
|
||||
#define FLAC_API __declspec(dllexport)
|
||||
#else
|
||||
#define FLAC_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#elif defined(FLAC__USE_VISIBILITY_ATTR)
|
||||
#define FLAC_API __attribute__ ((visibility ("default")))
|
||||
|
||||
#else
|
||||
#define FLAC_API
|
||||
|
||||
#endif
|
||||
|
||||
/** These #defines will mirror the libtool-based library version number, see
|
||||
* http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning
|
||||
*/
|
||||
#define FLAC_API_VERSION_CURRENT 11
|
||||
#define FLAC_API_VERSION_REVISION 0 /**< see above */
|
||||
#define FLAC_API_VERSION_AGE 3 /**< see above */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \c 1 if the library has been compiled with support for Ogg FLAC, else \c 0. */
|
||||
extern FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* \} */
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,86 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__ORDINALS_H
|
||||
#define FLAC__ORDINALS_H
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1600
|
||||
|
||||
/* Microsoft Visual Studio earlier than the 2010 version did not provide
|
||||
* the 1999 ISO C Standard header file <stdint.h>.
|
||||
*/
|
||||
|
||||
typedef __int8 FLAC__int8;
|
||||
typedef unsigned __int8 FLAC__uint8;
|
||||
|
||||
typedef __int16 FLAC__int16;
|
||||
typedef __int32 FLAC__int32;
|
||||
typedef __int64 FLAC__int64;
|
||||
typedef unsigned __int16 FLAC__uint16;
|
||||
typedef unsigned __int32 FLAC__uint32;
|
||||
typedef unsigned __int64 FLAC__uint64;
|
||||
|
||||
#else
|
||||
|
||||
/* For MSVC 2010 and everything else which provides <stdint.h>. */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int8_t FLAC__int8;
|
||||
typedef uint8_t FLAC__uint8;
|
||||
|
||||
typedef int16_t FLAC__int16;
|
||||
typedef int32_t FLAC__int32;
|
||||
typedef int64_t FLAC__int64;
|
||||
typedef uint16_t FLAC__uint16;
|
||||
typedef uint32_t FLAC__uint32;
|
||||
typedef uint64_t FLAC__uint64;
|
||||
|
||||
#endif
|
||||
|
||||
typedef int FLAC__bool;
|
||||
|
||||
typedef FLAC__uint8 FLAC__byte;
|
||||
|
||||
|
||||
#ifdef true
|
||||
#undef true
|
||||
#endif
|
||||
#ifdef false
|
||||
#undef false
|
||||
#endif
|
||||
#ifndef __cplusplus
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/bitmath.h"
|
||||
|
||||
/* An example of what FLAC__bitmath_silog2() computes:
|
||||
*
|
||||
* silog2(-10) = 5
|
||||
* silog2(- 9) = 5
|
||||
* silog2(- 8) = 4
|
||||
* silog2(- 7) = 4
|
||||
* silog2(- 6) = 4
|
||||
* silog2(- 5) = 4
|
||||
* silog2(- 4) = 3
|
||||
* silog2(- 3) = 3
|
||||
* silog2(- 2) = 2
|
||||
* silog2(- 1) = 2
|
||||
* silog2( 0) = 0
|
||||
* silog2( 1) = 2
|
||||
* silog2( 2) = 3
|
||||
* silog2( 3) = 3
|
||||
* silog2( 4) = 4
|
||||
* silog2( 5) = 4
|
||||
* silog2( 6) = 4
|
||||
* silog2( 7) = 4
|
||||
* silog2( 8) = 5
|
||||
* silog2( 9) = 5
|
||||
* silog2( 10) = 5
|
||||
*/
|
||||
unsigned FLAC__bitmath_silog2(int v)
|
||||
{
|
||||
while(1) {
|
||||
if(v == 0) {
|
||||
return 0;
|
||||
}
|
||||
else if(v > 0) {
|
||||
unsigned l = 0;
|
||||
while(v) {
|
||||
l++;
|
||||
v >>= 1;
|
||||
}
|
||||
return l+1;
|
||||
}
|
||||
else if(v == -1) {
|
||||
return 2;
|
||||
}
|
||||
else {
|
||||
v++;
|
||||
v = -v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned FLAC__bitmath_silog2_wide(FLAC__int64 v)
|
||||
{
|
||||
while(1) {
|
||||
if(v == 0) {
|
||||
return 0;
|
||||
}
|
||||
else if(v > 0) {
|
||||
unsigned l = 0;
|
||||
while(v) {
|
||||
l++;
|
||||
v >>= 1;
|
||||
}
|
||||
return l+1;
|
||||
}
|
||||
else if(v == -1) {
|
||||
return 2;
|
||||
}
|
||||
else {
|
||||
v++;
|
||||
v = -v;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,843 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "private/bitwriter.h"
|
||||
#include "private/crc.h"
|
||||
#include "private/macros.h"
|
||||
#include "FLAC/assert.h"
|
||||
#include "share/alloc.h"
|
||||
#include "share/compat.h"
|
||||
#include "share/endswap.h"
|
||||
|
||||
/* Things should be fastest when this matches the machine word size */
|
||||
/* WATCHOUT: if you change this you must also change the following #defines down to SWAP_BE_WORD_TO_HOST below to match */
|
||||
/* WATCHOUT: there are a few places where the code will not work unless uint32_t is >= 32 bits wide */
|
||||
#define FLAC__BYTES_PER_WORD 4
|
||||
#define FLAC__BITS_PER_WORD 32
|
||||
#define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff)
|
||||
/* SWAP_BE_WORD_TO_HOST swaps bytes in a uint32_t (which is always big-endian) if necessary to match host byte order */
|
||||
#if WORDS_BIGENDIAN
|
||||
#define SWAP_BE_WORD_TO_HOST(x) (x)
|
||||
#else
|
||||
#define SWAP_BE_WORD_TO_HOST(x) ENDSWAP_32(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The default capacity here doesn't matter too much. The buffer always grows
|
||||
* to hold whatever is written to it. Usually the encoder will stop adding at
|
||||
* a frame or metadata block, then write that out and clear the buffer for the
|
||||
* next one.
|
||||
*/
|
||||
static const unsigned FLAC__BITWRITER_DEFAULT_CAPACITY = 32768u / sizeof(uint32_t); /* size in words */
|
||||
/* When growing, increment 4K at a time */
|
||||
static const unsigned FLAC__BITWRITER_DEFAULT_INCREMENT = 4096u / sizeof(uint32_t); /* size in words */
|
||||
|
||||
#define FLAC__WORDS_TO_BITS(words) ((words) * FLAC__BITS_PER_WORD)
|
||||
#define FLAC__TOTAL_BITS(bw) (FLAC__WORDS_TO_BITS((bw)->words) + (bw)->bits)
|
||||
|
||||
struct FLAC__BitWriter {
|
||||
uint32_t *buffer;
|
||||
uint32_t accum; /* accumulator; bits are right-justified; when full, accum is appended to buffer */
|
||||
unsigned capacity; /* capacity of buffer in words */
|
||||
unsigned words; /* # of complete words in buffer */
|
||||
unsigned bits; /* # of used bits in accum */
|
||||
};
|
||||
|
||||
/* * WATCHOUT: The current implementation only grows the buffer. */
|
||||
#ifndef __SUNPRO_C
|
||||
static
|
||||
#endif
|
||||
FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, unsigned bits_to_add)
|
||||
{
|
||||
unsigned new_capacity;
|
||||
uint32_t *new_buffer;
|
||||
|
||||
FLAC__ASSERT(0 != bw);
|
||||
FLAC__ASSERT(0 != bw->buffer);
|
||||
|
||||
/* calculate total words needed to store 'bits_to_add' additional bits */
|
||||
new_capacity = bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD);
|
||||
|
||||
/* it's possible (due to pessimism in the growth estimation that
|
||||
* leads to this call) that we don't actually need to grow
|
||||
*/
|
||||
if(bw->capacity >= new_capacity)
|
||||
return true;
|
||||
|
||||
/* round up capacity increase to the nearest FLAC__BITWRITER_DEFAULT_INCREMENT */
|
||||
if((new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT)
|
||||
new_capacity += FLAC__BITWRITER_DEFAULT_INCREMENT - ((new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT);
|
||||
/* make sure we got everything right */
|
||||
FLAC__ASSERT(0 == (new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT);
|
||||
FLAC__ASSERT(new_capacity > bw->capacity);
|
||||
FLAC__ASSERT(new_capacity >= bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD));
|
||||
|
||||
new_buffer = safe_realloc_mul_2op_(bw->buffer, sizeof(uint32_t), /*times*/new_capacity);
|
||||
if(new_buffer == 0)
|
||||
return false;
|
||||
bw->buffer = new_buffer;
|
||||
bw->capacity = new_capacity;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Class constructor/destructor
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
FLAC__BitWriter *FLAC__bitwriter_new(void)
|
||||
{
|
||||
FLAC__BitWriter *bw = calloc(1, sizeof(FLAC__BitWriter));
|
||||
/* note that calloc() sets all members to 0 for us */
|
||||
return bw;
|
||||
}
|
||||
|
||||
void FLAC__bitwriter_delete(FLAC__BitWriter *bw)
|
||||
{
|
||||
FLAC__ASSERT(0 != bw);
|
||||
|
||||
FLAC__bitwriter_free(bw);
|
||||
free(bw);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Public class methods
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
FLAC__bool FLAC__bitwriter_init(FLAC__BitWriter *bw)
|
||||
{
|
||||
FLAC__ASSERT(0 != bw);
|
||||
|
||||
bw->words = bw->bits = 0;
|
||||
bw->capacity = FLAC__BITWRITER_DEFAULT_CAPACITY;
|
||||
bw->buffer = malloc(sizeof(uint32_t) * bw->capacity);
|
||||
if(bw->buffer == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FLAC__bitwriter_free(FLAC__BitWriter *bw)
|
||||
{
|
||||
FLAC__ASSERT(0 != bw);
|
||||
|
||||
if(0 != bw->buffer)
|
||||
free(bw->buffer);
|
||||
bw->buffer = 0;
|
||||
bw->capacity = 0;
|
||||
bw->words = bw->bits = 0;
|
||||
}
|
||||
|
||||
void FLAC__bitwriter_clear(FLAC__BitWriter *bw)
|
||||
{
|
||||
bw->words = bw->bits = 0;
|
||||
}
|
||||
|
||||
void FLAC__bitwriter_dump(const FLAC__BitWriter *bw, FILE *out)
|
||||
{
|
||||
unsigned i, j;
|
||||
if(bw == 0) {
|
||||
fprintf(out, "bitwriter is NULL\n");
|
||||
}
|
||||
else {
|
||||
fprintf(out, "bitwriter: capacity=%u words=%u bits=%u total_bits=%u\n", bw->capacity, bw->words, bw->bits, FLAC__TOTAL_BITS(bw));
|
||||
|
||||
for(i = 0; i < bw->words; i++) {
|
||||
fprintf(out, "%08X: ", i);
|
||||
for(j = 0; j < FLAC__BITS_PER_WORD; j++)
|
||||
fprintf(out, "%01u", bw->buffer[i] & (1 << (FLAC__BITS_PER_WORD-j-1)) ? 1:0);
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
if(bw->bits > 0) {
|
||||
fprintf(out, "%08X: ", i);
|
||||
for(j = 0; j < bw->bits; j++)
|
||||
fprintf(out, "%01u", bw->accum & (1 << (bw->bits-j-1)) ? 1:0);
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__bitwriter_get_write_crc16(FLAC__BitWriter *bw, FLAC__uint16 *crc)
|
||||
{
|
||||
const FLAC__byte *buffer;
|
||||
size_t bytes;
|
||||
|
||||
FLAC__ASSERT((bw->bits & 7) == 0); /* assert that we're byte-aligned */
|
||||
|
||||
if(!FLAC__bitwriter_get_buffer(bw, &buffer, &bytes))
|
||||
return false;
|
||||
|
||||
*crc = (FLAC__uint16)FLAC__crc16(buffer, bytes);
|
||||
FLAC__bitwriter_release_buffer(bw);
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__bitwriter_get_write_crc8(FLAC__BitWriter *bw, FLAC__byte *crc)
|
||||
{
|
||||
const FLAC__byte *buffer;
|
||||
size_t bytes;
|
||||
|
||||
FLAC__ASSERT((bw->bits & 7) == 0); /* assert that we're byte-aligned */
|
||||
|
||||
if(!FLAC__bitwriter_get_buffer(bw, &buffer, &bytes))
|
||||
return false;
|
||||
|
||||
*crc = FLAC__crc8(buffer, bytes);
|
||||
FLAC__bitwriter_release_buffer(bw);
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__bitwriter_is_byte_aligned(const FLAC__BitWriter *bw)
|
||||
{
|
||||
return ((bw->bits & 7) == 0);
|
||||
}
|
||||
|
||||
unsigned FLAC__bitwriter_get_input_bits_unconsumed(const FLAC__BitWriter *bw)
|
||||
{
|
||||
return FLAC__TOTAL_BITS(bw);
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__bitwriter_get_buffer(FLAC__BitWriter *bw, const FLAC__byte **buffer, size_t *bytes)
|
||||
{
|
||||
FLAC__ASSERT((bw->bits & 7) == 0);
|
||||
/* double protection */
|
||||
if(bw->bits & 7)
|
||||
return false;
|
||||
/* if we have bits in the accumulator we have to flush those to the buffer first */
|
||||
if(bw->bits) {
|
||||
FLAC__ASSERT(bw->words <= bw->capacity);
|
||||
if(bw->words == bw->capacity && !bitwriter_grow_(bw, FLAC__BITS_PER_WORD))
|
||||
return false;
|
||||
/* append bits as complete word to buffer, but don't change bw->accum or bw->bits */
|
||||
bw->buffer[bw->words] = SWAP_BE_WORD_TO_HOST(bw->accum << (FLAC__BITS_PER_WORD-bw->bits));
|
||||
}
|
||||
/* now we can just return what we have */
|
||||
*buffer = (FLAC__byte*)bw->buffer;
|
||||
*bytes = (FLAC__BYTES_PER_WORD * bw->words) + (bw->bits >> 3);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FLAC__bitwriter_release_buffer(FLAC__BitWriter *bw)
|
||||
{
|
||||
/* nothing to do. in the future, strict checking of a 'writer-is-in-
|
||||
* get-mode' flag could be added everywhere and then cleared here
|
||||
*/
|
||||
(void)bw;
|
||||
}
|
||||
|
||||
inline FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bits)
|
||||
{
|
||||
unsigned n;
|
||||
|
||||
FLAC__ASSERT(0 != bw);
|
||||
FLAC__ASSERT(0 != bw->buffer);
|
||||
|
||||
if(bits == 0)
|
||||
return true;
|
||||
/* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+bits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */
|
||||
if(bw->capacity <= bw->words + bits && !bitwriter_grow_(bw, bits))
|
||||
return false;
|
||||
/* first part gets to word alignment */
|
||||
if(bw->bits) {
|
||||
n = flac_min(FLAC__BITS_PER_WORD - bw->bits, bits);
|
||||
bw->accum <<= n;
|
||||
bits -= n;
|
||||
bw->bits += n;
|
||||
if(bw->bits == FLAC__BITS_PER_WORD) {
|
||||
bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum);
|
||||
bw->bits = 0;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
/* do whole words */
|
||||
while(bits >= FLAC__BITS_PER_WORD) {
|
||||
bw->buffer[bw->words++] = 0;
|
||||
bits -= FLAC__BITS_PER_WORD;
|
||||
}
|
||||
/* do any leftovers */
|
||||
if(bits > 0) {
|
||||
bw->accum = 0;
|
||||
bw->bits = bits;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, unsigned bits)
|
||||
{
|
||||
register unsigned left;
|
||||
|
||||
/* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */
|
||||
FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32);
|
||||
|
||||
FLAC__ASSERT(0 != bw);
|
||||
FLAC__ASSERT(0 != bw->buffer);
|
||||
|
||||
FLAC__ASSERT(bits <= 32);
|
||||
if(bits == 0)
|
||||
return true;
|
||||
|
||||
/* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+bits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */
|
||||
if(bw->capacity <= bw->words + bits && !bitwriter_grow_(bw, bits))
|
||||
return false;
|
||||
|
||||
left = FLAC__BITS_PER_WORD - bw->bits;
|
||||
if(bits < left) {
|
||||
bw->accum <<= bits;
|
||||
bw->accum |= val;
|
||||
bw->bits += bits;
|
||||
}
|
||||
else if(bw->bits) { /* WATCHOUT: if bw->bits == 0, left==FLAC__BITS_PER_WORD and bw->accum<<=left is a NOP instead of setting to 0 */
|
||||
bw->accum <<= left;
|
||||
bw->accum |= val >> (bw->bits = bits - left);
|
||||
bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum);
|
||||
bw->accum = val;
|
||||
}
|
||||
else {
|
||||
bw->accum = val;
|
||||
bw->bits = 0;
|
||||
bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(val);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, unsigned bits)
|
||||
{
|
||||
/* zero-out unused bits */
|
||||
if(bits < 32)
|
||||
val &= (~(0xffffffff << bits));
|
||||
|
||||
return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits);
|
||||
}
|
||||
|
||||
inline FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, unsigned bits)
|
||||
{
|
||||
/* this could be a little faster but it's not used for much */
|
||||
if(bits > 32) {
|
||||
return
|
||||
FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)(val>>32), bits-32) &&
|
||||
FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, 32);
|
||||
}
|
||||
else
|
||||
return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits);
|
||||
}
|
||||
|
||||
inline FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val)
|
||||
{
|
||||
/* this doesn't need to be that fast as currently it is only used for vorbis comments */
|
||||
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, val & 0xff, 8))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, (val>>8) & 0xff, 8))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, (val>>16) & 0xff, 8))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, val>>24, 8))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], unsigned nvals)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* this could be faster but currently we don't need it to be since it's only used for writing metadata */
|
||||
for(i = 0; i < nvals; i++) {
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)(vals[i]), 8))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__bitwriter_write_unary_unsigned(FLAC__BitWriter *bw, unsigned val)
|
||||
{
|
||||
if(val < 32)
|
||||
return FLAC__bitwriter_write_raw_uint32(bw, 1, ++val);
|
||||
else
|
||||
return
|
||||
FLAC__bitwriter_write_zeroes(bw, val) &&
|
||||
FLAC__bitwriter_write_raw_uint32(bw, 1, 1);
|
||||
}
|
||||
|
||||
unsigned FLAC__bitwriter_rice_bits(FLAC__int32 val, unsigned parameter)
|
||||
{
|
||||
FLAC__uint32 uval;
|
||||
|
||||
FLAC__ASSERT(parameter < sizeof(unsigned)*8);
|
||||
|
||||
/* fold signed to unsigned; actual formula is: negative(v)? -2v-1 : 2v */
|
||||
uval = (val<<1) ^ (val>>31);
|
||||
|
||||
return 1 + parameter + (uval >> parameter);
|
||||
}
|
||||
|
||||
#if 0 /* UNUSED */
|
||||
unsigned FLAC__bitwriter_golomb_bits_signed(int val, unsigned parameter)
|
||||
{
|
||||
unsigned bits, msbs, uval;
|
||||
unsigned k;
|
||||
|
||||
FLAC__ASSERT(parameter > 0);
|
||||
|
||||
/* fold signed to unsigned */
|
||||
if(val < 0)
|
||||
uval = (unsigned)(((-(++val)) << 1) + 1);
|
||||
else
|
||||
uval = (unsigned)(val << 1);
|
||||
|
||||
k = FLAC__bitmath_ilog2(parameter);
|
||||
if(parameter == 1u<<k) {
|
||||
FLAC__ASSERT(k <= 30);
|
||||
|
||||
msbs = uval >> k;
|
||||
bits = 1 + k + msbs;
|
||||
}
|
||||
else {
|
||||
unsigned q, r, d;
|
||||
|
||||
d = (1 << (k+1)) - parameter;
|
||||
q = uval / parameter;
|
||||
r = uval - (q * parameter);
|
||||
|
||||
bits = 1 + q + k;
|
||||
if(r >= d)
|
||||
bits++;
|
||||
}
|
||||
return bits;
|
||||
}
|
||||
|
||||
unsigned FLAC__bitwriter_golomb_bits_unsigned(unsigned uval, unsigned parameter)
|
||||
{
|
||||
unsigned bits, msbs;
|
||||
unsigned k;
|
||||
|
||||
FLAC__ASSERT(parameter > 0);
|
||||
|
||||
k = FLAC__bitmath_ilog2(parameter);
|
||||
if(parameter == 1u<<k) {
|
||||
FLAC__ASSERT(k <= 30);
|
||||
|
||||
msbs = uval >> k;
|
||||
bits = 1 + k + msbs;
|
||||
}
|
||||
else {
|
||||
unsigned q, r, d;
|
||||
|
||||
d = (1 << (k+1)) - parameter;
|
||||
q = uval / parameter;
|
||||
r = uval - (q * parameter);
|
||||
|
||||
bits = 1 + q + k;
|
||||
if(r >= d)
|
||||
bits++;
|
||||
}
|
||||
return bits;
|
||||
}
|
||||
#endif /* UNUSED */
|
||||
|
||||
FLAC__bool FLAC__bitwriter_write_rice_signed(FLAC__BitWriter *bw, FLAC__int32 val, unsigned parameter)
|
||||
{
|
||||
unsigned total_bits, interesting_bits, msbs;
|
||||
FLAC__uint32 uval, pattern;
|
||||
|
||||
FLAC__ASSERT(0 != bw);
|
||||
FLAC__ASSERT(0 != bw->buffer);
|
||||
FLAC__ASSERT(parameter < 8*sizeof(uval));
|
||||
|
||||
/* fold signed to unsigned; actual formula is: negative(v)? -2v-1 : 2v */
|
||||
uval = (val<<1) ^ (val>>31);
|
||||
|
||||
msbs = uval >> parameter;
|
||||
interesting_bits = 1 + parameter;
|
||||
total_bits = interesting_bits + msbs;
|
||||
pattern = 1 << parameter; /* the unary end bit */
|
||||
pattern |= (uval & ((1<<parameter)-1)); /* the binary LSBs */
|
||||
|
||||
if(total_bits <= 32)
|
||||
return FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits);
|
||||
else
|
||||
return
|
||||
FLAC__bitwriter_write_zeroes(bw, msbs) && /* write the unary MSBs */
|
||||
FLAC__bitwriter_write_raw_uint32(bw, pattern, interesting_bits); /* write the unary end bit and binary LSBs */
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FLAC__int32 *vals, unsigned nvals, unsigned parameter)
|
||||
{
|
||||
const FLAC__uint32 mask1 = FLAC__WORD_ALL_ONES << parameter; /* we val|=mask1 to set the stop bit above it... */
|
||||
const FLAC__uint32 mask2 = FLAC__WORD_ALL_ONES >> (31-parameter); /* ...then mask off the bits above the stop bit with val&=mask2*/
|
||||
FLAC__uint32 uval;
|
||||
unsigned left;
|
||||
const unsigned lsbits = 1 + parameter;
|
||||
unsigned msbits;
|
||||
|
||||
FLAC__ASSERT(0 != bw);
|
||||
FLAC__ASSERT(0 != bw->buffer);
|
||||
FLAC__ASSERT(parameter < 8*sizeof(uint32_t)-1);
|
||||
/* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */
|
||||
FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32);
|
||||
|
||||
while(nvals) {
|
||||
/* fold signed to unsigned; actual formula is: negative(v)? -2v-1 : 2v */
|
||||
uval = (*vals<<1) ^ (*vals>>31);
|
||||
|
||||
msbits = uval >> parameter;
|
||||
|
||||
if(bw->bits && bw->bits + msbits + lsbits < FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current uint32_t */
|
||||
/* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free uint32_t to work in */
|
||||
bw->bits = bw->bits + msbits + lsbits;
|
||||
uval |= mask1; /* set stop bit */
|
||||
uval &= mask2; /* mask off unused top bits */
|
||||
bw->accum <<= msbits + lsbits;
|
||||
bw->accum |= uval;
|
||||
}
|
||||
else {
|
||||
/* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+msbits+lsbits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */
|
||||
/* OPT: pessimism may cause flurry of false calls to grow_ which eat up all savings before it */
|
||||
if(bw->capacity <= bw->words + bw->bits + msbits + 1/*lsbits always fit in 1 uint32_t*/ && !bitwriter_grow_(bw, msbits+lsbits))
|
||||
return false;
|
||||
|
||||
if(msbits) {
|
||||
/* first part gets to word alignment */
|
||||
if(bw->bits) {
|
||||
left = FLAC__BITS_PER_WORD - bw->bits;
|
||||
if(msbits < left) {
|
||||
bw->accum <<= msbits;
|
||||
bw->bits += msbits;
|
||||
goto break1;
|
||||
}
|
||||
else {
|
||||
bw->accum <<= left;
|
||||
msbits -= left;
|
||||
bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum);
|
||||
bw->bits = 0;
|
||||
}
|
||||
}
|
||||
/* do whole words */
|
||||
while(msbits >= FLAC__BITS_PER_WORD) {
|
||||
bw->buffer[bw->words++] = 0;
|
||||
msbits -= FLAC__BITS_PER_WORD;
|
||||
}
|
||||
/* do any leftovers */
|
||||
if(msbits > 0) {
|
||||
bw->accum = 0;
|
||||
bw->bits = msbits;
|
||||
}
|
||||
}
|
||||
break1:
|
||||
uval |= mask1; /* set stop bit */
|
||||
uval &= mask2; /* mask off unused top bits */
|
||||
|
||||
left = FLAC__BITS_PER_WORD - bw->bits;
|
||||
if(lsbits < left) {
|
||||
bw->accum <<= lsbits;
|
||||
bw->accum |= uval;
|
||||
bw->bits += lsbits;
|
||||
}
|
||||
else {
|
||||
/* if bw->bits == 0, left==FLAC__BITS_PER_WORD which will always
|
||||
* be > lsbits (because of previous assertions) so it would have
|
||||
* triggered the (lsbits<left) case above.
|
||||
*/
|
||||
FLAC__ASSERT(bw->bits);
|
||||
FLAC__ASSERT(left < FLAC__BITS_PER_WORD);
|
||||
bw->accum <<= left;
|
||||
bw->accum |= uval >> (bw->bits = lsbits - left);
|
||||
bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum);
|
||||
bw->accum = uval;
|
||||
}
|
||||
}
|
||||
vals++;
|
||||
nvals--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0 /* UNUSED */
|
||||
FLAC__bool FLAC__bitwriter_write_golomb_signed(FLAC__BitWriter *bw, int val, unsigned parameter)
|
||||
{
|
||||
unsigned total_bits, msbs, uval;
|
||||
unsigned k;
|
||||
|
||||
FLAC__ASSERT(0 != bw);
|
||||
FLAC__ASSERT(0 != bw->buffer);
|
||||
FLAC__ASSERT(parameter > 0);
|
||||
|
||||
/* fold signed to unsigned */
|
||||
if(val < 0)
|
||||
uval = (unsigned)(((-(++val)) << 1) + 1);
|
||||
else
|
||||
uval = (unsigned)(val << 1);
|
||||
|
||||
k = FLAC__bitmath_ilog2(parameter);
|
||||
if(parameter == 1u<<k) {
|
||||
unsigned pattern;
|
||||
|
||||
FLAC__ASSERT(k <= 30);
|
||||
|
||||
msbs = uval >> k;
|
||||
total_bits = 1 + k + msbs;
|
||||
pattern = 1 << k; /* the unary end bit */
|
||||
pattern |= (uval & ((1u<<k)-1)); /* the binary LSBs */
|
||||
|
||||
if(total_bits <= 32) {
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
/* write the unary MSBs */
|
||||
if(!FLAC__bitwriter_write_zeroes(bw, msbs))
|
||||
return false;
|
||||
/* write the unary end bit and binary LSBs */
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, k+1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned q, r, d;
|
||||
|
||||
d = (1 << (k+1)) - parameter;
|
||||
q = uval / parameter;
|
||||
r = uval - (q * parameter);
|
||||
/* write the unary MSBs */
|
||||
if(!FLAC__bitwriter_write_zeroes(bw, q))
|
||||
return false;
|
||||
/* write the unary end bit */
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, 1, 1))
|
||||
return false;
|
||||
/* write the binary LSBs */
|
||||
if(r >= d) {
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, r+d, k+1))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, r, k))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__bitwriter_write_golomb_unsigned(FLAC__BitWriter *bw, unsigned uval, unsigned parameter)
|
||||
{
|
||||
unsigned total_bits, msbs;
|
||||
unsigned k;
|
||||
|
||||
FLAC__ASSERT(0 != bw);
|
||||
FLAC__ASSERT(0 != bw->buffer);
|
||||
FLAC__ASSERT(parameter > 0);
|
||||
|
||||
k = FLAC__bitmath_ilog2(parameter);
|
||||
if(parameter == 1u<<k) {
|
||||
unsigned pattern;
|
||||
|
||||
FLAC__ASSERT(k <= 30);
|
||||
|
||||
msbs = uval >> k;
|
||||
total_bits = 1 + k + msbs;
|
||||
pattern = 1 << k; /* the unary end bit */
|
||||
pattern |= (uval & ((1u<<k)-1)); /* the binary LSBs */
|
||||
|
||||
if(total_bits <= 32) {
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
/* write the unary MSBs */
|
||||
if(!FLAC__bitwriter_write_zeroes(bw, msbs))
|
||||
return false;
|
||||
/* write the unary end bit and binary LSBs */
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, k+1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned q, r, d;
|
||||
|
||||
d = (1 << (k+1)) - parameter;
|
||||
q = uval / parameter;
|
||||
r = uval - (q * parameter);
|
||||
/* write the unary MSBs */
|
||||
if(!FLAC__bitwriter_write_zeroes(bw, q))
|
||||
return false;
|
||||
/* write the unary end bit */
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, 1, 1))
|
||||
return false;
|
||||
/* write the binary LSBs */
|
||||
if(r >= d) {
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, r+d, k+1))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, r, k))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif /* UNUSED */
|
||||
|
||||
FLAC__bool FLAC__bitwriter_write_utf8_uint32(FLAC__BitWriter *bw, FLAC__uint32 val)
|
||||
{
|
||||
FLAC__bool ok = 1;
|
||||
|
||||
FLAC__ASSERT(0 != bw);
|
||||
FLAC__ASSERT(0 != bw->buffer);
|
||||
|
||||
FLAC__ASSERT(!(val & 0x80000000)); /* this version only handles 31 bits */
|
||||
|
||||
if(val < 0x80) {
|
||||
return FLAC__bitwriter_write_raw_uint32(bw, val, 8);
|
||||
}
|
||||
else if(val < 0x800) {
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xC0 | (val>>6), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8);
|
||||
}
|
||||
else if(val < 0x10000) {
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xE0 | (val>>12), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>6)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8);
|
||||
}
|
||||
else if(val < 0x200000) {
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xF0 | (val>>18), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>12)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>6)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8);
|
||||
}
|
||||
else if(val < 0x4000000) {
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xF8 | (val>>24), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>18)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>12)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>6)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8);
|
||||
}
|
||||
else {
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xFC | (val>>30), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>24)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>18)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>12)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>6)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__bitwriter_write_utf8_uint64(FLAC__BitWriter *bw, FLAC__uint64 val)
|
||||
{
|
||||
FLAC__bool ok = 1;
|
||||
|
||||
FLAC__ASSERT(0 != bw);
|
||||
FLAC__ASSERT(0 != bw->buffer);
|
||||
|
||||
FLAC__ASSERT(!(val & FLAC__U64L(0xFFFFFFF000000000))); /* this version only handles 36 bits */
|
||||
|
||||
if(val < 0x80) {
|
||||
return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, 8);
|
||||
}
|
||||
else if(val < 0x800) {
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xC0 | (FLAC__uint32)(val>>6), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8);
|
||||
}
|
||||
else if(val < 0x10000) {
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xE0 | (FLAC__uint32)(val>>12), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8);
|
||||
}
|
||||
else if(val < 0x200000) {
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xF0 | (FLAC__uint32)(val>>18), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8);
|
||||
}
|
||||
else if(val < 0x4000000) {
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xF8 | (FLAC__uint32)(val>>24), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8);
|
||||
}
|
||||
else if(val < 0x80000000) {
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xFC | (FLAC__uint32)(val>>30), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>24)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8);
|
||||
}
|
||||
else {
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xFE, 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>30)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>24)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8);
|
||||
ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw)
|
||||
{
|
||||
/* 0-pad to byte boundary */
|
||||
if(bw->bits & 7u)
|
||||
return FLAC__bitwriter_write_zeroes(bw, 8 - (bw->bits & 7u));
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
/* These functions are declared inline in this file but are also callable as
|
||||
* externs from elsewhere.
|
||||
* According to the C99 spec, section 6.7.4, simply providing a function
|
||||
* prototype in a header file without 'inline' and making the function inline
|
||||
* in this file should be sufficient.
|
||||
* Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To
|
||||
* fix that we add extern declarations here.
|
||||
*/
|
||||
extern FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bits);
|
||||
extern FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, unsigned bits);
|
||||
extern FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, unsigned bits);
|
||||
extern FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val);
|
||||
extern FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], unsigned nvals);
|
||||
|
|
@ -0,0 +1,487 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/cpu.h"
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined FLAC__CPU_IA32
|
||||
# include <signal.h>
|
||||
|
||||
static void disable_sse(FLAC__CPUInfo *info)
|
||||
{
|
||||
info->ia32.sse = false;
|
||||
info->ia32.sse2 = false;
|
||||
info->ia32.sse3 = false;
|
||||
info->ia32.ssse3 = false;
|
||||
info->ia32.sse41 = false;
|
||||
info->ia32.sse42 = false;
|
||||
}
|
||||
|
||||
static void disable_avx(FLAC__CPUInfo *info)
|
||||
{
|
||||
info->ia32.avx = false;
|
||||
info->ia32.avx2 = false;
|
||||
info->ia32.fma = false;
|
||||
}
|
||||
|
||||
#elif defined FLAC__CPU_X86_64
|
||||
|
||||
static void disable_avx(FLAC__CPUInfo *info)
|
||||
{
|
||||
info->x86.avx = false;
|
||||
info->x86.avx2 = false;
|
||||
info->x86.fma = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (__NetBSD__) || defined(__OpenBSD__)
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <machine/cpu.h>
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
/* how to get sysctlbyname()? */
|
||||
#endif
|
||||
|
||||
#ifdef FLAC__CPU_IA32
|
||||
/* these are flags in EDX of CPUID AX=00000001 */
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000;
|
||||
#endif
|
||||
|
||||
/* these are flags in ECX of CPUID AX=00000001 */
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE3 = 0x00000001;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSSE3 = 0x00000200;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE41 = 0x00080000;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE42 = 0x00100000;
|
||||
|
||||
#if defined FLAC__AVX_SUPPORTED
|
||||
/* these are flags in ECX of CPUID AX=00000001 */
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_OSXSAVE = 0x08000000;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX = 0x10000000;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_FMA = 0x00001000;
|
||||
/* these are flags in EBX of CPUID AX=00000007 */
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX2 = 0x00000020;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Extra stuff needed for detection of OS support for SSE on IA-32
|
||||
*/
|
||||
#if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || defined FLAC__HAS_X86INTRIN) && !defined FLAC__NO_SSE_OS && !defined FLAC__SSE_OS
|
||||
# if defined(__linux__)
|
||||
/*
|
||||
* If the OS doesn't support SSE, we will get here with a SIGILL. We
|
||||
* modify the return address to jump over the offending SSE instruction
|
||||
* and also the operation following it that indicates the instruction
|
||||
* executed successfully. In this way we use no global variables and
|
||||
* stay thread-safe.
|
||||
*
|
||||
* 3 + 3 + 6:
|
||||
* 3 bytes for "xorps xmm0,xmm0"
|
||||
* 3 bytes for estimate of how long the follwing "inc var" instruction is
|
||||
* 6 bytes extra in case our estimate is wrong
|
||||
* 12 bytes puts us in the NOP "landing zone"
|
||||
*/
|
||||
# include <sys/ucontext.h>
|
||||
static void sigill_handler_sse_os(int signal, siginfo_t *si, void *uc)
|
||||
{
|
||||
(void)signal, (void)si;
|
||||
((ucontext_t*)uc)->uc_mcontext.gregs[14/*REG_EIP*/] += 3 + 3 + 6;
|
||||
}
|
||||
# elif defined(_MSC_VER)
|
||||
# include <windows.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
void FLAC__cpu_info(FLAC__CPUInfo *info)
|
||||
{
|
||||
/*
|
||||
* IA32-specific
|
||||
*/
|
||||
#ifdef FLAC__CPU_IA32
|
||||
FLAC__bool ia32_fxsr = false;
|
||||
FLAC__bool ia32_osxsave = false;
|
||||
(void) ia32_fxsr; (void) ia32_osxsave; /* to avoid warnings about unused variables */
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->type = FLAC__CPUINFO_TYPE_IA32;
|
||||
#if !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || defined FLAC__HAS_X86INTRIN)
|
||||
info->use_asm = true; /* we assume a minimum of 80386 with FLAC__CPU_IA32 */
|
||||
#ifdef FLAC__HAS_X86INTRIN
|
||||
if(!FLAC__cpu_have_cpuid_x86())
|
||||
return;
|
||||
#else
|
||||
if(!FLAC__cpu_have_cpuid_asm_ia32())
|
||||
return;
|
||||
#endif
|
||||
{
|
||||
/* http://www.sandpile.org/x86/cpuid.htm */
|
||||
#ifdef FLAC__HAS_X86INTRIN
|
||||
FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx;
|
||||
FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
|
||||
#else
|
||||
FLAC__uint32 flags_ecx, flags_edx;
|
||||
FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx);
|
||||
#endif
|
||||
info->ia32.cmov = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CMOV )? true : false;
|
||||
info->ia32.mmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MMX )? true : false;
|
||||
ia32_fxsr = (flags_edx & FLAC__CPUINFO_IA32_CPUID_FXSR )? true : false;
|
||||
info->ia32.sse = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE )? true : false;
|
||||
info->ia32.sse2 = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE2 )? true : false;
|
||||
info->ia32.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false;
|
||||
info->ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false;
|
||||
info->ia32.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41)? true : false;
|
||||
info->ia32.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42)? true : false;
|
||||
#if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED
|
||||
ia32_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE)? true : false;
|
||||
info->ia32.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX )? true : false;
|
||||
info->ia32.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA )? true : false;
|
||||
FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
|
||||
info->ia32.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 )? true : false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "CPU info (IA-32):\n");
|
||||
fprintf(stderr, " CMOV ....... %c\n", info->ia32.cmov ? 'Y' : 'n');
|
||||
fprintf(stderr, " MMX ........ %c\n", info->ia32.mmx ? 'Y' : 'n');
|
||||
fprintf(stderr, " SSE ........ %c\n", info->ia32.sse ? 'Y' : 'n');
|
||||
fprintf(stderr, " SSE2 ....... %c\n", info->ia32.sse2 ? 'Y' : 'n');
|
||||
fprintf(stderr, " SSE3 ....... %c\n", info->ia32.sse3 ? 'Y' : 'n');
|
||||
fprintf(stderr, " SSSE3 ...... %c\n", info->ia32.ssse3 ? 'Y' : 'n');
|
||||
fprintf(stderr, " SSE41 ...... %c\n", info->ia32.sse41 ? 'Y' : 'n');
|
||||
fprintf(stderr, " SSE42 ...... %c\n", info->ia32.sse42 ? 'Y' : 'n');
|
||||
# if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED
|
||||
fprintf(stderr, " AVX ........ %c\n", info->ia32.avx ? 'Y' : 'n');
|
||||
fprintf(stderr, " FMA ........ %c\n", info->ia32.fma ? 'Y' : 'n');
|
||||
fprintf(stderr, " AVX2 ....... %c\n", info->ia32.avx2 ? 'Y' : 'n');
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* now have to check for OS support of SSE instructions
|
||||
*/
|
||||
if(info->ia32.sse) {
|
||||
#if defined FLAC__NO_SSE_OS
|
||||
/* assume user knows better than us; turn it off */
|
||||
disable_sse(info);
|
||||
#elif defined FLAC__SSE_OS
|
||||
/* assume user knows better than us; leave as detected above */
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__APPLE__)
|
||||
int sse = 0;
|
||||
size_t len;
|
||||
/* at least one of these must work: */
|
||||
len = sizeof(sse); sse = sse || (sysctlbyname("hw.instruction_sse", &sse, &len, NULL, 0) == 0 && sse);
|
||||
len = sizeof(sse); sse = sse || (sysctlbyname("hw.optional.sse" , &sse, &len, NULL, 0) == 0 && sse); /* __APPLE__ ? */
|
||||
if(!sse)
|
||||
disable_sse(info);
|
||||
#elif defined(__NetBSD__) || defined (__OpenBSD__)
|
||||
# if __NetBSD_Version__ >= 105250000 || (defined __OpenBSD__)
|
||||
int val = 0, mib[2] = { CTL_MACHDEP, CPU_SSE };
|
||||
size_t len = sizeof(val);
|
||||
if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val)
|
||||
disable_sse(info);
|
||||
else { /* double-check SSE2 */
|
||||
mib[1] = CPU_SSE2;
|
||||
len = sizeof(val);
|
||||
if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) {
|
||||
disable_sse(info);
|
||||
info->ia32.sse = true;
|
||||
}
|
||||
}
|
||||
# else
|
||||
disable_sse(info);
|
||||
# endif
|
||||
#elif defined(__linux__)
|
||||
int sse = 0;
|
||||
struct sigaction sigill_save;
|
||||
struct sigaction sigill_sse;
|
||||
sigill_sse.sa_sigaction = sigill_handler_sse_os;
|
||||
__sigemptyset(&sigill_sse.sa_mask);
|
||||
sigill_sse.sa_flags = SA_SIGINFO | SA_RESETHAND; /* SA_RESETHAND just in case our SIGILL return jump breaks, so we don't get stuck in a loop */
|
||||
if(0 == sigaction(SIGILL, &sigill_sse, &sigill_save))
|
||||
{
|
||||
/* http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html */
|
||||
/* see sigill_handler_sse_os() for an explanation of the following: */
|
||||
asm volatile (
|
||||
"xorps %%xmm0,%%xmm0\n\t" /* will cause SIGILL if unsupported by OS */
|
||||
"incl %0\n\t" /* SIGILL handler will jump over this */
|
||||
/* landing zone */
|
||||
"nop\n\t" /* SIGILL jump lands here if "inc" is 9 bytes */
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t" /* SIGILL jump lands here if "inc" is 3 bytes (expected) */
|
||||
"nop\n\t"
|
||||
"nop" /* SIGILL jump lands here if "inc" is 1 byte */
|
||||
: "=r"(sse)
|
||||
: "0"(sse)
|
||||
);
|
||||
|
||||
sigaction(SIGILL, &sigill_save, NULL);
|
||||
}
|
||||
|
||||
if(!sse)
|
||||
disable_sse(info);
|
||||
#elif defined(_MSC_VER)
|
||||
__try {
|
||||
__asm {
|
||||
xorps xmm0,xmm0
|
||||
}
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION)
|
||||
disable_sse(info);
|
||||
}
|
||||
#elif defined(__GNUC__) /* MinGW goes here */
|
||||
int sse = 0;
|
||||
/* Based on the idea described in Agner Fog's manual "Optimizing subroutines in assembly language" */
|
||||
/* In theory, not guaranteed to detect lack of OS SSE support on some future Intel CPUs, but in practice works (see the aforementioned manual) */
|
||||
if (ia32_fxsr) {
|
||||
struct {
|
||||
FLAC__uint32 buff[128];
|
||||
} __attribute__((aligned(16))) fxsr;
|
||||
FLAC__uint32 old_val, new_val;
|
||||
|
||||
asm volatile ("fxsave %0" : "=m" (fxsr) : "m" (fxsr));
|
||||
old_val = fxsr.buff[50];
|
||||
fxsr.buff[50] ^= 0x0013c0de; /* change value in the buffer */
|
||||
asm volatile ("fxrstor %0" : "=m" (fxsr) : "m" (fxsr)); /* try to change SSE register */
|
||||
fxsr.buff[50] = old_val; /* restore old value in the buffer */
|
||||
asm volatile ("fxsave %0 " : "=m" (fxsr) : "m" (fxsr)); /* old value will be overwritten if SSE register was changed */
|
||||
new_val = fxsr.buff[50]; /* == old_val if FXRSTOR didn't change SSE register and (old_val ^ 0x0013c0de) otherwise */
|
||||
fxsr.buff[50] = old_val; /* again restore old value in the buffer */
|
||||
asm volatile ("fxrstor %0" : "=m" (fxsr) : "m" (fxsr)); /* restore old values of registers */
|
||||
|
||||
if ((old_val^new_val) == 0x0013c0de)
|
||||
sse = 1;
|
||||
}
|
||||
if(!sse)
|
||||
disable_sse(info);
|
||||
#else
|
||||
/* no way to test, disable to be safe */
|
||||
disable_sse(info);
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, " SSE OS sup . %c\n", info->ia32.sse ? 'Y' : 'n');
|
||||
#endif
|
||||
}
|
||||
else /* info->ia32.sse == false */
|
||||
disable_sse(info);
|
||||
|
||||
/*
|
||||
* now have to check for OS support of AVX instructions
|
||||
*/
|
||||
if(info->ia32.avx && ia32_osxsave) {
|
||||
FLAC__uint32 ecr = FLAC__cpu_xgetbv_x86();
|
||||
if ((ecr & 0x6) != 0x6)
|
||||
disable_avx(info);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, " AVX OS sup . %c\n", info->ia32.avx ? 'Y' : 'n');
|
||||
#endif
|
||||
}
|
||||
else /* no OS AVX support*/
|
||||
disable_avx(info);
|
||||
#else
|
||||
info->use_asm = false;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* x86-64-specific
|
||||
*/
|
||||
#elif defined FLAC__CPU_X86_64
|
||||
FLAC__bool x86_osxsave = false;
|
||||
(void) x86_osxsave; /* to avoid warnings about unused variables */
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->type = FLAC__CPUINFO_TYPE_X86_64;
|
||||
#if !defined FLAC__NO_ASM && defined FLAC__HAS_X86INTRIN
|
||||
info->use_asm = true;
|
||||
{
|
||||
/* http://www.sandpile.org/x86/cpuid.htm */
|
||||
FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx;
|
||||
FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
|
||||
info->x86.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false;
|
||||
info->x86.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false;
|
||||
info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41)? true : false;
|
||||
info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42)? true : false;
|
||||
#if defined FLAC__AVX_SUPPORTED
|
||||
x86_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE)? true : false;
|
||||
info->x86.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX )? true : false;
|
||||
info->x86.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA )? true : false;
|
||||
FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
|
||||
info->x86.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 )? true : false;
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "CPU info (x86-64):\n");
|
||||
fprintf(stderr, " SSE3 ....... %c\n", info->x86.sse3 ? 'Y' : 'n');
|
||||
fprintf(stderr, " SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n');
|
||||
fprintf(stderr, " SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n');
|
||||
fprintf(stderr, " SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n');
|
||||
# if defined FLAC__AVX_SUPPORTED
|
||||
fprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n');
|
||||
fprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n');
|
||||
fprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n');
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* now have to check for OS support of AVX instructions
|
||||
*/
|
||||
if(info->x86.avx && x86_osxsave) {
|
||||
FLAC__uint32 ecr = FLAC__cpu_xgetbv_x86();
|
||||
if ((ecr & 0x6) != 0x6)
|
||||
disable_avx(info);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n');
|
||||
#endif
|
||||
}
|
||||
else /* no OS AVX support*/
|
||||
disable_avx(info);
|
||||
#else
|
||||
info->use_asm = false;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* unknown CPU
|
||||
*/
|
||||
#else
|
||||
info->type = FLAC__CPUINFO_TYPE_UNKNOWN;
|
||||
info->use_asm = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
|
||||
|
||||
#if defined _MSC_VER
|
||||
#include <intrin.h> /* for __cpuid() and _xgetbv() */
|
||||
#elif defined __GNUC__ && defined HAVE_CPUID_H
|
||||
#include <cpuid.h> /* for __get_cpuid() and __get_cpuid_max() */
|
||||
#endif
|
||||
|
||||
FLAC__uint32 FLAC__cpu_have_cpuid_x86(void)
|
||||
{
|
||||
#ifdef FLAC__CPU_X86_64
|
||||
return 1;
|
||||
#else
|
||||
# if defined _MSC_VER || defined __INTEL_COMPILER /* Do they support CPUs w/o CPUID support (or OSes that work on those CPUs)? */
|
||||
FLAC__uint32 flags1, flags2;
|
||||
__asm {
|
||||
pushfd
|
||||
pushfd
|
||||
pop eax
|
||||
mov flags1, eax
|
||||
xor eax, 0x200000
|
||||
push eax
|
||||
popfd
|
||||
pushfd
|
||||
pop eax
|
||||
mov flags2, eax
|
||||
popfd
|
||||
}
|
||||
if (((flags1^flags2) & 0x200000) != 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
# elif defined __GNUC__ && defined HAVE_CPUID_H
|
||||
if (__get_cpuid_max(0, 0) != 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
# else
|
||||
return 0;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx)
|
||||
{
|
||||
#if defined _MSC_VER || defined __INTEL_COMPILER
|
||||
int cpuinfo[4];
|
||||
int ext = level & 0x80000000;
|
||||
__cpuid(cpuinfo, ext);
|
||||
if((unsigned)cpuinfo[0] < level) {
|
||||
*eax = *ebx = *ecx = *edx = 0;
|
||||
return;
|
||||
}
|
||||
#if defined FLAC__AVX_SUPPORTED
|
||||
__cpuidex(cpuinfo, level, 0); /* for AVX2 detection */
|
||||
#else
|
||||
__cpuid(cpuinfo, level); /* some old compilers don't support __cpuidex */
|
||||
#endif
|
||||
*eax = cpuinfo[0]; *ebx = cpuinfo[1]; *ecx = cpuinfo[2]; *edx = cpuinfo[3];
|
||||
#elif defined __GNUC__ && defined HAVE_CPUID_H
|
||||
FLAC__uint32 ext = level & 0x80000000;
|
||||
__cpuid(ext, *eax, *ebx, *ecx, *edx);
|
||||
if (*eax < level) {
|
||||
*eax = *ebx = *ecx = *edx = 0;
|
||||
return;
|
||||
}
|
||||
__cpuid_count(level, 0, *eax, *ebx, *ecx, *edx);
|
||||
#else
|
||||
*eax = *ebx = *ecx = *edx = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FLAC__uint32 FLAC__cpu_xgetbv_x86(void)
|
||||
{
|
||||
#if (defined _MSC_VER || defined __INTEL_COMPILER) && defined FLAC__AVX_SUPPORTED
|
||||
return (FLAC__uint32)_xgetbv(0);
|
||||
#elif defined __GNUC__
|
||||
FLAC__uint32 lo, hi;
|
||||
asm volatile (".byte 0x0f, 0x01, 0xd0" : "=a"(lo), "=d"(hi) : "c" (0));
|
||||
return lo;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/crc.h"
|
||||
|
||||
/* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
|
||||
|
||||
FLAC__byte const FLAC__crc8_table[256] = {
|
||||
0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
|
||||
0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
|
||||
0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
|
||||
0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
|
||||
0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
|
||||
0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
|
||||
0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
|
||||
0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
|
||||
0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
|
||||
0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
|
||||
0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
|
||||
0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
|
||||
0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
|
||||
0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
|
||||
0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
|
||||
0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
|
||||
0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
|
||||
0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
|
||||
0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
|
||||
0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
|
||||
0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
|
||||
0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
|
||||
0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
|
||||
0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
|
||||
0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
|
||||
0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
|
||||
0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
|
||||
0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
|
||||
0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
|
||||
0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
|
||||
0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
|
||||
0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
|
||||
};
|
||||
|
||||
/* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */
|
||||
|
||||
unsigned const FLAC__crc16_table[256] = {
|
||||
0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011,
|
||||
0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022,
|
||||
0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072,
|
||||
0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041,
|
||||
0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2,
|
||||
0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1,
|
||||
0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1,
|
||||
0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082,
|
||||
0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
|
||||
0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1,
|
||||
0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1,
|
||||
0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2,
|
||||
0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151,
|
||||
0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162,
|
||||
0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132,
|
||||
0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101,
|
||||
0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312,
|
||||
0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
|
||||
0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371,
|
||||
0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342,
|
||||
0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1,
|
||||
0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2,
|
||||
0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2,
|
||||
0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381,
|
||||
0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291,
|
||||
0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2,
|
||||
0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
|
||||
0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1,
|
||||
0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252,
|
||||
0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261,
|
||||
0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231,
|
||||
0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202
|
||||
};
|
||||
|
||||
|
||||
void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc)
|
||||
{
|
||||
*crc = FLAC__crc8_table[*crc ^ data];
|
||||
}
|
||||
|
||||
void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc)
|
||||
{
|
||||
while(len--)
|
||||
*crc = FLAC__crc8_table[*crc ^ *data++];
|
||||
}
|
||||
|
||||
FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len)
|
||||
{
|
||||
FLAC__uint8 crc = 0;
|
||||
|
||||
while(len--)
|
||||
crc = FLAC__crc8_table[crc ^ *data++];
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
unsigned FLAC__crc16(const FLAC__byte *data, unsigned len)
|
||||
{
|
||||
unsigned crc = 0;
|
||||
|
||||
while(len--)
|
||||
crc = ((crc<<8) ^ FLAC__crc16_table[(crc>>8) ^ *data++]) & 0xffff;
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
|
@ -0,0 +1,419 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "share/compat.h"
|
||||
#include "private/bitmath.h"
|
||||
#include "private/fixed.h"
|
||||
#include "private/macros.h"
|
||||
#include "FLAC/assert.h"
|
||||
|
||||
#ifdef local_abs
|
||||
#undef local_abs
|
||||
#endif
|
||||
#define local_abs(x) ((unsigned)((x)<0? -(x) : (x)))
|
||||
|
||||
#ifdef FLAC__INTEGER_ONLY_LIBRARY
|
||||
/* rbps stands for residual bits per sample
|
||||
*
|
||||
* (ln(2) * err)
|
||||
* rbps = log (-----------)
|
||||
* 2 ( n )
|
||||
*/
|
||||
static FLAC__fixedpoint local__compute_rbps_integerized(FLAC__uint32 err, FLAC__uint32 n)
|
||||
{
|
||||
FLAC__uint32 rbps;
|
||||
unsigned bits; /* the number of bits required to represent a number */
|
||||
int fracbits; /* the number of bits of rbps that comprise the fractional part */
|
||||
|
||||
FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint));
|
||||
FLAC__ASSERT(err > 0);
|
||||
FLAC__ASSERT(n > 0);
|
||||
|
||||
FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE);
|
||||
if(err <= n)
|
||||
return 0;
|
||||
/*
|
||||
* The above two things tell us 1) n fits in 16 bits; 2) err/n > 1.
|
||||
* These allow us later to know we won't lose too much precision in the
|
||||
* fixed-point division (err<<fracbits)/n.
|
||||
*/
|
||||
|
||||
fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2(err)+1);
|
||||
|
||||
err <<= fracbits;
|
||||
err /= n;
|
||||
/* err now holds err/n with fracbits fractional bits */
|
||||
|
||||
/*
|
||||
* Whittle err down to 16 bits max. 16 significant bits is enough for
|
||||
* our purposes.
|
||||
*/
|
||||
FLAC__ASSERT(err > 0);
|
||||
bits = FLAC__bitmath_ilog2(err)+1;
|
||||
if(bits > 16) {
|
||||
err >>= (bits-16);
|
||||
fracbits -= (bits-16);
|
||||
}
|
||||
rbps = (FLAC__uint32)err;
|
||||
|
||||
/* Multiply by fixed-point version of ln(2), with 16 fractional bits */
|
||||
rbps *= FLAC__FP_LN2;
|
||||
fracbits += 16;
|
||||
FLAC__ASSERT(fracbits >= 0);
|
||||
|
||||
/* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */
|
||||
{
|
||||
const int f = fracbits & 3;
|
||||
if(f) {
|
||||
rbps >>= f;
|
||||
fracbits -= f;
|
||||
}
|
||||
}
|
||||
|
||||
rbps = FLAC__fixedpoint_log2(rbps, fracbits, (unsigned)(-1));
|
||||
|
||||
if(rbps == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The return value must have 16 fractional bits. Since the whole part
|
||||
* of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits
|
||||
* must be >= -3, these assertion allows us to be able to shift rbps
|
||||
* left if necessary to get 16 fracbits without losing any bits of the
|
||||
* whole part of rbps.
|
||||
*
|
||||
* There is a slight chance due to accumulated error that the whole part
|
||||
* will require 6 bits, so we use 6 in the assertion. Really though as
|
||||
* long as it fits in 13 bits (32 - (16 - (-3))) we are fine.
|
||||
*/
|
||||
FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6);
|
||||
FLAC__ASSERT(fracbits >= -3);
|
||||
|
||||
/* now shift the decimal point into place */
|
||||
if(fracbits < 16)
|
||||
return rbps << (16-fracbits);
|
||||
else if(fracbits > 16)
|
||||
return rbps >> (fracbits-16);
|
||||
else
|
||||
return rbps;
|
||||
}
|
||||
|
||||
static FLAC__fixedpoint local__compute_rbps_wide_integerized(FLAC__uint64 err, FLAC__uint32 n)
|
||||
{
|
||||
FLAC__uint32 rbps;
|
||||
unsigned bits; /* the number of bits required to represent a number */
|
||||
int fracbits; /* the number of bits of rbps that comprise the fractional part */
|
||||
|
||||
FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint));
|
||||
FLAC__ASSERT(err > 0);
|
||||
FLAC__ASSERT(n > 0);
|
||||
|
||||
FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE);
|
||||
if(err <= n)
|
||||
return 0;
|
||||
/*
|
||||
* The above two things tell us 1) n fits in 16 bits; 2) err/n > 1.
|
||||
* These allow us later to know we won't lose too much precision in the
|
||||
* fixed-point division (err<<fracbits)/n.
|
||||
*/
|
||||
|
||||
fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2_wide(err)+1);
|
||||
|
||||
err <<= fracbits;
|
||||
err /= n;
|
||||
/* err now holds err/n with fracbits fractional bits */
|
||||
|
||||
/*
|
||||
* Whittle err down to 16 bits max. 16 significant bits is enough for
|
||||
* our purposes.
|
||||
*/
|
||||
FLAC__ASSERT(err > 0);
|
||||
bits = FLAC__bitmath_ilog2_wide(err)+1;
|
||||
if(bits > 16) {
|
||||
err >>= (bits-16);
|
||||
fracbits -= (bits-16);
|
||||
}
|
||||
rbps = (FLAC__uint32)err;
|
||||
|
||||
/* Multiply by fixed-point version of ln(2), with 16 fractional bits */
|
||||
rbps *= FLAC__FP_LN2;
|
||||
fracbits += 16;
|
||||
FLAC__ASSERT(fracbits >= 0);
|
||||
|
||||
/* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */
|
||||
{
|
||||
const int f = fracbits & 3;
|
||||
if(f) {
|
||||
rbps >>= f;
|
||||
fracbits -= f;
|
||||
}
|
||||
}
|
||||
|
||||
rbps = FLAC__fixedpoint_log2(rbps, fracbits, (unsigned)(-1));
|
||||
|
||||
if(rbps == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The return value must have 16 fractional bits. Since the whole part
|
||||
* of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits
|
||||
* must be >= -3, these assertion allows us to be able to shift rbps
|
||||
* left if necessary to get 16 fracbits without losing any bits of the
|
||||
* whole part of rbps.
|
||||
*
|
||||
* There is a slight chance due to accumulated error that the whole part
|
||||
* will require 6 bits, so we use 6 in the assertion. Really though as
|
||||
* long as it fits in 13 bits (32 - (16 - (-3))) we are fine.
|
||||
*/
|
||||
FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6);
|
||||
FLAC__ASSERT(fracbits >= -3);
|
||||
|
||||
/* now shift the decimal point into place */
|
||||
if(fracbits < 16)
|
||||
return rbps << (16-fracbits);
|
||||
else if(fracbits > 16)
|
||||
return rbps >> (fracbits-16);
|
||||
else
|
||||
return rbps;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
|
||||
#else
|
||||
unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
|
||||
#endif
|
||||
{
|
||||
FLAC__int32 last_error_0 = data[-1];
|
||||
FLAC__int32 last_error_1 = data[-1] - data[-2];
|
||||
FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]);
|
||||
FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]);
|
||||
FLAC__int32 error, save;
|
||||
FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0;
|
||||
unsigned i, order;
|
||||
|
||||
for(i = 0; i < data_len; i++) {
|
||||
error = data[i] ; total_error_0 += local_abs(error); save = error;
|
||||
error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error;
|
||||
error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error;
|
||||
error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error;
|
||||
error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save;
|
||||
}
|
||||
|
||||
if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
|
||||
order = 0;
|
||||
else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
|
||||
order = 1;
|
||||
else if(total_error_2 < flac_min(total_error_3, total_error_4))
|
||||
order = 2;
|
||||
else if(total_error_3 < total_error_4)
|
||||
order = 3;
|
||||
else
|
||||
order = 4;
|
||||
|
||||
/* Estimate the expected number of bits per residual signal sample. */
|
||||
/* 'total_error*' is linearly related to the variance of the residual */
|
||||
/* signal, so we use it directly to compute E(|x|) */
|
||||
FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
#else
|
||||
residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_integerized(total_error_0, data_len) : 0;
|
||||
residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_integerized(total_error_1, data_len) : 0;
|
||||
residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_integerized(total_error_2, data_len) : 0;
|
||||
residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_integerized(total_error_3, data_len) : 0;
|
||||
residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_integerized(total_error_4, data_len) : 0;
|
||||
#endif
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
|
||||
#else
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
|
||||
#endif
|
||||
{
|
||||
FLAC__int32 last_error_0 = data[-1];
|
||||
FLAC__int32 last_error_1 = data[-1] - data[-2];
|
||||
FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]);
|
||||
FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]);
|
||||
FLAC__int32 error, save;
|
||||
/* total_error_* are 64-bits to avoid overflow when encoding
|
||||
* erratic signals when the bits-per-sample and blocksize are
|
||||
* large.
|
||||
*/
|
||||
FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0;
|
||||
unsigned i, order;
|
||||
|
||||
for(i = 0; i < data_len; i++) {
|
||||
error = data[i] ; total_error_0 += local_abs(error); save = error;
|
||||
error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error;
|
||||
error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error;
|
||||
error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error;
|
||||
error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save;
|
||||
}
|
||||
|
||||
if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
|
||||
order = 0;
|
||||
else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
|
||||
order = 1;
|
||||
else if(total_error_2 < flac_min(total_error_3, total_error_4))
|
||||
order = 2;
|
||||
else if(total_error_3 < total_error_4)
|
||||
order = 3;
|
||||
else
|
||||
order = 4;
|
||||
|
||||
/* Estimate the expected number of bits per residual signal sample. */
|
||||
/* 'total_error*' is linearly related to the variance of the residual */
|
||||
/* signal, so we use it directly to compute E(|x|) */
|
||||
FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
#else
|
||||
residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_wide_integerized(total_error_0, data_len) : 0;
|
||||
residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0;
|
||||
residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_wide_integerized(total_error_2, data_len) : 0;
|
||||
residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_wide_integerized(total_error_3, data_len) : 0;
|
||||
residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_wide_integerized(total_error_4, data_len) : 0;
|
||||
#endif
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
void FLAC__fixed_compute_residual(const FLAC__int32 data[], unsigned data_len, unsigned order, FLAC__int32 residual[])
|
||||
{
|
||||
const int idata_len = (int)data_len;
|
||||
int i;
|
||||
|
||||
switch(order) {
|
||||
case 0:
|
||||
FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0]));
|
||||
memcpy(residual, data, sizeof(residual[0])*data_len);
|
||||
break;
|
||||
case 1:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
residual[i] = data[i] - data[i-1];
|
||||
break;
|
||||
case 2:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
#if 1 /* OPT: may be faster with some compilers on some systems */
|
||||
residual[i] = data[i] - (data[i-1] << 1) + data[i-2];
|
||||
#else
|
||||
residual[i] = data[i] - 2*data[i-1] + data[i-2];
|
||||
#endif
|
||||
break;
|
||||
case 3:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
#if 1 /* OPT: may be faster with some compilers on some systems */
|
||||
residual[i] = data[i] - (((data[i-1]-data[i-2])<<1) + (data[i-1]-data[i-2])) - data[i-3];
|
||||
#else
|
||||
residual[i] = data[i] - 3*data[i-1] + 3*data[i-2] - data[i-3];
|
||||
#endif
|
||||
break;
|
||||
case 4:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
#if 1 /* OPT: may be faster with some compilers on some systems */
|
||||
residual[i] = data[i] - ((data[i-1]+data[i-3])<<2) + ((data[i-2]<<2) + (data[i-2]<<1)) + data[i-4];
|
||||
#else
|
||||
residual[i] = data[i] - 4*data[i-1] + 6*data[i-2] - 4*data[i-3] + data[i-4];
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
FLAC__ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__fixed_restore_signal(const FLAC__int32 residual[], unsigned data_len, unsigned order, FLAC__int32 data[])
|
||||
{
|
||||
int i, idata_len = (int)data_len;
|
||||
|
||||
switch(order) {
|
||||
case 0:
|
||||
FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0]));
|
||||
memcpy(data, residual, sizeof(residual[0])*data_len);
|
||||
break;
|
||||
case 1:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
data[i] = residual[i] + data[i-1];
|
||||
break;
|
||||
case 2:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
#if 1 /* OPT: may be faster with some compilers on some systems */
|
||||
data[i] = residual[i] + (data[i-1]<<1) - data[i-2];
|
||||
#else
|
||||
data[i] = residual[i] + 2*data[i-1] - data[i-2];
|
||||
#endif
|
||||
break;
|
||||
case 3:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
#if 1 /* OPT: may be faster with some compilers on some systems */
|
||||
data[i] = residual[i] + (((data[i-1]-data[i-2])<<1) + (data[i-1]-data[i-2])) + data[i-3];
|
||||
#else
|
||||
data[i] = residual[i] + 3*data[i-1] - 3*data[i-2] + data[i-3];
|
||||
#endif
|
||||
break;
|
||||
case 4:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
#if 1 /* OPT: may be faster with some compilers on some systems */
|
||||
data[i] = residual[i] + ((data[i-1]+data[i-3])<<2) - ((data[i-2]<<2) + (data[i-2]<<1)) - data[i-4];
|
||||
#else
|
||||
data[i] = residual[i] + 4*data[i-1] - 6*data[i-2] + 4*data[i-3] - data[i-4];
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
FLAC__ASSERT(0);
|
||||
}
|
||||
}
|
||||
253
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/fixed_intrin_sse2.c
vendored
Normal file
253
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/fixed_intrin_sse2.c
vendored
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
#ifndef FLAC__NO_ASM
|
||||
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
|
||||
#include "private/fixed.h"
|
||||
#ifdef FLAC__SSE2_SUPPORTED
|
||||
|
||||
#include <emmintrin.h> /* SSE2 */
|
||||
#include <math.h>
|
||||
#include "private/macros.h"
|
||||
#include "share/compat.h"
|
||||
#include "FLAC/assert.h"
|
||||
|
||||
#ifdef FLAC__CPU_IA32
|
||||
#define m128i_to_i64(dest, src) _mm_storel_epi64((__m128i*)&dest, src)
|
||||
#else
|
||||
#define m128i_to_i64(dest, src) dest = _mm_cvtsi128_si64(src)
|
||||
#endif
|
||||
|
||||
FLAC__SSE_TARGET("sse2")
|
||||
unsigned FLAC__fixed_compute_best_predictor_intrin_sse2(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1])
|
||||
{
|
||||
FLAC__uint32 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4;
|
||||
unsigned i, order;
|
||||
|
||||
__m128i total_err0, total_err1, total_err2;
|
||||
|
||||
{
|
||||
FLAC__int32 itmp;
|
||||
__m128i last_error;
|
||||
|
||||
last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0
|
||||
itmp = data[-2];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1
|
||||
itmp -= data[-3];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2
|
||||
itmp -= data[-3] - data[-4];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3
|
||||
|
||||
total_err0 = total_err1 = _mm_setzero_si128();
|
||||
for(i = 0; i < data_len; i++) {
|
||||
__m128i err0, err1, tmp;
|
||||
err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0
|
||||
err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0
|
||||
#if 1 /* OPT_SSE */
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#else
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#endif
|
||||
tmp = _mm_slli_si128(err0, 12); // e0 0 0 0
|
||||
last_error = _mm_srli_si128(err1, 4); // 0 e1 e2 e3
|
||||
last_error = _mm_or_si128(last_error, tmp); // e0 e1 e2 e3
|
||||
|
||||
tmp = _mm_srai_epi32(err0, 31);
|
||||
err0 = _mm_xor_si128(err0, tmp);
|
||||
err0 = _mm_sub_epi32(err0, tmp);
|
||||
tmp = _mm_srai_epi32(err1, 31);
|
||||
err1 = _mm_xor_si128(err1, tmp);
|
||||
err1 = _mm_sub_epi32(err1, tmp);
|
||||
|
||||
total_err0 = _mm_add_epi32(total_err0, err0); // 0 0 0 te0
|
||||
total_err1 = _mm_add_epi32(total_err1, err1); // te1 te2 te3 te4
|
||||
}
|
||||
}
|
||||
|
||||
total_error_0 = _mm_cvtsi128_si32(total_err0);
|
||||
total_err2 = total_err1; // te1 te2 te3 te4
|
||||
total_err1 = _mm_srli_si128(total_err1, 8); // 0 0 te1 te2
|
||||
total_error_4 = _mm_cvtsi128_si32(total_err2);
|
||||
total_error_2 = _mm_cvtsi128_si32(total_err1);
|
||||
total_err2 = _mm_srli_si128(total_err2, 4); // 0 te1 te2 te3
|
||||
total_err1 = _mm_srli_si128(total_err1, 4); // 0 0 0 te1
|
||||
total_error_3 = _mm_cvtsi128_si32(total_err2);
|
||||
total_error_1 = _mm_cvtsi128_si32(total_err1);
|
||||
|
||||
/* prefer higher order */
|
||||
if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
|
||||
order = 0;
|
||||
else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
|
||||
order = 1;
|
||||
else if(total_error_2 < flac_min(total_error_3, total_error_4))
|
||||
order = 2;
|
||||
else if(total_error_3 < total_error_4)
|
||||
order = 3;
|
||||
else
|
||||
order = 4;
|
||||
|
||||
/* Estimate the expected number of bits per residual signal sample. */
|
||||
/* 'total_error*' is linearly related to the variance of the residual */
|
||||
/* signal, so we use it directly to compute E(|x|) */
|
||||
FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
|
||||
|
||||
residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("sse2")
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide_intrin_sse2(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1])
|
||||
{
|
||||
FLAC__uint64 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4;
|
||||
unsigned i, order;
|
||||
|
||||
__m128i total_err0, total_err1, total_err3;
|
||||
|
||||
{
|
||||
FLAC__int32 itmp;
|
||||
__m128i last_error, zero = _mm_setzero_si128();
|
||||
|
||||
last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0
|
||||
itmp = data[-2];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1
|
||||
itmp -= data[-3];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2
|
||||
itmp -= data[-3] - data[-4];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3
|
||||
|
||||
total_err0 = total_err1 = total_err3 = _mm_setzero_si128();
|
||||
for(i = 0; i < data_len; i++) {
|
||||
__m128i err0, err1, tmp;
|
||||
err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0
|
||||
err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0
|
||||
#if 1 /* OPT_SSE */
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#else
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#endif
|
||||
tmp = _mm_slli_si128(err0, 12); // e0 0 0 0
|
||||
last_error = _mm_srli_si128(err1, 4); // 0 e1 e2 e3
|
||||
last_error = _mm_or_si128(last_error, tmp); // e0 e1 e2 e3
|
||||
|
||||
tmp = _mm_srai_epi32(err0, 31);
|
||||
err0 = _mm_xor_si128(err0, tmp);
|
||||
err0 = _mm_sub_epi32(err0, tmp);
|
||||
tmp = _mm_srai_epi32(err1, 31);
|
||||
err1 = _mm_xor_si128(err1, tmp);
|
||||
err1 = _mm_sub_epi32(err1, tmp);
|
||||
|
||||
total_err0 = _mm_add_epi64(total_err0, err0); // 0 te0
|
||||
err0 = _mm_unpacklo_epi32(err1, zero); // 0 |e3| 0 |e4|
|
||||
err1 = _mm_unpackhi_epi32(err1, zero); // 0 |e1| 0 |e2|
|
||||
total_err3 = _mm_add_epi64(total_err3, err0); // te3 te4
|
||||
total_err1 = _mm_add_epi64(total_err1, err1); // te1 te2
|
||||
}
|
||||
}
|
||||
|
||||
m128i_to_i64(total_error_0, total_err0);
|
||||
m128i_to_i64(total_error_4, total_err3);
|
||||
m128i_to_i64(total_error_2, total_err1);
|
||||
total_err3 = _mm_srli_si128(total_err3, 8); // 0 te3
|
||||
total_err1 = _mm_srli_si128(total_err1, 8); // 0 te1
|
||||
m128i_to_i64(total_error_3, total_err3);
|
||||
m128i_to_i64(total_error_1, total_err1);
|
||||
|
||||
/* prefer higher order */
|
||||
if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
|
||||
order = 0;
|
||||
else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
|
||||
order = 1;
|
||||
else if(total_error_2 < flac_min(total_error_3, total_error_4))
|
||||
order = 2;
|
||||
else if(total_error_3 < total_error_4)
|
||||
order = 3;
|
||||
else
|
||||
order = 4;
|
||||
|
||||
/* Estimate the expected number of bits per residual signal sample. */
|
||||
/* 'total_error*' is linearly related to the variance of the residual */
|
||||
/* signal, so we use it directly to compute E(|x|) */
|
||||
FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
|
||||
|
||||
residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
#endif /* FLAC__SSE2_SUPPORTED */
|
||||
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
|
||||
#endif /* FLAC__NO_ASM */
|
||||
#endif /* FLAC__INTEGER_ONLY_LIBRARY */
|
||||
241
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/fixed_intrin_ssse3.c
vendored
Normal file
241
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/fixed_intrin_ssse3.c
vendored
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
#ifndef FLAC__NO_ASM
|
||||
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
|
||||
#include "private/fixed.h"
|
||||
#ifdef FLAC__SSSE3_SUPPORTED
|
||||
|
||||
#include <tmmintrin.h> /* SSSE3 */
|
||||
#include <math.h>
|
||||
#include "private/macros.h"
|
||||
#include "share/compat.h"
|
||||
#include "FLAC/assert.h"
|
||||
|
||||
#ifdef FLAC__CPU_IA32
|
||||
#define m128i_to_i64(dest, src) _mm_storel_epi64((__m128i*)&dest, src)
|
||||
#else
|
||||
#define m128i_to_i64(dest, src) dest = _mm_cvtsi128_si64(src)
|
||||
#endif
|
||||
|
||||
FLAC__SSE_TARGET("ssse3")
|
||||
unsigned FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1])
|
||||
{
|
||||
FLAC__uint32 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4;
|
||||
unsigned i, order;
|
||||
|
||||
__m128i total_err0, total_err1, total_err2;
|
||||
|
||||
{
|
||||
FLAC__int32 itmp;
|
||||
__m128i last_error;
|
||||
|
||||
last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0
|
||||
itmp = data[-2];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1
|
||||
itmp -= data[-3];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2
|
||||
itmp -= data[-3] - data[-4];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3
|
||||
|
||||
total_err0 = total_err1 = _mm_setzero_si128();
|
||||
for(i = 0; i < data_len; i++) {
|
||||
__m128i err0, err1;
|
||||
err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0
|
||||
err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0
|
||||
#if 1 /* OPT_SSE */
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#else
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#endif
|
||||
last_error = _mm_alignr_epi8(err0, err1, 4); // e0 e1 e2 e3
|
||||
|
||||
err0 = _mm_abs_epi32(err0);
|
||||
err1 = _mm_abs_epi32(err1);
|
||||
|
||||
total_err0 = _mm_add_epi32(total_err0, err0); // 0 0 0 te0
|
||||
total_err1 = _mm_add_epi32(total_err1, err1); // te1 te2 te3 te4
|
||||
}
|
||||
}
|
||||
|
||||
total_error_0 = _mm_cvtsi128_si32(total_err0);
|
||||
total_err2 = total_err1; // te1 te2 te3 te4
|
||||
total_err1 = _mm_srli_si128(total_err1, 8); // 0 0 te1 te2
|
||||
total_error_4 = _mm_cvtsi128_si32(total_err2);
|
||||
total_error_2 = _mm_cvtsi128_si32(total_err1);
|
||||
total_err2 = _mm_srli_si128(total_err2, 4); // 0 te1 te2 te3
|
||||
total_err1 = _mm_srli_si128(total_err1, 4); // 0 0 0 te1
|
||||
total_error_3 = _mm_cvtsi128_si32(total_err2);
|
||||
total_error_1 = _mm_cvtsi128_si32(total_err1);
|
||||
|
||||
/* prefer higher order */
|
||||
if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
|
||||
order = 0;
|
||||
else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
|
||||
order = 1;
|
||||
else if(total_error_2 < flac_min(total_error_3, total_error_4))
|
||||
order = 2;
|
||||
else if(total_error_3 < total_error_4)
|
||||
order = 3;
|
||||
else
|
||||
order = 4;
|
||||
|
||||
/* Estimate the expected number of bits per residual signal sample. */
|
||||
/* 'total_error*' is linearly related to the variance of the residual */
|
||||
/* signal, so we use it directly to compute E(|x|) */
|
||||
FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
|
||||
|
||||
residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("ssse3")
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1])
|
||||
{
|
||||
FLAC__uint64 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4;
|
||||
unsigned i, order;
|
||||
|
||||
__m128i total_err0, total_err1, total_err3;
|
||||
|
||||
{
|
||||
FLAC__int32 itmp;
|
||||
__m128i last_error, zero = _mm_setzero_si128();
|
||||
|
||||
last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0
|
||||
itmp = data[-2];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1
|
||||
itmp -= data[-3];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2
|
||||
itmp -= data[-3] - data[-4];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3
|
||||
|
||||
total_err0 = total_err1 = total_err3 = _mm_setzero_si128();
|
||||
for(i = 0; i < data_len; i++) {
|
||||
__m128i err0, err1;
|
||||
err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0
|
||||
err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0
|
||||
#if 1 /* OPT_SSE */
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#else
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#endif
|
||||
last_error = _mm_alignr_epi8(err0, err1, 4); // e0 e1 e2 e3
|
||||
|
||||
err0 = _mm_abs_epi32(err0);
|
||||
err1 = _mm_abs_epi32(err1); // |e1| |e2| |e3| |e4|
|
||||
|
||||
total_err0 = _mm_add_epi64(total_err0, err0); // 0 te0
|
||||
err0 = _mm_unpacklo_epi32(err1, zero); // 0 |e3| 0 |e4|
|
||||
err1 = _mm_unpackhi_epi32(err1, zero); // 0 |e1| 0 |e2|
|
||||
total_err3 = _mm_add_epi64(total_err3, err0); // te3 te4
|
||||
total_err1 = _mm_add_epi64(total_err1, err1); // te1 te2
|
||||
}
|
||||
}
|
||||
|
||||
m128i_to_i64(total_error_0, total_err0);
|
||||
m128i_to_i64(total_error_4, total_err3);
|
||||
m128i_to_i64(total_error_2, total_err1);
|
||||
total_err3 = _mm_srli_si128(total_err3, 8); // 0 te3
|
||||
total_err1 = _mm_srli_si128(total_err1, 8); // 0 te1
|
||||
m128i_to_i64(total_error_3, total_err3);
|
||||
m128i_to_i64(total_error_1, total_err1);
|
||||
|
||||
/* prefer higher order */
|
||||
if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
|
||||
order = 0;
|
||||
else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
|
||||
order = 1;
|
||||
else if(total_error_2 < flac_min(total_error_3, total_error_4))
|
||||
order = 2;
|
||||
else if(total_error_3 < total_error_4)
|
||||
order = 3;
|
||||
else
|
||||
order = 4;
|
||||
|
||||
/* Estimate the expected number of bits per residual signal sample. */
|
||||
/* 'total_error*' is linearly related to the variance of the residual */
|
||||
/* signal, so we use it directly to compute E(|x|) */
|
||||
FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
|
||||
|
||||
residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
#endif /* FLAC__SSSE3_SUPPORTED */
|
||||
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
|
||||
#endif /* FLAC__NO_ASM */
|
||||
#endif /* FLAC__INTEGER_ONLY_LIBRARY */
|
||||
|
|
@ -0,0 +1,302 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2004-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FLAC/assert.h"
|
||||
#include "share/compat.h"
|
||||
#include "private/float.h"
|
||||
|
||||
#ifdef FLAC__INTEGER_ONLY_LIBRARY
|
||||
|
||||
const FLAC__fixedpoint FLAC__FP_ZERO = 0;
|
||||
const FLAC__fixedpoint FLAC__FP_ONE_HALF = 0x00008000;
|
||||
const FLAC__fixedpoint FLAC__FP_ONE = 0x00010000;
|
||||
const FLAC__fixedpoint FLAC__FP_LN2 = 45426;
|
||||
const FLAC__fixedpoint FLAC__FP_E = 178145;
|
||||
|
||||
/* Lookup tables for Knuth's logarithm algorithm */
|
||||
#define LOG2_LOOKUP_PRECISION 16
|
||||
static const FLAC__uint32 log2_lookup[][LOG2_LOOKUP_PRECISION] = {
|
||||
{
|
||||
/*
|
||||
* 0 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x00000001,
|
||||
/* lg(4/3) = */ 0x00000000,
|
||||
/* lg(8/7) = */ 0x00000000,
|
||||
/* lg(16/15) = */ 0x00000000,
|
||||
/* lg(32/31) = */ 0x00000000,
|
||||
/* lg(64/63) = */ 0x00000000,
|
||||
/* lg(128/127) = */ 0x00000000,
|
||||
/* lg(256/255) = */ 0x00000000,
|
||||
/* lg(512/511) = */ 0x00000000,
|
||||
/* lg(1024/1023) = */ 0x00000000,
|
||||
/* lg(2048/2047) = */ 0x00000000,
|
||||
/* lg(4096/4095) = */ 0x00000000,
|
||||
/* lg(8192/8191) = */ 0x00000000,
|
||||
/* lg(16384/16383) = */ 0x00000000,
|
||||
/* lg(32768/32767) = */ 0x00000000
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 4 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x00000010,
|
||||
/* lg(4/3) = */ 0x00000007,
|
||||
/* lg(8/7) = */ 0x00000003,
|
||||
/* lg(16/15) = */ 0x00000001,
|
||||
/* lg(32/31) = */ 0x00000001,
|
||||
/* lg(64/63) = */ 0x00000000,
|
||||
/* lg(128/127) = */ 0x00000000,
|
||||
/* lg(256/255) = */ 0x00000000,
|
||||
/* lg(512/511) = */ 0x00000000,
|
||||
/* lg(1024/1023) = */ 0x00000000,
|
||||
/* lg(2048/2047) = */ 0x00000000,
|
||||
/* lg(4096/4095) = */ 0x00000000,
|
||||
/* lg(8192/8191) = */ 0x00000000,
|
||||
/* lg(16384/16383) = */ 0x00000000,
|
||||
/* lg(32768/32767) = */ 0x00000000
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 8 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x00000100,
|
||||
/* lg(4/3) = */ 0x0000006a,
|
||||
/* lg(8/7) = */ 0x00000031,
|
||||
/* lg(16/15) = */ 0x00000018,
|
||||
/* lg(32/31) = */ 0x0000000c,
|
||||
/* lg(64/63) = */ 0x00000006,
|
||||
/* lg(128/127) = */ 0x00000003,
|
||||
/* lg(256/255) = */ 0x00000001,
|
||||
/* lg(512/511) = */ 0x00000001,
|
||||
/* lg(1024/1023) = */ 0x00000000,
|
||||
/* lg(2048/2047) = */ 0x00000000,
|
||||
/* lg(4096/4095) = */ 0x00000000,
|
||||
/* lg(8192/8191) = */ 0x00000000,
|
||||
/* lg(16384/16383) = */ 0x00000000,
|
||||
/* lg(32768/32767) = */ 0x00000000
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 12 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x00001000,
|
||||
/* lg(4/3) = */ 0x000006a4,
|
||||
/* lg(8/7) = */ 0x00000315,
|
||||
/* lg(16/15) = */ 0x0000017d,
|
||||
/* lg(32/31) = */ 0x000000bc,
|
||||
/* lg(64/63) = */ 0x0000005d,
|
||||
/* lg(128/127) = */ 0x0000002e,
|
||||
/* lg(256/255) = */ 0x00000017,
|
||||
/* lg(512/511) = */ 0x0000000c,
|
||||
/* lg(1024/1023) = */ 0x00000006,
|
||||
/* lg(2048/2047) = */ 0x00000003,
|
||||
/* lg(4096/4095) = */ 0x00000001,
|
||||
/* lg(8192/8191) = */ 0x00000001,
|
||||
/* lg(16384/16383) = */ 0x00000000,
|
||||
/* lg(32768/32767) = */ 0x00000000
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 16 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x00010000,
|
||||
/* lg(4/3) = */ 0x00006a40,
|
||||
/* lg(8/7) = */ 0x00003151,
|
||||
/* lg(16/15) = */ 0x000017d6,
|
||||
/* lg(32/31) = */ 0x00000bba,
|
||||
/* lg(64/63) = */ 0x000005d1,
|
||||
/* lg(128/127) = */ 0x000002e6,
|
||||
/* lg(256/255) = */ 0x00000172,
|
||||
/* lg(512/511) = */ 0x000000b9,
|
||||
/* lg(1024/1023) = */ 0x0000005c,
|
||||
/* lg(2048/2047) = */ 0x0000002e,
|
||||
/* lg(4096/4095) = */ 0x00000017,
|
||||
/* lg(8192/8191) = */ 0x0000000c,
|
||||
/* lg(16384/16383) = */ 0x00000006,
|
||||
/* lg(32768/32767) = */ 0x00000003
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 20 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x00100000,
|
||||
/* lg(4/3) = */ 0x0006a3fe,
|
||||
/* lg(8/7) = */ 0x00031513,
|
||||
/* lg(16/15) = */ 0x00017d60,
|
||||
/* lg(32/31) = */ 0x0000bb9d,
|
||||
/* lg(64/63) = */ 0x00005d10,
|
||||
/* lg(128/127) = */ 0x00002e59,
|
||||
/* lg(256/255) = */ 0x00001721,
|
||||
/* lg(512/511) = */ 0x00000b8e,
|
||||
/* lg(1024/1023) = */ 0x000005c6,
|
||||
/* lg(2048/2047) = */ 0x000002e3,
|
||||
/* lg(4096/4095) = */ 0x00000171,
|
||||
/* lg(8192/8191) = */ 0x000000b9,
|
||||
/* lg(16384/16383) = */ 0x0000005c,
|
||||
/* lg(32768/32767) = */ 0x0000002e
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 24 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x01000000,
|
||||
/* lg(4/3) = */ 0x006a3fe6,
|
||||
/* lg(8/7) = */ 0x00315130,
|
||||
/* lg(16/15) = */ 0x0017d605,
|
||||
/* lg(32/31) = */ 0x000bb9ca,
|
||||
/* lg(64/63) = */ 0x0005d0fc,
|
||||
/* lg(128/127) = */ 0x0002e58f,
|
||||
/* lg(256/255) = */ 0x0001720e,
|
||||
/* lg(512/511) = */ 0x0000b8d8,
|
||||
/* lg(1024/1023) = */ 0x00005c61,
|
||||
/* lg(2048/2047) = */ 0x00002e2d,
|
||||
/* lg(4096/4095) = */ 0x00001716,
|
||||
/* lg(8192/8191) = */ 0x00000b8b,
|
||||
/* lg(16384/16383) = */ 0x000005c5,
|
||||
/* lg(32768/32767) = */ 0x000002e3
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 28 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x10000000,
|
||||
/* lg(4/3) = */ 0x06a3fe5c,
|
||||
/* lg(8/7) = */ 0x03151301,
|
||||
/* lg(16/15) = */ 0x017d6049,
|
||||
/* lg(32/31) = */ 0x00bb9ca6,
|
||||
/* lg(64/63) = */ 0x005d0fba,
|
||||
/* lg(128/127) = */ 0x002e58f7,
|
||||
/* lg(256/255) = */ 0x001720da,
|
||||
/* lg(512/511) = */ 0x000b8d87,
|
||||
/* lg(1024/1023) = */ 0x0005c60b,
|
||||
/* lg(2048/2047) = */ 0x0002e2d7,
|
||||
/* lg(4096/4095) = */ 0x00017160,
|
||||
/* lg(8192/8191) = */ 0x0000b8ad,
|
||||
/* lg(16384/16383) = */ 0x00005c56,
|
||||
/* lg(32768/32767) = */ 0x00002e2b
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
static const FLAC__uint64 log2_lookup_wide[] = {
|
||||
{
|
||||
/*
|
||||
* 32 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ FLAC__U64L(0x100000000),
|
||||
/* lg(4/3) = */ FLAC__U64L(0x6a3fe5c6),
|
||||
/* lg(8/7) = */ FLAC__U64L(0x31513015),
|
||||
/* lg(16/15) = */ FLAC__U64L(0x17d60497),
|
||||
/* lg(32/31) = */ FLAC__U64L(0x0bb9ca65),
|
||||
/* lg(64/63) = */ FLAC__U64L(0x05d0fba2),
|
||||
/* lg(128/127) = */ FLAC__U64L(0x02e58f74),
|
||||
/* lg(256/255) = */ FLAC__U64L(0x01720d9c),
|
||||
/* lg(512/511) = */ FLAC__U64L(0x00b8d875),
|
||||
/* lg(1024/1023) = */ FLAC__U64L(0x005c60aa),
|
||||
/* lg(2048/2047) = */ FLAC__U64L(0x002e2d72),
|
||||
/* lg(4096/4095) = */ FLAC__U64L(0x00171600),
|
||||
/* lg(8192/8191) = */ FLAC__U64L(0x000b8ad2),
|
||||
/* lg(16384/16383) = */ FLAC__U64L(0x0005c55d),
|
||||
/* lg(32768/32767) = */ FLAC__U64L(0x0002e2ac)
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 48 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ FLAC__U64L(0x1000000000000),
|
||||
/* lg(4/3) = */ FLAC__U64L(0x6a3fe5c60429),
|
||||
/* lg(8/7) = */ FLAC__U64L(0x315130157f7a),
|
||||
/* lg(16/15) = */ FLAC__U64L(0x17d60496cfbb),
|
||||
/* lg(32/31) = */ FLAC__U64L(0xbb9ca64ecac),
|
||||
/* lg(64/63) = */ FLAC__U64L(0x5d0fba187cd),
|
||||
/* lg(128/127) = */ FLAC__U64L(0x2e58f7441ee),
|
||||
/* lg(256/255) = */ FLAC__U64L(0x1720d9c06a8),
|
||||
/* lg(512/511) = */ FLAC__U64L(0xb8d8752173),
|
||||
/* lg(1024/1023) = */ FLAC__U64L(0x5c60aa252e),
|
||||
/* lg(2048/2047) = */ FLAC__U64L(0x2e2d71b0d8),
|
||||
/* lg(4096/4095) = */ FLAC__U64L(0x1716001719),
|
||||
/* lg(8192/8191) = */ FLAC__U64L(0xb8ad1de1b),
|
||||
/* lg(16384/16383) = */ FLAC__U64L(0x5c55d640d),
|
||||
/* lg(32768/32767) = */ FLAC__U64L(0x2e2abcf52)
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision)
|
||||
{
|
||||
const FLAC__uint32 ONE = (1u << fracbits);
|
||||
const FLAC__uint32 *table = log2_lookup[fracbits >> 2];
|
||||
|
||||
FLAC__ASSERT(fracbits < 32);
|
||||
FLAC__ASSERT((fracbits & 0x3) == 0);
|
||||
|
||||
if(x < ONE)
|
||||
return 0;
|
||||
|
||||
if(precision > LOG2_LOOKUP_PRECISION)
|
||||
precision = LOG2_LOOKUP_PRECISION;
|
||||
|
||||
/* Knuth's algorithm for computing logarithms, optimized for base-2 with lookup tables */
|
||||
{
|
||||
FLAC__uint32 y = 0;
|
||||
FLAC__uint32 z = x >> 1, k = 1;
|
||||
while (x > ONE && k < precision) {
|
||||
if (x - z >= ONE) {
|
||||
x -= z;
|
||||
z = x >> k;
|
||||
y += table[k];
|
||||
}
|
||||
else {
|
||||
z >>= 1;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined FLAC__INTEGER_ONLY_LIBRARY */
|
||||
|
|
@ -0,0 +1,585 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* for qsort() */
|
||||
#include <string.h> /* for memset() */
|
||||
#include "FLAC/assert.h"
|
||||
#include "FLAC/format.h"
|
||||
#include "share/compat.h"
|
||||
#include "private/format.h"
|
||||
#include "private/macros.h"
|
||||
|
||||
/* VERSION should come from configure */
|
||||
FLAC_API const char *FLAC__VERSION_STRING = "1.3.1";
|
||||
|
||||
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.3.1 20141125";
|
||||
|
||||
FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
|
||||
FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143;
|
||||
FLAC_API const unsigned FLAC__STREAM_SYNC_LEN = 32; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN = 32; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */
|
||||
|
||||
FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER = FLAC__U64L(0xffffffffffffffff);
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = 32; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = 32; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe;
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN = 1; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN = 1; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */
|
||||
FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */
|
||||
FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */
|
||||
FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN = 5; /* bits */
|
||||
FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
|
||||
FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER = 31; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */
|
||||
|
||||
FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = {
|
||||
"PARTITIONED_RICE",
|
||||
"PARTITIONED_RICE2"
|
||||
};
|
||||
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00;
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02;
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10;
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK = 0x40;
|
||||
|
||||
FLAC_API const char * const FLAC__SubframeTypeString[] = {
|
||||
"CONSTANT",
|
||||
"VERBATIM",
|
||||
"FIXED",
|
||||
"LPC"
|
||||
};
|
||||
|
||||
FLAC_API const char * const FLAC__ChannelAssignmentString[] = {
|
||||
"INDEPENDENT",
|
||||
"LEFT_SIDE",
|
||||
"RIGHT_SIDE",
|
||||
"MID_SIDE"
|
||||
};
|
||||
|
||||
FLAC_API const char * const FLAC__FrameNumberTypeString[] = {
|
||||
"FRAME_NUMBER_TYPE_FRAME_NUMBER",
|
||||
"FRAME_NUMBER_TYPE_SAMPLE_NUMBER"
|
||||
};
|
||||
|
||||
FLAC_API const char * const FLAC__MetadataTypeString[] = {
|
||||
"STREAMINFO",
|
||||
"PADDING",
|
||||
"APPLICATION",
|
||||
"SEEKTABLE",
|
||||
"VORBIS_COMMENT",
|
||||
"CUESHEET",
|
||||
"PICTURE"
|
||||
};
|
||||
|
||||
FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[] = {
|
||||
"Other",
|
||||
"32x32 pixels 'file icon' (PNG only)",
|
||||
"Other file icon",
|
||||
"Cover (front)",
|
||||
"Cover (back)",
|
||||
"Leaflet page",
|
||||
"Media (e.g. label side of CD)",
|
||||
"Lead artist/lead performer/soloist",
|
||||
"Artist/performer",
|
||||
"Conductor",
|
||||
"Band/Orchestra",
|
||||
"Composer",
|
||||
"Lyricist/text writer",
|
||||
"Recording Location",
|
||||
"During recording",
|
||||
"During performance",
|
||||
"Movie/video screen capture",
|
||||
"A bright coloured fish",
|
||||
"Illustration",
|
||||
"Band/artist logotype",
|
||||
"Publisher/Studio logotype"
|
||||
};
|
||||
|
||||
FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate)
|
||||
{
|
||||
if(sample_rate == 0 || sample_rate > FLAC__MAX_SAMPLE_RATE) {
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(unsigned blocksize, unsigned sample_rate)
|
||||
{
|
||||
if(blocksize > 16384)
|
||||
return false;
|
||||
else if(sample_rate <= 48000 && blocksize > 4608)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate)
|
||||
{
|
||||
if(
|
||||
!FLAC__format_sample_rate_is_valid(sample_rate) ||
|
||||
(
|
||||
sample_rate >= (1u << 16) &&
|
||||
!(sample_rate % 1000 == 0 || sample_rate % 10 == 0)
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
|
||||
FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table)
|
||||
{
|
||||
unsigned i;
|
||||
FLAC__uint64 prev_sample_number = 0;
|
||||
FLAC__bool got_prev = false;
|
||||
|
||||
FLAC__ASSERT(0 != seek_table);
|
||||
|
||||
for(i = 0; i < seek_table->num_points; i++) {
|
||||
if(got_prev) {
|
||||
if(
|
||||
seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER &&
|
||||
seek_table->points[i].sample_number <= prev_sample_number
|
||||
)
|
||||
return false;
|
||||
}
|
||||
prev_sample_number = seek_table->points[i].sample_number;
|
||||
got_prev = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* used as the sort predicate for qsort() */
|
||||
static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r)
|
||||
{
|
||||
/* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */
|
||||
if(l->sample_number == r->sample_number)
|
||||
return 0;
|
||||
else if(l->sample_number < r->sample_number)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
|
||||
FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table)
|
||||
{
|
||||
unsigned i, j;
|
||||
FLAC__bool first;
|
||||
|
||||
FLAC__ASSERT(0 != seek_table);
|
||||
|
||||
/* sort the seekpoints */
|
||||
qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_);
|
||||
|
||||
/* uniquify the seekpoints */
|
||||
first = true;
|
||||
for(i = j = 0; i < seek_table->num_points; i++) {
|
||||
if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) {
|
||||
if(!first) {
|
||||
if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
seek_table->points[j++] = seek_table->points[i];
|
||||
}
|
||||
|
||||
for(i = j; i < seek_table->num_points; i++) {
|
||||
seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
|
||||
seek_table->points[i].stream_offset = 0;
|
||||
seek_table->points[i].frame_samples = 0;
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
/*
|
||||
* also disallows non-shortest-form encodings, c.f.
|
||||
* http://www.unicode.org/versions/corrigendum1.html
|
||||
* and a more clear explanation at the end of this section:
|
||||
* http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
*/
|
||||
static unsigned utf8len_(const FLAC__byte *utf8)
|
||||
{
|
||||
FLAC__ASSERT(0 != utf8);
|
||||
if ((utf8[0] & 0x80) == 0) {
|
||||
return 1;
|
||||
}
|
||||
else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) {
|
||||
if ((utf8[0] & 0xFE) == 0xC0) /* overlong sequence check */
|
||||
return 0;
|
||||
return 2;
|
||||
}
|
||||
else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) {
|
||||
if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) /* overlong sequence check */
|
||||
return 0;
|
||||
/* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */
|
||||
if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) /* D800-DFFF */
|
||||
return 0;
|
||||
if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) /* FFFE-FFFF */
|
||||
return 0;
|
||||
return 3;
|
||||
}
|
||||
else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) {
|
||||
if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) /* overlong sequence check */
|
||||
return 0;
|
||||
return 4;
|
||||
}
|
||||
else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) {
|
||||
if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) /* overlong sequence check */
|
||||
return 0;
|
||||
return 5;
|
||||
}
|
||||
else if ((utf8[0] & 0xFE) == 0xFC && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80 && (utf8[5] & 0xC0) == 0x80) {
|
||||
if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) /* overlong sequence check */
|
||||
return 0;
|
||||
return 6;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name)
|
||||
{
|
||||
char c;
|
||||
for(c = *name; c; c = *(++name))
|
||||
if(c < 0x20 || c == 0x3d || c > 0x7d)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length)
|
||||
{
|
||||
if(length == (unsigned)(-1)) {
|
||||
while(*value) {
|
||||
unsigned n = utf8len_(value);
|
||||
if(n == 0)
|
||||
return false;
|
||||
value += n;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const FLAC__byte *end = value + length;
|
||||
while(value < end) {
|
||||
unsigned n = utf8len_(value);
|
||||
if(n == 0)
|
||||
return false;
|
||||
value += n;
|
||||
}
|
||||
if(value != end)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length)
|
||||
{
|
||||
const FLAC__byte *s, *end;
|
||||
|
||||
for(s = entry, end = s + length; s < end && *s != '='; s++) {
|
||||
if(*s < 0x20 || *s > 0x7D)
|
||||
return false;
|
||||
}
|
||||
if(s == end)
|
||||
return false;
|
||||
|
||||
s++; /* skip '=' */
|
||||
|
||||
while(s < end) {
|
||||
unsigned n = utf8len_(s);
|
||||
if(n == 0)
|
||||
return false;
|
||||
s += n;
|
||||
}
|
||||
if(s != end)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
|
||||
FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
if(check_cd_da_subset) {
|
||||
if(cue_sheet->lead_in < 2 * 44100) {
|
||||
if(violation) *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds";
|
||||
return false;
|
||||
}
|
||||
if(cue_sheet->lead_in % 588 != 0) {
|
||||
if(violation) *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(cue_sheet->num_tracks == 0) {
|
||||
if(violation) *violation = "cue sheet must have at least one track (the lead-out)";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks-1].number != 170) {
|
||||
if(violation) *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)";
|
||||
return false;
|
||||
}
|
||||
|
||||
for(i = 0; i < cue_sheet->num_tracks; i++) {
|
||||
if(cue_sheet->tracks[i].number == 0) {
|
||||
if(violation) *violation = "cue sheet may not have a track number 0";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(check_cd_da_subset) {
|
||||
if(!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) {
|
||||
if(violation) *violation = "CD-DA cue sheet track number must be 1-99 or 170";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) {
|
||||
if(violation) {
|
||||
if(i == cue_sheet->num_tracks-1) /* the lead-out track... */
|
||||
*violation = "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples";
|
||||
else
|
||||
*violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(i < cue_sheet->num_tracks - 1) {
|
||||
if(cue_sheet->tracks[i].num_indices == 0) {
|
||||
if(violation) *violation = "cue sheet track must have at least one index point";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(cue_sheet->tracks[i].indices[0].number > 1) {
|
||||
if(violation) *violation = "cue sheet track's first index number must be 0 or 1";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for(j = 0; j < cue_sheet->tracks[i].num_indices; j++) {
|
||||
if(check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) {
|
||||
if(violation) *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(j > 0) {
|
||||
if(cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j-1].number + 1) {
|
||||
if(violation) *violation = "cue sheet track index numbers must increase by 1";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
|
||||
FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation)
|
||||
{
|
||||
char *p;
|
||||
FLAC__byte *b;
|
||||
|
||||
for(p = picture->mime_type; *p; p++) {
|
||||
if(*p < 0x20 || *p > 0x7e) {
|
||||
if(violation) *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for(b = picture->description; *b; ) {
|
||||
unsigned n = utf8len_(b);
|
||||
if(n == 0) {
|
||||
if(violation) *violation = "description string must be valid UTF-8";
|
||||
return false;
|
||||
}
|
||||
b += n;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* These routines are private to libFLAC
|
||||
*/
|
||||
unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order)
|
||||
{
|
||||
return
|
||||
FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(
|
||||
FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize),
|
||||
blocksize,
|
||||
predictor_order
|
||||
);
|
||||
}
|
||||
|
||||
unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize)
|
||||
{
|
||||
unsigned max_rice_partition_order = 0;
|
||||
while(!(blocksize & 1)) {
|
||||
max_rice_partition_order++;
|
||||
blocksize >>= 1;
|
||||
}
|
||||
return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order);
|
||||
}
|
||||
|
||||
unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order)
|
||||
{
|
||||
unsigned max_rice_partition_order = limit;
|
||||
|
||||
while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order)
|
||||
max_rice_partition_order--;
|
||||
|
||||
FLAC__ASSERT(
|
||||
(max_rice_partition_order == 0 && blocksize >= predictor_order) ||
|
||||
(max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order)
|
||||
);
|
||||
|
||||
return max_rice_partition_order;
|
||||
}
|
||||
|
||||
void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
|
||||
{
|
||||
FLAC__ASSERT(0 != object);
|
||||
|
||||
object->parameters = 0;
|
||||
object->raw_bits = 0;
|
||||
object->capacity_by_order = 0;
|
||||
}
|
||||
|
||||
void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
|
||||
{
|
||||
FLAC__ASSERT(0 != object);
|
||||
|
||||
if(0 != object->parameters)
|
||||
free(object->parameters);
|
||||
if(0 != object->raw_bits)
|
||||
free(object->raw_bits);
|
||||
FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object);
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order)
|
||||
{
|
||||
FLAC__ASSERT(0 != object);
|
||||
|
||||
FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits));
|
||||
|
||||
if(object->capacity_by_order < max_partition_order) {
|
||||
if(0 == (object->parameters = realloc(object->parameters, sizeof(unsigned)*(1 << max_partition_order))))
|
||||
return false;
|
||||
if(0 == (object->raw_bits = realloc(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order))))
|
||||
return false;
|
||||
memset(object->raw_bits, 0, sizeof(unsigned)*(1 << max_partition_order));
|
||||
object->capacity_by_order = max_partition_order;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
98
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/ia32/cpu_asm.nasm
vendored
Normal file
98
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/ia32/cpu_asm.nasm
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
; vim:filetype=nasm ts=8
|
||||
|
||||
; libFLAC - Free Lossless Audio Codec library
|
||||
; Copyright (C) 2001-2009 Josh Coalson
|
||||
; Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions
|
||||
; are met:
|
||||
;
|
||||
; - Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
;
|
||||
; - Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
;
|
||||
; - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
; contributors may be used to endorse or promote products derived from
|
||||
; this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
%include "nasm.h"
|
||||
|
||||
data_section
|
||||
|
||||
cglobal FLAC__cpu_have_cpuid_asm_ia32
|
||||
cglobal FLAC__cpu_info_asm_ia32
|
||||
|
||||
code_section
|
||||
|
||||
; **********************************************************************
|
||||
;
|
||||
; FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32()
|
||||
;
|
||||
|
||||
cident FLAC__cpu_have_cpuid_asm_ia32
|
||||
pushfd
|
||||
pop eax
|
||||
mov edx, eax
|
||||
xor eax, 0x00200000
|
||||
push eax
|
||||
popfd
|
||||
pushfd
|
||||
pop eax
|
||||
xor eax, edx
|
||||
and eax, 0x00200000
|
||||
shr eax, 0x15
|
||||
push edx
|
||||
popfd
|
||||
ret
|
||||
|
||||
; **********************************************************************
|
||||
;
|
||||
; void FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx)
|
||||
;
|
||||
|
||||
cident FLAC__cpu_info_asm_ia32
|
||||
;[esp + 8] == flags_edx
|
||||
;[esp + 12] == flags_ecx
|
||||
|
||||
push ebx
|
||||
call FLAC__cpu_have_cpuid_asm_ia32
|
||||
test eax, eax
|
||||
jz .no_cpuid
|
||||
mov eax, 0
|
||||
cpuid
|
||||
cmp eax, 1
|
||||
jb .no_cpuid
|
||||
mov eax, 1
|
||||
cpuid
|
||||
mov ebx, [esp + 8]
|
||||
mov [ebx], edx
|
||||
mov ebx, [esp + 12]
|
||||
mov [ebx], ecx
|
||||
jmp .end
|
||||
.no_cpuid:
|
||||
xor eax, eax
|
||||
mov ebx, [esp + 8]
|
||||
mov [ebx], eax
|
||||
mov ebx, [esp + 12]
|
||||
mov [ebx], eax
|
||||
.end:
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
; end
|
||||
309
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/ia32/fixed_asm.nasm
vendored
Normal file
309
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/ia32/fixed_asm.nasm
vendored
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
; vim:filetype=nasm ts=8
|
||||
|
||||
; libFLAC - Free Lossless Audio Codec library
|
||||
; Copyright (C) 2001-2009 Josh Coalson
|
||||
; Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions
|
||||
; are met:
|
||||
;
|
||||
; - Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
;
|
||||
; - Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
;
|
||||
; - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
; contributors may be used to endorse or promote products derived from
|
||||
; this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
%include "nasm.h"
|
||||
|
||||
data_section
|
||||
|
||||
cglobal FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov
|
||||
|
||||
code_section
|
||||
|
||||
; **********************************************************************
|
||||
;
|
||||
; unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 *data, unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
|
||||
; {
|
||||
; FLAC__int32 last_error_0 = data[-1];
|
||||
; FLAC__int32 last_error_1 = data[-1] - data[-2];
|
||||
; FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]);
|
||||
; FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]);
|
||||
; FLAC__int32 error, save;
|
||||
; FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0;
|
||||
; unsigned i, order;
|
||||
;
|
||||
; for(i = 0; i < data_len; i++) {
|
||||
; error = data[i] ; total_error_0 += local_abs(error); save = error;
|
||||
; error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error;
|
||||
; error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error;
|
||||
; error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error;
|
||||
; error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save;
|
||||
; }
|
||||
;
|
||||
; if(total_error_0 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4))
|
||||
; order = 0;
|
||||
; else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4))
|
||||
; order = 1;
|
||||
; else if(total_error_2 < min(total_error_3, total_error_4))
|
||||
; order = 2;
|
||||
; else if(total_error_3 < total_error_4)
|
||||
; order = 3;
|
||||
; else
|
||||
; order = 4;
|
||||
;
|
||||
; residual_bits_per_sample[0] = (FLAC__float)((data_len > 0 && total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
; residual_bits_per_sample[1] = (FLAC__float)((data_len > 0 && total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
; residual_bits_per_sample[2] = (FLAC__float)((data_len > 0 && total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
; residual_bits_per_sample[3] = (FLAC__float)((data_len > 0 && total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
; residual_bits_per_sample[4] = (FLAC__float)((data_len > 0 && total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
;
|
||||
; return order;
|
||||
; }
|
||||
ALIGN 16
|
||||
cident FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov
|
||||
|
||||
; esp + 36 == data[]
|
||||
; esp + 40 == data_len
|
||||
; esp + 44 == residual_bits_per_sample[]
|
||||
|
||||
push ebp
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
sub esp, byte 16
|
||||
; qword [esp] == temp space for loading FLAC__uint64s to FPU regs
|
||||
|
||||
; ebx == &data[i]
|
||||
; ecx == loop counter (i)
|
||||
; ebp == order
|
||||
; mm0 == total_error_1:total_error_0
|
||||
; mm1 == total_error_2:total_error_3
|
||||
; mm2 == :total_error_4
|
||||
; mm3 == last_error_1:last_error_0
|
||||
; mm4 == last_error_2:last_error_3
|
||||
|
||||
mov ecx, [esp + 40] ; ecx = data_len
|
||||
test ecx, ecx
|
||||
jz near .data_len_is_0
|
||||
|
||||
mov ebx, [esp + 36] ; ebx = data[]
|
||||
movd mm3, [ebx - 4] ; mm3 = 0:last_error_0
|
||||
movd mm2, [ebx - 8] ; mm2 = 0:data[-2]
|
||||
movd mm1, [ebx - 12] ; mm1 = 0:data[-3]
|
||||
movd mm0, [ebx - 16] ; mm0 = 0:data[-4]
|
||||
movq mm5, mm3 ; mm5 = 0:last_error_0
|
||||
psubd mm5, mm2 ; mm5 = 0:last_error_1
|
||||
punpckldq mm3, mm5 ; mm3 = last_error_1:last_error_0
|
||||
psubd mm2, mm1 ; mm2 = 0:data[-2] - data[-3]
|
||||
psubd mm5, mm2 ; mm5 = 0:last_error_2
|
||||
movq mm4, mm5 ; mm4 = 0:last_error_2
|
||||
psubd mm4, mm2 ; mm4 = 0:last_error_2 - (data[-2] - data[-3])
|
||||
paddd mm4, mm1 ; mm4 = 0:last_error_2 - (data[-2] - 2 * data[-3])
|
||||
psubd mm4, mm0 ; mm4 = 0:last_error_3
|
||||
punpckldq mm4, mm5 ; mm4 = last_error_2:last_error_3
|
||||
pxor mm0, mm0 ; mm0 = total_error_1:total_error_0
|
||||
pxor mm1, mm1 ; mm1 = total_error_2:total_error_3
|
||||
pxor mm2, mm2 ; mm2 = 0:total_error_4
|
||||
|
||||
ALIGN 16
|
||||
.loop:
|
||||
movd mm7, [ebx] ; mm7 = 0:error_0
|
||||
add ebx, byte 4
|
||||
movq mm6, mm7 ; mm6 = 0:error_0
|
||||
psubd mm7, mm3 ; mm7 = :error_1
|
||||
punpckldq mm6, mm7 ; mm6 = error_1:error_0
|
||||
movq mm5, mm6 ; mm5 = error_1:error_0
|
||||
movq mm7, mm6 ; mm7 = error_1:error_0
|
||||
psubd mm5, mm3 ; mm5 = error_2:
|
||||
movq mm3, mm6 ; mm3 = error_1:error_0
|
||||
psrad mm6, 31
|
||||
pxor mm7, mm6
|
||||
psubd mm7, mm6 ; mm7 = abs(error_1):abs(error_0)
|
||||
paddd mm0, mm7 ; mm0 = total_error_1:total_error_0
|
||||
movq mm6, mm5 ; mm6 = error_2:
|
||||
psubd mm5, mm4 ; mm5 = error_3:
|
||||
punpckhdq mm5, mm6 ; mm5 = error_2:error_3
|
||||
movq mm7, mm5 ; mm7 = error_2:error_3
|
||||
movq mm6, mm5 ; mm6 = error_2:error_3
|
||||
psubd mm5, mm4 ; mm5 = :error_4
|
||||
movq mm4, mm6 ; mm4 = error_2:error_3
|
||||
psrad mm6, 31
|
||||
pxor mm7, mm6
|
||||
psubd mm7, mm6 ; mm7 = abs(error_2):abs(error_3)
|
||||
paddd mm1, mm7 ; mm1 = total_error_2:total_error_3
|
||||
movq mm6, mm5 ; mm6 = :error_4
|
||||
psrad mm5, 31
|
||||
pxor mm6, mm5
|
||||
psubd mm6, mm5 ; mm6 = :abs(error_4)
|
||||
paddd mm2, mm6 ; mm2 = :total_error_4
|
||||
|
||||
dec ecx
|
||||
jnz short .loop
|
||||
|
||||
; if(total_error_0 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4))
|
||||
; order = 0;
|
||||
; else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4))
|
||||
; order = 1;
|
||||
; else if(total_error_2 < min(total_error_3, total_error_4))
|
||||
; order = 2;
|
||||
; else if(total_error_3 < total_error_4)
|
||||
; order = 3;
|
||||
; else
|
||||
; order = 4;
|
||||
movq mm3, mm0 ; mm3 = total_error_1:total_error_0
|
||||
movd edi, mm2 ; edi = total_error_4
|
||||
movd esi, mm1 ; esi = total_error_3
|
||||
movd eax, mm0 ; eax = total_error_0
|
||||
punpckhdq mm1, mm1 ; mm1 = total_error_2:total_error_2
|
||||
punpckhdq mm3, mm3 ; mm3 = total_error_1:total_error_1
|
||||
movd edx, mm1 ; edx = total_error_2
|
||||
movd ecx, mm3 ; ecx = total_error_1
|
||||
|
||||
xor ebx, ebx
|
||||
xor ebp, ebp
|
||||
inc ebx
|
||||
cmp ecx, eax
|
||||
cmovb eax, ecx ; eax = min(total_error_0, total_error_1)
|
||||
cmovbe ebp, ebx
|
||||
inc ebx
|
||||
cmp edx, eax
|
||||
cmovb eax, edx ; eax = min(total_error_0, total_error_1, total_error_2)
|
||||
cmovbe ebp, ebx
|
||||
inc ebx
|
||||
cmp esi, eax
|
||||
cmovb eax, esi ; eax = min(total_error_0, total_error_1, total_error_2, total_error_3)
|
||||
cmovbe ebp, ebx
|
||||
inc ebx
|
||||
cmp edi, eax
|
||||
cmovb eax, edi ; eax = min(total_error_0, total_error_1, total_error_2, total_error_3, total_error_4)
|
||||
cmovbe ebp, ebx
|
||||
movd ebx, mm0 ; ebx = total_error_0
|
||||
emms
|
||||
|
||||
; residual_bits_per_sample[0] = (FLAC__float)((data_len > 0 && total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
; residual_bits_per_sample[1] = (FLAC__float)((data_len > 0 && total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
; residual_bits_per_sample[2] = (FLAC__float)((data_len > 0 && total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
; residual_bits_per_sample[3] = (FLAC__float)((data_len > 0 && total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
; residual_bits_per_sample[4] = (FLAC__float)((data_len > 0 && total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
|
||||
xor eax, eax
|
||||
fild dword [esp + 40] ; ST = data_len (NOTE: assumes data_len is <2gigs)
|
||||
.rbps_0:
|
||||
test ebx, ebx
|
||||
jz .total_error_0_is_0
|
||||
fld1 ; ST = 1.0 data_len
|
||||
mov [esp], ebx
|
||||
mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_0
|
||||
mov ebx, [esp + 44]
|
||||
fild qword [esp] ; ST = total_error_0 1.0 data_len
|
||||
fdiv st2 ; ST = total_error_0/data_len 1.0 data_len
|
||||
fldln2 ; ST = ln2 total_error_0/data_len 1.0 data_len
|
||||
fmulp st1 ; ST = ln2*total_error_0/data_len 1.0 data_len
|
||||
fyl2x ; ST = log2(ln2*total_error_0/data_len) data_len
|
||||
fstp dword [ebx] ; residual_bits_per_sample[0] = log2(ln2*total_error_0/data_len) ST = data_len
|
||||
jmp short .rbps_1
|
||||
.total_error_0_is_0:
|
||||
mov ebx, [esp + 44]
|
||||
mov [ebx], eax ; residual_bits_per_sample[0] = 0.0
|
||||
.rbps_1:
|
||||
test ecx, ecx
|
||||
jz .total_error_1_is_0
|
||||
fld1 ; ST = 1.0 data_len
|
||||
mov [esp], ecx
|
||||
mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_1
|
||||
fild qword [esp] ; ST = total_error_1 1.0 data_len
|
||||
fdiv st2 ; ST = total_error_1/data_len 1.0 data_len
|
||||
fldln2 ; ST = ln2 total_error_1/data_len 1.0 data_len
|
||||
fmulp st1 ; ST = ln2*total_error_1/data_len 1.0 data_len
|
||||
fyl2x ; ST = log2(ln2*total_error_1/data_len) data_len
|
||||
fstp dword [ebx + 4] ; residual_bits_per_sample[1] = log2(ln2*total_error_1/data_len) ST = data_len
|
||||
jmp short .rbps_2
|
||||
.total_error_1_is_0:
|
||||
mov [ebx + 4], eax ; residual_bits_per_sample[1] = 0.0
|
||||
.rbps_2:
|
||||
test edx, edx
|
||||
jz .total_error_2_is_0
|
||||
fld1 ; ST = 1.0 data_len
|
||||
mov [esp], edx
|
||||
mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_2
|
||||
fild qword [esp] ; ST = total_error_2 1.0 data_len
|
||||
fdiv st2 ; ST = total_error_2/data_len 1.0 data_len
|
||||
fldln2 ; ST = ln2 total_error_2/data_len 1.0 data_len
|
||||
fmulp st1 ; ST = ln2*total_error_2/data_len 1.0 data_len
|
||||
fyl2x ; ST = log2(ln2*total_error_2/data_len) data_len
|
||||
fstp dword [ebx + 8] ; residual_bits_per_sample[2] = log2(ln2*total_error_2/data_len) ST = data_len
|
||||
jmp short .rbps_3
|
||||
.total_error_2_is_0:
|
||||
mov [ebx + 8], eax ; residual_bits_per_sample[2] = 0.0
|
||||
.rbps_3:
|
||||
test esi, esi
|
||||
jz .total_error_3_is_0
|
||||
fld1 ; ST = 1.0 data_len
|
||||
mov [esp], esi
|
||||
mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_3
|
||||
fild qword [esp] ; ST = total_error_3 1.0 data_len
|
||||
fdiv st2 ; ST = total_error_3/data_len 1.0 data_len
|
||||
fldln2 ; ST = ln2 total_error_3/data_len 1.0 data_len
|
||||
fmulp st1 ; ST = ln2*total_error_3/data_len 1.0 data_len
|
||||
fyl2x ; ST = log2(ln2*total_error_3/data_len) data_len
|
||||
fstp dword [ebx + 12] ; residual_bits_per_sample[3] = log2(ln2*total_error_3/data_len) ST = data_len
|
||||
jmp short .rbps_4
|
||||
.total_error_3_is_0:
|
||||
mov [ebx + 12], eax ; residual_bits_per_sample[3] = 0.0
|
||||
.rbps_4:
|
||||
test edi, edi
|
||||
jz .total_error_4_is_0
|
||||
fld1 ; ST = 1.0 data_len
|
||||
mov [esp], edi
|
||||
mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_4
|
||||
fild qword [esp] ; ST = total_error_4 1.0 data_len
|
||||
fdiv st2 ; ST = total_error_4/data_len 1.0 data_len
|
||||
fldln2 ; ST = ln2 total_error_4/data_len 1.0 data_len
|
||||
fmulp st1 ; ST = ln2*total_error_4/data_len 1.0 data_len
|
||||
fyl2x ; ST = log2(ln2*total_error_4/data_len) data_len
|
||||
fstp dword [ebx + 16] ; residual_bits_per_sample[4] = log2(ln2*total_error_4/data_len) ST = data_len
|
||||
jmp short .rbps_end
|
||||
.total_error_4_is_0:
|
||||
mov [ebx + 16], eax ; residual_bits_per_sample[4] = 0.0
|
||||
.rbps_end:
|
||||
fstp st0 ; ST = [empty]
|
||||
jmp short .end
|
||||
.data_len_is_0:
|
||||
; data_len == 0, so residual_bits_per_sample[*] = 0.0
|
||||
xor ebp, ebp
|
||||
mov edi, [esp + 44]
|
||||
mov [edi], ebp
|
||||
mov [edi + 4], ebp
|
||||
mov [edi + 8], ebp
|
||||
mov [edi + 12], ebp
|
||||
mov [edi + 16], ebp
|
||||
add ebp, byte 4 ; order = 4
|
||||
|
||||
.end:
|
||||
mov eax, ebp ; return order
|
||||
add esp, byte 16
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
; end
|
||||
2049
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/ia32/lpc_asm.nasm
vendored
Normal file
2049
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/ia32/lpc_asm.nasm
vendored
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,85 @@
|
|||
; libFLAC - Free Lossless Audio Codec library
|
||||
; Copyright (C) 2001-2009 Josh Coalson
|
||||
; Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
;
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions
|
||||
; are met:
|
||||
;
|
||||
; - Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
;
|
||||
; - Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
;
|
||||
; - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
; contributors may be used to endorse or promote products derived from
|
||||
; this software without specific prior written permission.
|
||||
;
|
||||
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
bits 32
|
||||
|
||||
%ifdef OBJ_FORMAT_win32
|
||||
%define FLAC__PUBLIC_NEEDS_UNDERSCORE
|
||||
%idefine code_section section .text align=16 class=CODE use32
|
||||
%idefine data_section section .data align=32 class=DATA use32
|
||||
%idefine bss_section section .bss align=32 class=DATA use32
|
||||
%elifdef OBJ_FORMAT_aout
|
||||
%define FLAC__PUBLIC_NEEDS_UNDERSCORE
|
||||
%idefine code_section section .text
|
||||
%idefine data_section section .data
|
||||
%idefine bss_section section .bss
|
||||
%elifdef OBJ_FORMAT_aoutb
|
||||
%define FLAC__PUBLIC_NEEDS_UNDERSCORE
|
||||
%idefine code_section section .text
|
||||
%idefine data_section section .data
|
||||
%idefine bss_section section .bss
|
||||
%elifdef OBJ_FORMAT_elf
|
||||
%idefine code_section section .text align=16
|
||||
%idefine data_section section .data align=32
|
||||
%idefine bss_section section .bss align=32
|
||||
%else
|
||||
%error unsupported object format!
|
||||
%endif
|
||||
|
||||
%imacro cglobal 1
|
||||
%ifdef FLAC__PUBLIC_NEEDS_UNDERSCORE
|
||||
global _%1
|
||||
%else
|
||||
%if __NASM_MAJOR__ >= 2
|
||||
global %1:function hidden
|
||||
%else
|
||||
global %1
|
||||
%endif
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%imacro cextern 1
|
||||
%ifdef FLAC__PUBLIC_NEEDS_UNDERSCORE
|
||||
extern _%1
|
||||
%else
|
||||
extern %1
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%imacro cident 1
|
||||
_%1:
|
||||
%1:
|
||||
%endmacro
|
||||
|
||||
%ifdef OBJ_FORMAT_elf
|
||||
section .note.GNU-stack progbits noalloc noexec nowrite align=1
|
||||
%endif
|
||||
|
||||
50
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/all.h
vendored
Normal file
50
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/all.h
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__ALL_H
|
||||
#define FLAC__PRIVATE__ALL_H
|
||||
|
||||
#include "bitmath.h"
|
||||
#include "bitreader.h"
|
||||
#include "bitwriter.h"
|
||||
#include "cpu.h"
|
||||
#include "crc.h"
|
||||
#include "fixed.h"
|
||||
#include "float.h"
|
||||
#include "format.h"
|
||||
#include "lpc.h"
|
||||
#include "md5.h"
|
||||
#include "memory.h"
|
||||
#include "metadata.h"
|
||||
#include "stream_encoder_framing.h"
|
||||
|
||||
#endif
|
||||
186
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/bitmath.h
vendored
Normal file
186
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/bitmath.h
vendored
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__BITMATH_H
|
||||
#define FLAC__PRIVATE__BITMATH_H
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
#include "FLAC/assert.h"
|
||||
|
||||
/* for CHAR_BIT */
|
||||
#include <limits.h>
|
||||
#include "share/compat.h"
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
#include <intrin.h> /* for _BitScanReverse* */
|
||||
#endif
|
||||
|
||||
/* Will never be emitted for MSVC, GCC, Intel compilers */
|
||||
static inline unsigned int FLAC__clz_soft_uint32(unsigned int word)
|
||||
{
|
||||
static const unsigned char byte_to_unary_table[] = {
|
||||
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
return (word) > 0xffffff ? byte_to_unary_table[(word) >> 24] :
|
||||
(word) > 0xffff ? byte_to_unary_table[(word) >> 16] + 8 :
|
||||
(word) > 0xff ? byte_to_unary_table[(word) >> 8] + 16 :
|
||||
byte_to_unary_table[(word)] + 24;
|
||||
}
|
||||
|
||||
static inline unsigned int FLAC__clz_uint32(FLAC__uint32 v)
|
||||
{
|
||||
/* Never used with input 0 */
|
||||
FLAC__ASSERT(v > 0);
|
||||
#if defined(__INTEL_COMPILER)
|
||||
return _bit_scan_reverse(v) ^ 31U;
|
||||
#elif defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
|
||||
/* This will translate either to (bsr ^ 31U), clz , ctlz, cntlz, lzcnt depending on
|
||||
* -march= setting or to a software routine in exotic machines. */
|
||||
return __builtin_clz(v);
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
{
|
||||
unsigned long idx;
|
||||
_BitScanReverse(&idx, v);
|
||||
return idx ^ 31U;
|
||||
}
|
||||
#else
|
||||
return FLAC__clz_soft_uint32(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This one works with input 0 */
|
||||
static inline unsigned int FLAC__clz2_uint32(FLAC__uint32 v)
|
||||
{
|
||||
if (!v)
|
||||
return 32;
|
||||
return FLAC__clz_uint32(v);
|
||||
}
|
||||
|
||||
/* An example of what FLAC__bitmath_ilog2() computes:
|
||||
*
|
||||
* ilog2( 0) = assertion failure
|
||||
* ilog2( 1) = 0
|
||||
* ilog2( 2) = 1
|
||||
* ilog2( 3) = 1
|
||||
* ilog2( 4) = 2
|
||||
* ilog2( 5) = 2
|
||||
* ilog2( 6) = 2
|
||||
* ilog2( 7) = 2
|
||||
* ilog2( 8) = 3
|
||||
* ilog2( 9) = 3
|
||||
* ilog2(10) = 3
|
||||
* ilog2(11) = 3
|
||||
* ilog2(12) = 3
|
||||
* ilog2(13) = 3
|
||||
* ilog2(14) = 3
|
||||
* ilog2(15) = 3
|
||||
* ilog2(16) = 4
|
||||
* ilog2(17) = 4
|
||||
* ilog2(18) = 4
|
||||
*/
|
||||
|
||||
static inline unsigned FLAC__bitmath_ilog2(FLAC__uint32 v)
|
||||
{
|
||||
FLAC__ASSERT(v > 0);
|
||||
#if defined(__INTEL_COMPILER)
|
||||
return _bit_scan_reverse(v);
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
{
|
||||
unsigned long idx;
|
||||
_BitScanReverse(&idx, v);
|
||||
return idx;
|
||||
}
|
||||
#else
|
||||
return sizeof(FLAC__uint32) * CHAR_BIT - 1 - FLAC__clz_uint32(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef FLAC__INTEGER_ONLY_LIBRARY /* Unused otherwise */
|
||||
|
||||
static inline unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v)
|
||||
{
|
||||
FLAC__ASSERT(v > 0);
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
|
||||
return sizeof(FLAC__uint64) * CHAR_BIT - 1 - __builtin_clzll(v);
|
||||
/* Sorry, only supported in x64/Itanium.. and both have fast FPU which makes integer-only encoder pointless */
|
||||
#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && (defined(_M_IA64) || defined(_M_X64))
|
||||
{
|
||||
unsigned long idx;
|
||||
_BitScanReverse64(&idx, v);
|
||||
return idx;
|
||||
}
|
||||
#else
|
||||
/* Brain-damaged compilers will use the fastest possible way that is,
|
||||
de Bruijn sequences (http://supertech.csail.mit.edu/papers/debruijn.pdf)
|
||||
(C) Timothy B. Terriberry (tterribe@xiph.org) 2001-2009 CC0 (Public domain).
|
||||
*/
|
||||
{
|
||||
static const unsigned char DEBRUIJN_IDX64[64]={
|
||||
0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40,
|
||||
5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57,
|
||||
63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56,
|
||||
62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58
|
||||
};
|
||||
v|= v>>1;
|
||||
v|= v>>2;
|
||||
v|= v>>4;
|
||||
v|= v>>8;
|
||||
v|= v>>16;
|
||||
v|= v>>32;
|
||||
v= (v>>1)+1;
|
||||
return DEBRUIJN_IDX64[v*0x218A392CD3D5DBF>>58&0x3F];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned FLAC__bitmath_silog2(int v);
|
||||
unsigned FLAC__bitmath_silog2_wide(FLAC__int64 v);
|
||||
|
||||
#endif
|
||||
91
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/bitreader.h
vendored
Normal file
91
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/bitreader.h
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__BITREADER_H
|
||||
#define FLAC__PRIVATE__BITREADER_H
|
||||
|
||||
#include <stdio.h> /* for FILE */
|
||||
#include "FLAC/ordinals.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/*
|
||||
* opaque structure definition
|
||||
*/
|
||||
struct FLAC__BitReader;
|
||||
typedef struct FLAC__BitReader FLAC__BitReader;
|
||||
|
||||
typedef FLAC__bool (*FLAC__BitReaderReadCallback)(FLAC__byte buffer[], size_t *bytes, void *client_data);
|
||||
|
||||
/*
|
||||
* construction, deletion, initialization, etc functions
|
||||
*/
|
||||
FLAC__BitReader *FLAC__bitreader_new(void);
|
||||
void FLAC__bitreader_delete(FLAC__BitReader *br);
|
||||
FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd);
|
||||
void FLAC__bitreader_free(FLAC__BitReader *br); /* does not 'free(br)' */
|
||||
FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br);
|
||||
void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out);
|
||||
|
||||
/*
|
||||
* CRC functions
|
||||
*/
|
||||
void FLAC__bitreader_reset_read_crc16(FLAC__BitReader *br, FLAC__uint16 seed);
|
||||
FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br);
|
||||
|
||||
/*
|
||||
* info functions
|
||||
*/
|
||||
FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br);
|
||||
unsigned FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br);
|
||||
unsigned FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br);
|
||||
|
||||
/*
|
||||
* read functions
|
||||
*/
|
||||
|
||||
FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, unsigned bits);
|
||||
FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, unsigned bits);
|
||||
FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *val, unsigned bits);
|
||||
FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val); /*only for bits=32*/
|
||||
FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, unsigned bits); /* WATCHOUT: does not CRC the skipped data! */ /*@@@@ add to unit tests */
|
||||
FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, unsigned nvals); /* WATCHOUT: does not CRC the read data! */
|
||||
FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, FLAC__byte *val, unsigned nvals); /* WATCHOUT: does not CRC the read data! */
|
||||
FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *val);
|
||||
FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, unsigned parameter);
|
||||
FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter);
|
||||
#if 0 /* UNUSED */
|
||||
FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter);
|
||||
FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, unsigned *val, unsigned parameter);
|
||||
#endif
|
||||
FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, unsigned *rawlen);
|
||||
FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, unsigned *rawlen);
|
||||
#endif
|
||||
104
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/bitwriter.h
vendored
Normal file
104
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/bitwriter.h
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__BITWRITER_H
|
||||
#define FLAC__PRIVATE__BITWRITER_H
|
||||
|
||||
#include <stdio.h> /* for FILE */
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
/*
|
||||
* opaque structure definition
|
||||
*/
|
||||
struct FLAC__BitWriter;
|
||||
typedef struct FLAC__BitWriter FLAC__BitWriter;
|
||||
|
||||
/*
|
||||
* construction, deletion, initialization, etc functions
|
||||
*/
|
||||
FLAC__BitWriter *FLAC__bitwriter_new(void);
|
||||
void FLAC__bitwriter_delete(FLAC__BitWriter *bw);
|
||||
FLAC__bool FLAC__bitwriter_init(FLAC__BitWriter *bw);
|
||||
void FLAC__bitwriter_free(FLAC__BitWriter *bw); /* does not 'free(buffer)' */
|
||||
void FLAC__bitwriter_clear(FLAC__BitWriter *bw);
|
||||
void FLAC__bitwriter_dump(const FLAC__BitWriter *bw, FILE *out);
|
||||
|
||||
/*
|
||||
* CRC functions
|
||||
*
|
||||
* non-const *bw because they have to cal FLAC__bitwriter_get_buffer()
|
||||
*/
|
||||
FLAC__bool FLAC__bitwriter_get_write_crc16(FLAC__BitWriter *bw, FLAC__uint16 *crc);
|
||||
FLAC__bool FLAC__bitwriter_get_write_crc8(FLAC__BitWriter *bw, FLAC__byte *crc);
|
||||
|
||||
/*
|
||||
* info functions
|
||||
*/
|
||||
FLAC__bool FLAC__bitwriter_is_byte_aligned(const FLAC__BitWriter *bw);
|
||||
unsigned FLAC__bitwriter_get_input_bits_unconsumed(const FLAC__BitWriter *bw); /* can be called anytime, returns total # of bits unconsumed */
|
||||
|
||||
/*
|
||||
* direct buffer access
|
||||
*
|
||||
* there may be no calls on the bitwriter between get and release.
|
||||
* the bitwriter continues to own the returned buffer.
|
||||
* before get, bitwriter MUST be byte aligned: check with FLAC__bitwriter_is_byte_aligned()
|
||||
*/
|
||||
FLAC__bool FLAC__bitwriter_get_buffer(FLAC__BitWriter *bw, const FLAC__byte **buffer, size_t *bytes);
|
||||
void FLAC__bitwriter_release_buffer(FLAC__BitWriter *bw);
|
||||
|
||||
/*
|
||||
* write functions
|
||||
*/
|
||||
FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bits);
|
||||
FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, unsigned bits);
|
||||
FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, unsigned bits);
|
||||
FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, unsigned bits);
|
||||
FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val); /*only for bits=32*/
|
||||
FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], unsigned nvals);
|
||||
FLAC__bool FLAC__bitwriter_write_unary_unsigned(FLAC__BitWriter *bw, unsigned val);
|
||||
unsigned FLAC__bitwriter_rice_bits(FLAC__int32 val, unsigned parameter);
|
||||
#if 0 /* UNUSED */
|
||||
unsigned FLAC__bitwriter_golomb_bits_signed(int val, unsigned parameter);
|
||||
unsigned FLAC__bitwriter_golomb_bits_unsigned(unsigned val, unsigned parameter);
|
||||
#endif
|
||||
FLAC__bool FLAC__bitwriter_write_rice_signed(FLAC__BitWriter *bw, FLAC__int32 val, unsigned parameter);
|
||||
FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FLAC__int32 *vals, unsigned nvals, unsigned parameter);
|
||||
#if 0 /* UNUSED */
|
||||
FLAC__bool FLAC__bitwriter_write_golomb_signed(FLAC__BitWriter *bw, int val, unsigned parameter);
|
||||
FLAC__bool FLAC__bitwriter_write_golomb_unsigned(FLAC__BitWriter *bw, unsigned val, unsigned parameter);
|
||||
#endif
|
||||
FLAC__bool FLAC__bitwriter_write_utf8_uint32(FLAC__BitWriter *bw, FLAC__uint32 val);
|
||||
FLAC__bool FLAC__bitwriter_write_utf8_uint64(FLAC__BitWriter *bw, FLAC__uint64 val);
|
||||
FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw);
|
||||
|
||||
#endif
|
||||
168
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/cpu.h
vendored
Normal file
168
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/cpu.h
vendored
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__CPU_H
|
||||
#define FLAC__PRIVATE__CPU_H
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined FLAC__HAS_X86INTRIN
|
||||
/* SSE intrinsics support by ICC/MSVC/GCC */
|
||||
#if defined __INTEL_COMPILER
|
||||
#define FLAC__SSE_TARGET(x)
|
||||
#define FLAC__SSE_SUPPORTED 1
|
||||
#define FLAC__SSE2_SUPPORTED 1
|
||||
#if (__INTEL_COMPILER >= 1000) /* Intel C++ Compiler 10.0 */
|
||||
#define FLAC__SSSE3_SUPPORTED 1
|
||||
#define FLAC__SSE4_1_SUPPORTED 1
|
||||
#endif
|
||||
#if (__INTEL_COMPILER >= 1110) /* Intel C++ Compiler 11.1 */
|
||||
#define FLAC__AVX_SUPPORTED 1
|
||||
#endif
|
||||
#if (__INTEL_COMPILER >= 1300) /* Intel C++ Compiler 13.0 */
|
||||
#define FLAC__AVX2_SUPPORTED 1
|
||||
#define FLAC__FMA_SUPPORTED 1
|
||||
#endif
|
||||
#elif defined _MSC_VER
|
||||
#define FLAC__SSE_TARGET(x)
|
||||
#define FLAC__SSE_SUPPORTED 1
|
||||
#define FLAC__SSE2_SUPPORTED 1
|
||||
#if (_MSC_VER >= 1500) /* MS Visual Studio 2008 */
|
||||
#define FLAC__SSSE3_SUPPORTED 1
|
||||
#define FLAC__SSE4_1_SUPPORTED 1
|
||||
#endif
|
||||
#if (_MSC_FULL_VER >= 160040219) /* MS Visual Studio 2010 SP1 */
|
||||
#define FLAC__AVX_SUPPORTED 1
|
||||
#endif
|
||||
#if (_MSC_VER >= 1700) /* MS Visual Studio 2012 */
|
||||
#define FLAC__AVX2_SUPPORTED 1
|
||||
#define FLAC__FMA_SUPPORTED 1
|
||||
#endif
|
||||
#elif defined __GNUC__
|
||||
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) /* since GCC 4.9 -msse.. compiler options aren't necessary */
|
||||
#define FLAC__SSE_TARGET(x) __attribute__ ((__target__ (x)))
|
||||
#define FLAC__SSE_SUPPORTED 1
|
||||
#define FLAC__SSE2_SUPPORTED 1
|
||||
#define FLAC__SSSE3_SUPPORTED 1
|
||||
#define FLAC__SSE4_1_SUPPORTED 1
|
||||
#define FLAC__AVX_SUPPORTED 1
|
||||
#define FLAC__AVX2_SUPPORTED 1
|
||||
#define FLAC__FMA_SUPPORTED 1
|
||||
#else /* for GCC older than 4.9 */
|
||||
#define FLAC__SSE_TARGET(x)
|
||||
#ifdef __SSE__
|
||||
#define FLAC__SSE_SUPPORTED 1
|
||||
#endif
|
||||
#ifdef __SSE2__
|
||||
#define FLAC__SSE2_SUPPORTED 1
|
||||
#endif
|
||||
#ifdef __SSSE3__
|
||||
#define FLAC__SSSE3_SUPPORTED 1
|
||||
#endif
|
||||
#ifdef __SSE4_1__
|
||||
#define FLAC__SSE4_1_SUPPORTED 1
|
||||
#endif
|
||||
#ifdef __AVX__
|
||||
#define FLAC__AVX_SUPPORTED 1
|
||||
#endif
|
||||
#ifdef __AVX2__
|
||||
#define FLAC__AVX2_SUPPORTED 1
|
||||
#endif
|
||||
#ifdef __FMA__
|
||||
#define FLAC__FMA_SUPPORTED 1
|
||||
#endif
|
||||
#endif /* GCC version */
|
||||
#endif /* compiler version */
|
||||
#endif /* intrinsics support */
|
||||
|
||||
typedef enum {
|
||||
FLAC__CPUINFO_TYPE_IA32,
|
||||
FLAC__CPUINFO_TYPE_X86_64,
|
||||
FLAC__CPUINFO_TYPE_UNKNOWN
|
||||
} FLAC__CPUInfo_Type;
|
||||
|
||||
#if defined FLAC__CPU_IA32
|
||||
typedef struct {
|
||||
FLAC__bool cmov;
|
||||
FLAC__bool mmx;
|
||||
FLAC__bool sse;
|
||||
FLAC__bool sse2;
|
||||
|
||||
FLAC__bool sse3;
|
||||
FLAC__bool ssse3;
|
||||
FLAC__bool sse41;
|
||||
FLAC__bool sse42;
|
||||
FLAC__bool avx;
|
||||
FLAC__bool avx2;
|
||||
FLAC__bool fma;
|
||||
} FLAC__CPUInfo_IA32;
|
||||
#elif defined FLAC__CPU_X86_64
|
||||
typedef struct {
|
||||
FLAC__bool sse3;
|
||||
FLAC__bool ssse3;
|
||||
FLAC__bool sse41;
|
||||
FLAC__bool sse42;
|
||||
FLAC__bool avx;
|
||||
FLAC__bool avx2;
|
||||
FLAC__bool fma;
|
||||
} FLAC__CPUInfo_x86;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
FLAC__bool use_asm;
|
||||
FLAC__CPUInfo_Type type;
|
||||
#if defined FLAC__CPU_IA32
|
||||
FLAC__CPUInfo_IA32 ia32;
|
||||
#elif defined FLAC__CPU_X86_64
|
||||
FLAC__CPUInfo_x86 x86;
|
||||
#endif
|
||||
} FLAC__CPUInfo;
|
||||
|
||||
void FLAC__cpu_info(FLAC__CPUInfo *info);
|
||||
|
||||
#ifndef FLAC__NO_ASM
|
||||
# if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM
|
||||
FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32(void);
|
||||
void FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx);
|
||||
# endif
|
||||
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
|
||||
FLAC__uint32 FLAC__cpu_have_cpuid_x86(void);
|
||||
void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx);
|
||||
FLAC__uint32 FLAC__cpu_xgetbv_x86(void);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
62
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/crc.h
vendored
Normal file
62
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/crc.h
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__CRC_H
|
||||
#define FLAC__PRIVATE__CRC_H
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
/* 8 bit CRC generator, MSB shifted first
|
||||
** polynomial = x^8 + x^2 + x^1 + x^0
|
||||
** init = 0
|
||||
*/
|
||||
extern FLAC__byte const FLAC__crc8_table[256];
|
||||
#define FLAC__CRC8_UPDATE(data, crc) (crc) = FLAC__crc8_table[(crc) ^ (data)];
|
||||
void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc);
|
||||
void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc);
|
||||
FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len);
|
||||
|
||||
/* 16 bit CRC generator, MSB shifted first
|
||||
** polynomial = x^16 + x^15 + x^2 + x^0
|
||||
** init = 0
|
||||
*/
|
||||
extern unsigned const FLAC__crc16_table[256];
|
||||
|
||||
#define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) & 0xffff) ^ FLAC__crc16_table[((crc)>>8) ^ (data)])
|
||||
/* this alternate may be faster on some systems/compilers */
|
||||
#if 0
|
||||
#define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]) & 0xffff)
|
||||
#endif
|
||||
|
||||
unsigned FLAC__crc16(const FLAC__byte *data, unsigned len);
|
||||
|
||||
#endif
|
||||
107
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/fixed.h
vendored
Normal file
107
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/fixed.h
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__FIXED_H
|
||||
#define FLAC__PRIVATE__FIXED_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/cpu.h"
|
||||
#include "private/float.h"
|
||||
#include "FLAC/format.h"
|
||||
|
||||
/*
|
||||
* FLAC__fixed_compute_best_predictor()
|
||||
* --------------------------------------------------------------------
|
||||
* Compute the best fixed predictor and the expected bits-per-sample
|
||||
* of the residual signal for each order. The _wide() version uses
|
||||
* 64-bit integers which is statistically necessary when bits-per-
|
||||
* sample + log2(blocksize) > 30
|
||||
*
|
||||
* IN data[0,data_len-1]
|
||||
* IN data_len
|
||||
* OUT residual_bits_per_sample[0,FLAC__MAX_FIXED_ORDER]
|
||||
*/
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
|
||||
# ifndef FLAC__NO_ASM
|
||||
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
|
||||
# ifdef FLAC__SSE2_SUPPORTED
|
||||
unsigned FLAC__fixed_compute_best_predictor_intrin_sse2(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]);
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide_intrin_sse2(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]);
|
||||
# endif
|
||||
# ifdef FLAC__SSSE3_SUPPORTED
|
||||
unsigned FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]);
|
||||
# endif
|
||||
# endif
|
||||
# if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM
|
||||
unsigned FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FLAC__fixed_compute_residual()
|
||||
* --------------------------------------------------------------------
|
||||
* Compute the residual signal obtained from sutracting the predicted
|
||||
* signal from the original.
|
||||
*
|
||||
* IN data[-order,data_len-1] original signal (NOTE THE INDICES!)
|
||||
* IN data_len length of original signal
|
||||
* IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order
|
||||
* OUT residual[0,data_len-1] residual signal
|
||||
*/
|
||||
void FLAC__fixed_compute_residual(const FLAC__int32 data[], unsigned data_len, unsigned order, FLAC__int32 residual[]);
|
||||
|
||||
/*
|
||||
* FLAC__fixed_restore_signal()
|
||||
* --------------------------------------------------------------------
|
||||
* Restore the original signal by summing the residual and the
|
||||
* predictor.
|
||||
*
|
||||
* IN residual[0,data_len-1] residual signal
|
||||
* IN data_len length of original signal
|
||||
* IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order
|
||||
* *** IMPORTANT: the caller must pass in the historical samples:
|
||||
* IN data[-order,-1] previously-reconstructed historical samples
|
||||
* OUT data[0,data_len-1] original signal
|
||||
*/
|
||||
void FLAC__fixed_restore_signal(const FLAC__int32 residual[], unsigned data_len, unsigned order, FLAC__int32 data[]);
|
||||
|
||||
#endif
|
||||
98
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/float.h
vendored
Normal file
98
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/float.h
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2004-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__FLOAT_H
|
||||
#define FLAC__PRIVATE__FLOAT_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
/*
|
||||
* These typedefs make it easier to ensure that integer versions of
|
||||
* the library really only contain integer operations. All the code
|
||||
* in libFLAC should use FLAC__float and FLAC__double in place of
|
||||
* float and double, and be protected by checks of the macro
|
||||
* FLAC__INTEGER_ONLY_LIBRARY.
|
||||
*
|
||||
* FLAC__real is the basic floating point type used in LPC analysis.
|
||||
*/
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
typedef double FLAC__double;
|
||||
typedef float FLAC__float;
|
||||
/*
|
||||
* WATCHOUT: changing FLAC__real will change the signatures of many
|
||||
* functions that have assembly language equivalents and break them.
|
||||
*/
|
||||
typedef float FLAC__real;
|
||||
#else
|
||||
/*
|
||||
* The convention for FLAC__fixedpoint is to use the upper 16 bits
|
||||
* for the integer part and lower 16 bits for the fractional part.
|
||||
*/
|
||||
typedef FLAC__int32 FLAC__fixedpoint;
|
||||
extern const FLAC__fixedpoint FLAC__FP_ZERO;
|
||||
extern const FLAC__fixedpoint FLAC__FP_ONE_HALF;
|
||||
extern const FLAC__fixedpoint FLAC__FP_ONE;
|
||||
extern const FLAC__fixedpoint FLAC__FP_LN2;
|
||||
extern const FLAC__fixedpoint FLAC__FP_E;
|
||||
|
||||
#define FLAC__fixedpoint_trunc(x) ((x)>>16)
|
||||
|
||||
#define FLAC__fixedpoint_mul(x, y) ( (FLAC__fixedpoint) ( ((FLAC__int64)(x)*(FLAC__int64)(y)) >> 16 ) )
|
||||
|
||||
#define FLAC__fixedpoint_div(x, y) ( (FLAC__fixedpoint) ( ( ((FLAC__int64)(x)<<32) / (FLAC__int64)(y) ) >> 16 ) )
|
||||
|
||||
/*
|
||||
* FLAC__fixedpoint_log2()
|
||||
* --------------------------------------------------------------------
|
||||
* Returns the base-2 logarithm of the fixed-point number 'x' using an
|
||||
* algorithm by Knuth for x >= 1.0
|
||||
*
|
||||
* 'fracbits' is the number of fractional bits of 'x'. 'fracbits' must
|
||||
* be < 32 and evenly divisible by 4 (0 is OK but not very precise).
|
||||
*
|
||||
* 'precision' roughly limits the number of iterations that are done;
|
||||
* use (unsigned)(-1) for maximum precision.
|
||||
*
|
||||
* If 'x' is less than one -- that is, x < (1<<fracbits) -- then this
|
||||
* function will punt and return 0.
|
||||
*
|
||||
* The return value will also have 'fracbits' fractional bits.
|
||||
*/
|
||||
FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
45
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/format.h
vendored
Normal file
45
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/format.h
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__FORMAT_H
|
||||
#define FLAC__PRIVATE__FORMAT_H
|
||||
|
||||
#include "FLAC/format.h"
|
||||
|
||||
unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order);
|
||||
unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize);
|
||||
unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order);
|
||||
void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object);
|
||||
void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object);
|
||||
FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order);
|
||||
|
||||
#endif
|
||||
246
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/lpc.h
vendored
Normal file
246
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/lpc.h
vendored
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__LPC_H
|
||||
#define FLAC__PRIVATE__LPC_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/cpu.h"
|
||||
#include "private/float.h"
|
||||
#include "FLAC/format.h"
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
|
||||
/*
|
||||
* FLAC__lpc_window_data()
|
||||
* --------------------------------------------------------------------
|
||||
* Applies the given window to the data.
|
||||
* OPT: asm implementation
|
||||
*
|
||||
* IN in[0,data_len-1]
|
||||
* IN window[0,data_len-1]
|
||||
* OUT out[0,lag-1]
|
||||
* IN data_len
|
||||
*/
|
||||
void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len);
|
||||
|
||||
/*
|
||||
* FLAC__lpc_compute_autocorrelation()
|
||||
* --------------------------------------------------------------------
|
||||
* Compute the autocorrelation for lags between 0 and lag-1.
|
||||
* Assumes data[] outside of [0,data_len-1] == 0.
|
||||
* Asserts that lag > 0.
|
||||
*
|
||||
* IN data[0,data_len-1]
|
||||
* IN data_len
|
||||
* IN 0 < lag <= data_len
|
||||
* OUT autoc[0,lag-1]
|
||||
*/
|
||||
void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
#ifndef FLAC__NO_ASM
|
||||
# ifdef FLAC__CPU_IA32
|
||||
# ifdef FLAC__HAS_NASM
|
||||
void FLAC__lpc_compute_autocorrelation_asm_ia32(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
# endif
|
||||
# endif
|
||||
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
|
||||
# ifdef FLAC__SSE_SUPPORTED
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FLAC__lpc_compute_lp_coefficients()
|
||||
* --------------------------------------------------------------------
|
||||
* Computes LP coefficients for orders 1..max_order.
|
||||
* Do not call if autoc[0] == 0.0. This means the signal is zero
|
||||
* and there is no point in calculating a predictor.
|
||||
*
|
||||
* IN autoc[0,max_order] autocorrelation values
|
||||
* IN 0 < max_order <= FLAC__MAX_LPC_ORDER max LP order to compute
|
||||
* OUT lp_coeff[0,max_order-1][0,max_order-1] LP coefficients for each order
|
||||
* *** IMPORTANT:
|
||||
* *** lp_coeff[0,max_order-1][max_order,FLAC__MAX_LPC_ORDER-1] are untouched
|
||||
* OUT error[0,max_order-1] error for each order (more
|
||||
* specifically, the variance of
|
||||
* the error signal times # of
|
||||
* samples in the signal)
|
||||
*
|
||||
* Example: if max_order is 9, the LP coefficients for order 9 will be
|
||||
* in lp_coeff[8][0,8], the LP coefficients for order 8 will be
|
||||
* in lp_coeff[7][0,7], etc.
|
||||
*/
|
||||
void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], FLAC__double error[]);
|
||||
|
||||
/*
|
||||
* FLAC__lpc_quantize_coefficients()
|
||||
* --------------------------------------------------------------------
|
||||
* Quantizes the LP coefficients. NOTE: precision + bits_per_sample
|
||||
* must be less than 32 (sizeof(FLAC__int32)*8).
|
||||
*
|
||||
* IN lp_coeff[0,order-1] LP coefficients
|
||||
* IN order LP order
|
||||
* IN FLAC__MIN_QLP_COEFF_PRECISION < precision
|
||||
* desired precision (in bits, including sign
|
||||
* bit) of largest coefficient
|
||||
* OUT qlp_coeff[0,order-1] quantized coefficients
|
||||
* OUT shift # of bits to shift right to get approximated
|
||||
* LP coefficients. NOTE: could be negative.
|
||||
* RETURN 0 => quantization OK
|
||||
* 1 => coefficients require too much shifting for *shift to
|
||||
* fit in the LPC subframe header. 'shift' is unset.
|
||||
* 2 => coefficients are all zero, which is bad. 'shift' is
|
||||
* unset.
|
||||
*/
|
||||
int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, unsigned precision, FLAC__int32 qlp_coeff[], int *shift);
|
||||
|
||||
/*
|
||||
* FLAC__lpc_compute_residual_from_qlp_coefficients()
|
||||
* --------------------------------------------------------------------
|
||||
* Compute the residual signal obtained from sutracting the predicted
|
||||
* signal from the original.
|
||||
*
|
||||
* IN data[-order,data_len-1] original signal (NOTE THE INDICES!)
|
||||
* IN data_len length of original signal
|
||||
* IN qlp_coeff[0,order-1] quantized LP coefficients
|
||||
* IN order > 0 LP order
|
||||
* IN lp_quantization quantization of LP coefficients in bits
|
||||
* OUT residual[0,data_len-1] residual signal
|
||||
*/
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
#ifndef FLAC__NO_ASM
|
||||
# ifdef FLAC__CPU_IA32
|
||||
# ifdef FLAC__HAS_NASM
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
# endif
|
||||
# endif
|
||||
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
|
||||
# ifdef FLAC__SSE2_SUPPORTED
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
# endif
|
||||
# ifdef FLAC__SSE4_1_SUPPORTED
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
# endif
|
||||
# ifdef FLAC__AVX2_SUPPORTED
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
|
||||
|
||||
/*
|
||||
* FLAC__lpc_restore_signal()
|
||||
* --------------------------------------------------------------------
|
||||
* Restore the original signal by summing the residual and the
|
||||
* predictor.
|
||||
*
|
||||
* IN residual[0,data_len-1] residual signal
|
||||
* IN data_len length of original signal
|
||||
* IN qlp_coeff[0,order-1] quantized LP coefficients
|
||||
* IN order > 0 LP order
|
||||
* IN lp_quantization quantization of LP coefficients in bits
|
||||
* *** IMPORTANT: the caller must pass in the historical samples:
|
||||
* IN data[-order,-1] previously-reconstructed historical samples
|
||||
* OUT data[0,data_len-1] original signal
|
||||
*/
|
||||
void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
|
||||
void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
|
||||
#ifndef FLAC__NO_ASM
|
||||
# ifdef FLAC__CPU_IA32
|
||||
# ifdef FLAC__HAS_NASM
|
||||
void FLAC__lpc_restore_signal_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
|
||||
void FLAC__lpc_restore_signal_asm_ia32_mmx(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
|
||||
void FLAC__lpc_restore_signal_wide_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
|
||||
# endif /* FLAC__HAS_NASM */
|
||||
# endif /* FLAC__CPU_IA32 */
|
||||
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
|
||||
# ifdef FLAC__SSE2_SUPPORTED
|
||||
void FLAC__lpc_restore_signal_16_intrin_sse2(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
|
||||
# endif
|
||||
# ifdef FLAC__SSE4_1_SUPPORTED
|
||||
void FLAC__lpc_restore_signal_wide_intrin_sse41(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
|
||||
# endif
|
||||
# endif
|
||||
#endif /* FLAC__NO_ASM */
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
|
||||
/*
|
||||
* FLAC__lpc_compute_expected_bits_per_residual_sample()
|
||||
* --------------------------------------------------------------------
|
||||
* Compute the expected number of bits per residual signal sample
|
||||
* based on the LP error (which is related to the residual variance).
|
||||
*
|
||||
* IN lpc_error >= 0.0 error returned from calculating LP coefficients
|
||||
* IN total_samples > 0 # of samples in residual signal
|
||||
* RETURN expected bits per sample
|
||||
*/
|
||||
FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples);
|
||||
FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(FLAC__double lpc_error, FLAC__double error_scale);
|
||||
|
||||
/*
|
||||
* FLAC__lpc_compute_best_order()
|
||||
* --------------------------------------------------------------------
|
||||
* Compute the best order from the array of signal errors returned
|
||||
* during coefficient computation.
|
||||
*
|
||||
* IN lpc_error[0,max_order-1] >= 0.0 error returned from calculating LP coefficients
|
||||
* IN max_order > 0 max LP order
|
||||
* IN total_samples > 0 # of samples in residual signal
|
||||
* IN overhead_bits_per_order # of bits overhead for each increased LP order
|
||||
* (includes warmup sample size and quantized LP coefficient)
|
||||
* RETURN [1,max_order] best order
|
||||
*/
|
||||
unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned max_order, unsigned total_samples, unsigned overhead_bits_per_order);
|
||||
|
||||
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
|
||||
|
||||
#endif
|
||||
72
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/macros.h
vendored
Normal file
72
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/macros.h
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2012-2014 Xiph.org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__MACROS_H
|
||||
#define FLAC__PRIVATE__MACROS_H
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|
||||
|
||||
#define flac_max(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a > _b ? _a : _b; })
|
||||
|
||||
#define MIN_PASTE(A,B) A##B
|
||||
#define MIN_IMPL(A,B,L) ({ \
|
||||
__typeof__(A) MIN_PASTE(__a,L) = (A); \
|
||||
__typeof__(B) MIN_PASTE(__b,L) = (B); \
|
||||
MIN_PASTE(__a,L) < MIN_PASTE(__b,L) ? MIN_PASTE(__a,L) : MIN_PASTE(__b,L); \
|
||||
})
|
||||
|
||||
#define flac_min(A,B) MIN_IMPL(A,B,__COUNTER__)
|
||||
|
||||
/* Whatever other unix that has sys/param.h */
|
||||
#elif defined(HAVE_SYS_PARAM_H)
|
||||
#include <sys/param.h>
|
||||
#define flac_max(a,b) MAX(a,b)
|
||||
#define flac_min(a,b) MIN(a,b)
|
||||
|
||||
/* Windows VS has them in stdlib.h.. XXX:Untested */
|
||||
#elif defined(_MSC_VER)
|
||||
#include <stdlib.h>
|
||||
#define flac_max(a,b) __max(a,b)
|
||||
#define flac_min(a,b) __min(a,b)
|
||||
#endif
|
||||
|
||||
#ifndef flac_min
|
||||
#define flac_min(x,y) ((x) <= (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef flac_max
|
||||
#define flac_max(x,y) ((x) >= (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
50
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/md5.h
vendored
Normal file
50
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/md5.h
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef FLAC__PRIVATE__MD5_H
|
||||
#define FLAC__PRIVATE__MD5_H
|
||||
|
||||
/*
|
||||
* This is the header file for the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
*
|
||||
* Changed so as no longer to depend on Colin Plumb's `usual.h'
|
||||
* header definitions; now uses stuff from dpkg's config.h
|
||||
* - Ian Jackson <ijackson@nyx.cs.du.edu>.
|
||||
* Still in the public domain.
|
||||
*
|
||||
* Josh Coalson: made some changes to integrate with libFLAC.
|
||||
* Still in the public domain, with no warranty.
|
||||
*/
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
typedef union {
|
||||
FLAC__byte *p8;
|
||||
FLAC__int16 *p16;
|
||||
FLAC__int32 *p32;
|
||||
} FLAC__multibyte;
|
||||
|
||||
typedef struct {
|
||||
FLAC__uint32 in[16];
|
||||
FLAC__uint32 buf[4];
|
||||
FLAC__uint32 bytes[2];
|
||||
FLAC__multibyte internal_buf;
|
||||
size_t capacity;
|
||||
} FLAC__MD5Context;
|
||||
|
||||
void FLAC__MD5Init(FLAC__MD5Context *context);
|
||||
void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *context);
|
||||
|
||||
FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample);
|
||||
|
||||
#endif
|
||||
58
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/memory.h
vendored
Normal file
58
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/memory.h
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__MEMORY_H
|
||||
#define FLAC__PRIVATE__MEMORY_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> /* for size_t */
|
||||
|
||||
#include "private/float.h"
|
||||
#include "FLAC/ordinals.h" /* for FLAC__bool */
|
||||
|
||||
/* Returns the unaligned address returned by malloc.
|
||||
* Use free() on this address to deallocate.
|
||||
*/
|
||||
void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address);
|
||||
FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer);
|
||||
FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer);
|
||||
FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer);
|
||||
FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, unsigned **unaligned_pointer, unsigned **aligned_pointer);
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer);
|
||||
#endif
|
||||
void *safe_malloc_mul_2op_p(size_t size1, size_t size2);
|
||||
|
||||
#endif
|
||||
46
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/metadata.h
vendored
Normal file
46
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/metadata.h
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2002-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__METADATA_H
|
||||
#define FLAC__PRIVATE__METADATA_H
|
||||
|
||||
#include "FLAC/metadata.h"
|
||||
|
||||
/* WATCHOUT: all malloc()ed data in the block is free()ed; this may not
|
||||
* be a consistent state (e.g. PICTURE) or equivalent to the initial
|
||||
* state after FLAC__metadata_object_new()
|
||||
*/
|
||||
void FLAC__metadata_object_delete_data(FLAC__StreamMetadata *object);
|
||||
|
||||
void FLAC__metadata_object_cuesheet_track_delete_data(FLAC__StreamMetadata_CueSheet_Track *object);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/* libFLAC - Free Lossless Audio Codec
|
||||
* Copyright (C) 2002-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__OGG_DECODER_ASPECT_H
|
||||
#define FLAC__PRIVATE__OGG_DECODER_ASPECT_H
|
||||
|
||||
#include <ogg/ogg.h>
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
#include "FLAC/stream_decoder.h" /* for FLAC__StreamDecoderReadStatus */
|
||||
|
||||
typedef struct FLAC__OggDecoderAspect {
|
||||
/* these are storage for values that can be set through the API */
|
||||
FLAC__bool use_first_serial_number;
|
||||
long serial_number;
|
||||
|
||||
/* these are for internal state related to Ogg decoding */
|
||||
ogg_stream_state stream_state;
|
||||
ogg_sync_state sync_state;
|
||||
unsigned version_major, version_minor;
|
||||
FLAC__bool need_serial_number;
|
||||
FLAC__bool end_of_stream;
|
||||
FLAC__bool have_working_page; /* only if true will the following vars be valid */
|
||||
ogg_page working_page;
|
||||
FLAC__bool have_working_packet; /* only if true will the following vars be valid */
|
||||
ogg_packet working_packet; /* as we work through the packet we will move working_packet.packet forward and working_packet.bytes down */
|
||||
} FLAC__OggDecoderAspect;
|
||||
|
||||
void FLAC__ogg_decoder_aspect_set_serial_number(FLAC__OggDecoderAspect *aspect, long value);
|
||||
void FLAC__ogg_decoder_aspect_set_defaults(FLAC__OggDecoderAspect *aspect);
|
||||
FLAC__bool FLAC__ogg_decoder_aspect_init(FLAC__OggDecoderAspect *aspect);
|
||||
void FLAC__ogg_decoder_aspect_finish(FLAC__OggDecoderAspect *aspect);
|
||||
void FLAC__ogg_decoder_aspect_flush(FLAC__OggDecoderAspect *aspect);
|
||||
void FLAC__ogg_decoder_aspect_reset(FLAC__OggDecoderAspect *aspect);
|
||||
|
||||
typedef enum {
|
||||
FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK = 0,
|
||||
FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM,
|
||||
FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC,
|
||||
FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC,
|
||||
FLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION,
|
||||
FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT,
|
||||
FLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR,
|
||||
FLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR
|
||||
} FLAC__OggDecoderAspectReadStatus;
|
||||
|
||||
typedef FLAC__OggDecoderAspectReadStatus (*FLAC__OggDecoderAspectReadCallbackProxy)(const void *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
|
||||
|
||||
FLAC__OggDecoderAspectReadStatus FLAC__ogg_decoder_aspect_read_callback_wrapper(FLAC__OggDecoderAspect *aspect, FLAC__byte buffer[], size_t *bytes, FLAC__OggDecoderAspectReadCallbackProxy read_callback, const FLAC__StreamDecoder *decoder, void *client_data);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/* libFLAC - Free Lossless Audio Codec
|
||||
* Copyright (C) 2002-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__OGG_ENCODER_ASPECT_H
|
||||
#define FLAC__PRIVATE__OGG_ENCODER_ASPECT_H
|
||||
|
||||
#include <ogg/ogg.h>
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
#include "FLAC/stream_encoder.h" /* for FLAC__StreamEncoderWriteStatus */
|
||||
|
||||
typedef struct FLAC__OggEncoderAspect {
|
||||
/* these are storage for values that can be set through the API */
|
||||
long serial_number;
|
||||
unsigned num_metadata;
|
||||
|
||||
/* these are for internal state related to Ogg encoding */
|
||||
ogg_stream_state stream_state;
|
||||
ogg_page page;
|
||||
FLAC__bool seen_magic; /* true if we've seen the fLaC magic in the write callback yet */
|
||||
FLAC__bool is_first_packet;
|
||||
FLAC__uint64 samples_written;
|
||||
} FLAC__OggEncoderAspect;
|
||||
|
||||
void FLAC__ogg_encoder_aspect_set_serial_number(FLAC__OggEncoderAspect *aspect, long value);
|
||||
FLAC__bool FLAC__ogg_encoder_aspect_set_num_metadata(FLAC__OggEncoderAspect *aspect, unsigned value);
|
||||
void FLAC__ogg_encoder_aspect_set_defaults(FLAC__OggEncoderAspect *aspect);
|
||||
FLAC__bool FLAC__ogg_encoder_aspect_init(FLAC__OggEncoderAspect *aspect);
|
||||
void FLAC__ogg_encoder_aspect_finish(FLAC__OggEncoderAspect *aspect);
|
||||
|
||||
typedef FLAC__StreamEncoderWriteStatus (*FLAC__OggEncoderAspectWriteCallbackProxy)(const void *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data);
|
||||
|
||||
FLAC__StreamEncoderWriteStatus FLAC__ogg_encoder_aspect_write_callback_wrapper(FLAC__OggEncoderAspect *aspect, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, FLAC__bool is_last_block, FLAC__OggEncoderAspectWriteCallbackProxy write_callback, void *encoder, void *client_data);
|
||||
#endif
|
||||
44
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/ogg_helper.h
vendored
Normal file
44
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/ogg_helper.h
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/* libFLAC - Free Lossless Audio Codec
|
||||
* Copyright (C) 2004-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__OGG_HELPER_H
|
||||
#define FLAC__PRIVATE__OGG_HELPER_H
|
||||
|
||||
#include <ogg/ogg.h>
|
||||
#include "FLAC/stream_encoder.h" /* for FLAC__StreamEncoder */
|
||||
|
||||
void simple_ogg_page__init(ogg_page *page);
|
||||
void simple_ogg_page__clear(ogg_page *page);
|
||||
FLAC__bool simple_ogg_page__get_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderReadCallback read_callback, void *client_data);
|
||||
FLAC__bool simple_ogg_page__set_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderWriteCallback write_callback, void *client_data);
|
||||
|
||||
#endif
|
||||
64
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/ogg_mapping.h
vendored
Normal file
64
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/ogg_mapping.h
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/* libFLAC - Free Lossless Audio Codec
|
||||
* Copyright (C) 2004-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__OGG_MAPPING_H
|
||||
#define FLAC__PRIVATE__OGG_MAPPING_H
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
/** The length of the packet type field in bytes. */
|
||||
#define FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH (1u)
|
||||
|
||||
extern const unsigned FLAC__OGG_MAPPING_PACKET_TYPE_LEN; /* = 8 bits */
|
||||
|
||||
extern const FLAC__byte FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE; /* = 0x7f */
|
||||
|
||||
/** The length of the 'FLAC' magic in bytes. */
|
||||
#define FLAC__OGG_MAPPING_MAGIC_LENGTH (4u)
|
||||
|
||||
extern const FLAC__byte * const FLAC__OGG_MAPPING_MAGIC; /* = "FLAC" */
|
||||
|
||||
extern const unsigned FLAC__OGG_MAPPING_VERSION_MAJOR_LEN; /* = 8 bits */
|
||||
extern const unsigned FLAC__OGG_MAPPING_VERSION_MINOR_LEN; /* = 8 bits */
|
||||
|
||||
/** The length of the Ogg FLAC mapping major version number in bytes. */
|
||||
#define FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH (1u)
|
||||
|
||||
/** The length of the Ogg FLAC mapping minor version number in bytes. */
|
||||
#define FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH (1u)
|
||||
|
||||
extern const unsigned FLAC__OGG_MAPPING_NUM_HEADERS_LEN; /* = 16 bits */
|
||||
|
||||
/** The length of the #-of-header-packets number bytes. */
|
||||
#define FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH (2u)
|
||||
|
||||
#endif
|
||||
67
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/stream_encoder.h
vendored
Normal file
67
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/stream_encoder.h
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__STREAM_ENCODER_H
|
||||
#define FLAC__PRIVATE__STREAM_ENCODER_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is used to avoid overflow with unusual signals in 32-bit
|
||||
* accumulator in the *precompute_partition_info_sums_* functions.
|
||||
*/
|
||||
#define FLAC__MAX_EXTRA_RESIDUAL_BPS 4
|
||||
|
||||
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
|
||||
#include "private/cpu.h"
|
||||
#include "FLAC/format.h"
|
||||
|
||||
#ifdef FLAC__SSE2_SUPPORTED
|
||||
extern void FLAC__precompute_partition_info_sums_intrin_sse2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[],
|
||||
unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps);
|
||||
#endif
|
||||
|
||||
#ifdef FLAC__SSSE3_SUPPORTED
|
||||
extern void FLAC__precompute_partition_info_sums_intrin_ssse3(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[],
|
||||
unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps);
|
||||
#endif
|
||||
|
||||
#ifdef FLAC__AVX2_SUPPORTED
|
||||
extern void FLAC__precompute_partition_info_sums_intrin_avx2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[],
|
||||
unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__STREAM_ENCODER_FRAMING_H
|
||||
#define FLAC__PRIVATE__STREAM_ENCODER_FRAMING_H
|
||||
|
||||
#include "FLAC/format.h"
|
||||
#include "bitwriter.h"
|
||||
|
||||
FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw);
|
||||
FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWriter *bw);
|
||||
FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw);
|
||||
FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw);
|
||||
FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw);
|
||||
FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, unsigned samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw);
|
||||
|
||||
#endif
|
||||
74
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/window.h
vendored
Normal file
74
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/private/window.h
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2006-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__WINDOW_H
|
||||
#define FLAC__PRIVATE__WINDOW_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/float.h"
|
||||
#include "FLAC/format.h"
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
|
||||
/*
|
||||
* FLAC__window_*()
|
||||
* --------------------------------------------------------------------
|
||||
* Calculates window coefficients according to different apodization
|
||||
* functions.
|
||||
*
|
||||
* OUT window[0,L-1]
|
||||
* IN L (number of points in window)
|
||||
*/
|
||||
void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev); /* 0.0 < stddev <= 0.5 */
|
||||
void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p);
|
||||
void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end);
|
||||
void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end);
|
||||
void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L);
|
||||
|
||||
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
|
||||
|
||||
#endif
|
||||
39
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/protected/all.h
vendored
Normal file
39
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/protected/all.h
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PROTECTED__ALL_H
|
||||
#define FLAC__PROTECTED__ALL_H
|
||||
|
||||
#include "stream_decoder.h"
|
||||
#include "stream_encoder.h"
|
||||
|
||||
#endif
|
||||
60
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/protected/stream_decoder.h
vendored
Normal file
60
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/protected/stream_decoder.h
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PROTECTED__STREAM_DECODER_H
|
||||
#define FLAC__PROTECTED__STREAM_DECODER_H
|
||||
|
||||
#include "FLAC/stream_decoder.h"
|
||||
#if FLAC__HAS_OGG
|
||||
#include "private/ogg_decoder_aspect.h"
|
||||
#endif
|
||||
|
||||
typedef struct FLAC__StreamDecoderProtected {
|
||||
FLAC__StreamDecoderState state;
|
||||
FLAC__StreamDecoderInitStatus initstate;
|
||||
unsigned channels;
|
||||
FLAC__ChannelAssignment channel_assignment;
|
||||
unsigned bits_per_sample;
|
||||
unsigned sample_rate; /* in Hz */
|
||||
unsigned blocksize; /* in samples (per channel) */
|
||||
FLAC__bool md5_checking; /* if true, generate MD5 signature of decoded data and compare against signature in the STREAMINFO metadata block */
|
||||
#if FLAC__HAS_OGG
|
||||
FLAC__OggDecoderAspect ogg_decoder_aspect;
|
||||
#endif
|
||||
} FLAC__StreamDecoderProtected;
|
||||
|
||||
/*
|
||||
* return the number of input bytes consumed
|
||||
*/
|
||||
unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder);
|
||||
|
||||
#endif
|
||||
118
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/protected/stream_encoder.h
vendored
Normal file
118
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/protected/stream_encoder.h
vendored
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PROTECTED__STREAM_ENCODER_H
|
||||
#define FLAC__PROTECTED__STREAM_ENCODER_H
|
||||
|
||||
#include "FLAC/stream_encoder.h"
|
||||
#if FLAC__HAS_OGG
|
||||
#include "private/ogg_encoder_aspect.h"
|
||||
#endif
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
|
||||
#include "private/float.h"
|
||||
|
||||
#define FLAC__MAX_APODIZATION_FUNCTIONS 32
|
||||
|
||||
typedef enum {
|
||||
FLAC__APODIZATION_BARTLETT,
|
||||
FLAC__APODIZATION_BARTLETT_HANN,
|
||||
FLAC__APODIZATION_BLACKMAN,
|
||||
FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE,
|
||||
FLAC__APODIZATION_CONNES,
|
||||
FLAC__APODIZATION_FLATTOP,
|
||||
FLAC__APODIZATION_GAUSS,
|
||||
FLAC__APODIZATION_HAMMING,
|
||||
FLAC__APODIZATION_HANN,
|
||||
FLAC__APODIZATION_KAISER_BESSEL,
|
||||
FLAC__APODIZATION_NUTTALL,
|
||||
FLAC__APODIZATION_RECTANGLE,
|
||||
FLAC__APODIZATION_TRIANGLE,
|
||||
FLAC__APODIZATION_TUKEY,
|
||||
FLAC__APODIZATION_PARTIAL_TUKEY,
|
||||
FLAC__APODIZATION_PUNCHOUT_TUKEY,
|
||||
FLAC__APODIZATION_WELCH
|
||||
} FLAC__ApodizationFunction;
|
||||
|
||||
typedef struct {
|
||||
FLAC__ApodizationFunction type;
|
||||
union {
|
||||
struct {
|
||||
FLAC__real stddev;
|
||||
} gauss;
|
||||
struct {
|
||||
FLAC__real p;
|
||||
} tukey;
|
||||
struct {
|
||||
FLAC__real p;
|
||||
FLAC__real start;
|
||||
FLAC__real end;
|
||||
} multiple_tukey;
|
||||
} parameters;
|
||||
} FLAC__ApodizationSpecification;
|
||||
|
||||
#endif // #ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
|
||||
typedef struct FLAC__StreamEncoderProtected {
|
||||
FLAC__StreamEncoderState state;
|
||||
FLAC__bool verify;
|
||||
FLAC__bool streamable_subset;
|
||||
FLAC__bool do_md5;
|
||||
FLAC__bool do_mid_side_stereo;
|
||||
FLAC__bool loose_mid_side_stereo;
|
||||
unsigned channels;
|
||||
unsigned bits_per_sample;
|
||||
unsigned sample_rate;
|
||||
unsigned blocksize;
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
unsigned num_apodizations;
|
||||
FLAC__ApodizationSpecification apodizations[FLAC__MAX_APODIZATION_FUNCTIONS];
|
||||
#endif
|
||||
unsigned max_lpc_order;
|
||||
unsigned qlp_coeff_precision;
|
||||
FLAC__bool do_qlp_coeff_prec_search;
|
||||
FLAC__bool do_exhaustive_model_search;
|
||||
FLAC__bool do_escape_coding;
|
||||
unsigned min_residual_partition_order;
|
||||
unsigned max_residual_partition_order;
|
||||
unsigned rice_parameter_search_dist;
|
||||
FLAC__uint64 total_samples_estimate;
|
||||
FLAC__StreamMetadata **metadata;
|
||||
unsigned num_metadata_blocks;
|
||||
FLAC__uint64 streaminfo_offset, seektable_offset, audio_offset;
|
||||
#if FLAC__HAS_OGG
|
||||
FLAC__OggEncoderAspect ogg_encoder_aspect;
|
||||
#endif
|
||||
} FLAC__StreamEncoderProtected;
|
||||
|
||||
#endif
|
||||
209
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/alloc.h
vendored
Normal file
209
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/alloc.h
vendored
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
/* alloc - Convenience routines for safely allocating memory
|
||||
* Copyright (C) 2007-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__SHARE__ALLOC_H
|
||||
#define FLAC__SHARE__ALLOC_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early
|
||||
* before #including this file, otherwise SIZE_MAX might not be defined
|
||||
*/
|
||||
|
||||
#include <limits.h> /* for SIZE_MAX */
|
||||
#if HAVE_STDINT_H
|
||||
#include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */
|
||||
#endif
|
||||
#include <stdlib.h> /* for size_t, malloc(), etc */
|
||||
#include "share/compat.h"
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# ifndef SIZE_T_MAX
|
||||
# ifdef _MSC_VER
|
||||
# ifdef _WIN64
|
||||
# define SIZE_T_MAX 0xffffffffffffffffui64
|
||||
# else
|
||||
# define SIZE_T_MAX 0xffffffff
|
||||
# endif
|
||||
# else
|
||||
# error
|
||||
# endif
|
||||
# endif
|
||||
# define SIZE_MAX SIZE_T_MAX
|
||||
#endif
|
||||
|
||||
/* avoid malloc()ing 0 bytes, see:
|
||||
* https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003
|
||||
*/
|
||||
static inline void *safe_malloc_(size_t size)
|
||||
{
|
||||
/* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
if(!size)
|
||||
size++;
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static inline void *safe_calloc_(size_t nmemb, size_t size)
|
||||
{
|
||||
if(!nmemb || !size)
|
||||
return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
return calloc(nmemb, size);
|
||||
}
|
||||
|
||||
/*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */
|
||||
|
||||
static inline void *safe_malloc_add_2op_(size_t size1, size_t size2)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
return safe_malloc_(size2);
|
||||
}
|
||||
|
||||
static inline void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
size3 += size2;
|
||||
if(size3 < size2)
|
||||
return 0;
|
||||
return safe_malloc_(size3);
|
||||
}
|
||||
|
||||
static inline void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
size3 += size2;
|
||||
if(size3 < size2)
|
||||
return 0;
|
||||
size4 += size3;
|
||||
if(size4 < size3)
|
||||
return 0;
|
||||
return safe_malloc_(size4);
|
||||
}
|
||||
|
||||
void *safe_malloc_mul_2op_(size_t size1, size_t size2) ;
|
||||
|
||||
static inline void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
if(!size1 || !size2 || !size3)
|
||||
return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
size1 *= size2;
|
||||
if(size1 > SIZE_MAX / size3)
|
||||
return 0;
|
||||
return malloc(size1*size3);
|
||||
}
|
||||
|
||||
/* size1*size2 + size3 */
|
||||
static inline void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
if(!size1 || !size2)
|
||||
return safe_malloc_(size3);
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
return safe_malloc_add_2op_(size1*size2, size3);
|
||||
}
|
||||
|
||||
/* size1 * (size2 + size3) */
|
||||
static inline void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
if(!size1 || (!size2 && !size3))
|
||||
return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
size2 += size3;
|
||||
if(size2 < size3)
|
||||
return 0;
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
return malloc(size1*size2);
|
||||
}
|
||||
|
||||
static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
return realloc(ptr, size2);
|
||||
}
|
||||
|
||||
static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
size3 += size2;
|
||||
if(size3 < size2)
|
||||
return 0;
|
||||
return realloc(ptr, size3);
|
||||
}
|
||||
|
||||
static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
size3 += size2;
|
||||
if(size3 < size2)
|
||||
return 0;
|
||||
size4 += size3;
|
||||
if(size4 < size3)
|
||||
return 0;
|
||||
return realloc(ptr, size4);
|
||||
}
|
||||
|
||||
static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2)
|
||||
{
|
||||
if(!size1 || !size2)
|
||||
return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
return realloc(ptr, size1*size2);
|
||||
}
|
||||
|
||||
/* size1 * (size2 + size3) */
|
||||
static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
if(!size1 || (!size2 && !size3))
|
||||
return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
|
||||
size2 += size3;
|
||||
if(size2 < size3)
|
||||
return 0;
|
||||
return safe_realloc_mul_2op_(ptr, size1, size2);
|
||||
}
|
||||
|
||||
#endif
|
||||
201
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/compat.h
vendored
Normal file
201
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/compat.h
vendored
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2012-2014 Xiph.org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* This is the prefered location of all CPP hackery to make $random_compiler
|
||||
* work like something approaching a C99 (or maybe more accurately GNU99)
|
||||
* compiler.
|
||||
*
|
||||
* It is assumed that this header will be included after "config.h".
|
||||
*/
|
||||
|
||||
#ifndef FLAC__SHARE__COMPAT_H
|
||||
#define FLAC__SHARE__COMPAT_H
|
||||
|
||||
#if defined _WIN32 && !defined __CYGWIN__
|
||||
/* where MSVC puts unlink() */
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
|
||||
#include <sys/types.h> /* for off_t */
|
||||
#define FLAC__off_t __int64 /* use this instead of off_t to fix the 2 GB limit */
|
||||
#if !defined __MINGW32__
|
||||
#define fseeko _fseeki64
|
||||
#define ftello _ftelli64
|
||||
#else /* MinGW */
|
||||
#if !defined(HAVE_FSEEKO)
|
||||
#define fseeko fseeko64
|
||||
#define ftello ftello64
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define FLAC__off_t off_t
|
||||
#endif
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define strtoll _strtoi64
|
||||
#define strtoull _strtoui64
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#if defined __INTEL_COMPILER || (defined _MSC_VER && defined _WIN64)
|
||||
/* MSVS generates VERY slow 32-bit code with __restrict */
|
||||
#define flac_restrict __restrict
|
||||
#elif defined __GNUC__
|
||||
#define flac_restrict __restrict__
|
||||
#else
|
||||
#define flac_restrict
|
||||
#endif
|
||||
|
||||
#define FLAC__U64L(x) x##ULL
|
||||
|
||||
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
|
||||
#define FLAC__STRCASECMP stricmp
|
||||
#define FLAC__STRNCASECMP strnicmp
|
||||
#else
|
||||
#define FLAC__STRCASECMP strcasecmp
|
||||
#define FLAC__STRNCASECMP strncasecmp
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ || defined __EMX__
|
||||
#include <io.h> /* for _setmode(), chmod() */
|
||||
#include <fcntl.h> /* for _O_BINARY */
|
||||
#else
|
||||
#include <unistd.h> /* for chown(), unlink() */
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
|
||||
#if defined __BORLANDC__
|
||||
#include <utime.h> /* for utime() */
|
||||
#else
|
||||
#include <sys/utime.h> /* for utime() */
|
||||
#endif
|
||||
#else
|
||||
#include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */
|
||||
#include <utime.h> /* for utime() */
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER
|
||||
# if _MSC_VER >= 1600
|
||||
/* Visual Studio 2010 has decent C99 support */
|
||||
# include <stdint.h>
|
||||
# define PRIu64 "llu"
|
||||
# define PRId64 "lld"
|
||||
# define PRIx64 "llx"
|
||||
# else
|
||||
# include <limits.h>
|
||||
# ifndef UINT32_MAX
|
||||
# define UINT32_MAX _UI32_MAX
|
||||
# endif
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int8 int8_t;
|
||||
# define PRIu64 "I64u"
|
||||
# define PRId64 "I64d"
|
||||
# define PRIx64 "I64x"
|
||||
# endif
|
||||
#endif /* defined _MSC_VER */
|
||||
|
||||
#ifdef _WIN32
|
||||
/* All char* strings are in UTF-8 format. Added to support Unicode files on Windows */
|
||||
#include "share/win_utf8_io.h"
|
||||
|
||||
#define flac_printf printf_utf8
|
||||
#define flac_fprintf fprintf_utf8
|
||||
#define flac_vfprintf vfprintf_utf8
|
||||
#define flac_fopen fopen_utf8
|
||||
#define flac_chmod chmod_utf8
|
||||
#define flac_utime utime_utf8
|
||||
#define flac_unlink unlink_utf8
|
||||
#define flac_rename rename_utf8
|
||||
#define flac_stat _stat64_utf8
|
||||
|
||||
#else
|
||||
|
||||
#define flac_printf printf
|
||||
#define flac_fprintf fprintf
|
||||
#define flac_vfprintf vfprintf
|
||||
#define flac_fopen fopen
|
||||
#define flac_chmod chmod
|
||||
#define flac_utime utime
|
||||
#define flac_unlink unlink
|
||||
#define flac_rename rename
|
||||
#define flac_stat stat
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define flac_stat_s __stat64 /* stat struct */
|
||||
#define flac_fstat _fstat64
|
||||
#else
|
||||
#define flac_stat_s stat /* stat struct */
|
||||
#define flac_fstat fstat
|
||||
#endif
|
||||
|
||||
#ifndef M_LN2
|
||||
#define M_LN2 0.69314718055994530942
|
||||
#endif
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
/* FLAC needs to compile and work correctly on systems with a normal ISO C99
|
||||
* snprintf as well as Microsoft Visual Studio which has an non-standards
|
||||
* conformant snprint_s function.
|
||||
*
|
||||
* This function wraps the MS version to behave more like the the ISO version.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int flac_snprintf(char *str, size_t size, const char *fmt, ...);
|
||||
int flac_vsnprintf(char *str, size_t size, const char *fmt, va_list va);
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* FLAC__SHARE__COMPAT_H */
|
||||
78
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/endswap.h
vendored
Normal file
78
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/endswap.h
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2012-2014 Xiph.org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* It is assumed that this header will be included after "config.h". */
|
||||
|
||||
#if HAVE_BSWAP32 /* GCC and Clang */
|
||||
|
||||
/* GCC prior to 4.8 didn't provide bswap16 on x86_64 */
|
||||
#if ! HAVE_BSWAP16
|
||||
static inline unsigned short __builtin_bswap16(unsigned short a)
|
||||
{
|
||||
return (a<<8)|(a>>8);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ENDSWAP_16(x) (__builtin_bswap16 (x))
|
||||
#define ENDSWAP_32(x) (__builtin_bswap32 (x))
|
||||
|
||||
#elif defined _MSC_VER /* Windows. Apparently in <stdlib.h>. */
|
||||
|
||||
#define ENDSWAP_16(x) (_byteswap_ushort (x))
|
||||
#define ENDSWAP_32(x) (_byteswap_ulong (x))
|
||||
|
||||
#elif defined HAVE_BYTESWAP_H /* Linux */
|
||||
|
||||
#include <byteswap.h>
|
||||
|
||||
#define ENDSWAP_16(x) (bswap_16 (x))
|
||||
#define ENDSWAP_32(x) (bswap_32 (x))
|
||||
|
||||
#else
|
||||
|
||||
#define ENDSWAP_16(x) ((((x) >> 8) & 0xFF) | (((x) & 0xFF) << 8))
|
||||
#define ENDSWAP_32(x) ((((x) >> 24) & 0xFF) | (((x) >> 8) & 0xFF00) | (((x) & 0xFF00) << 8) | (((x) & 0xFF) << 24))
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Host to little-endian byte swapping. */
|
||||
#if CPU_IS_BIG_ENDIAN
|
||||
|
||||
#define H2LE_16(x) ENDSWAP_16 (x)
|
||||
#define H2LE_32(x) ENDSWAP_32 (x)
|
||||
|
||||
#else
|
||||
|
||||
#define H2LE_16(x) (x)
|
||||
#define H2LE_32(x) (x)
|
||||
|
||||
#endif
|
||||
184
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/getopt.h
vendored
Normal file
184
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/getopt.h
vendored
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
NOTE:
|
||||
I cannot get the vanilla getopt code to work (i.e. compile only what
|
||||
is needed and not duplicate symbols found in the standard library)
|
||||
on all the platforms that FLAC supports. In particular the gating
|
||||
of code with the ELIDE_CODE #define is not accurate enough on systems
|
||||
that are POSIX but not glibc. If someone has a patch that works on
|
||||
GNU/Linux, Darwin, AND Solaris please submit it on the project page:
|
||||
https://sourceforge.net/p/flac/patches/
|
||||
|
||||
In the meantime I have munged the global symbols and removed gates
|
||||
around code, while at the same time trying to touch the original as
|
||||
little as possible.
|
||||
*/
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef SHARE__GETOPT_H
|
||||
#define SHARE__GETOPT_H
|
||||
|
||||
/*[JEC] was:#ifndef __need_getopt*/
|
||||
/*[JEC] was:# define _GETOPT_H 1*/
|
||||
/*[JEC] was:#endif*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `share__getopt' to the caller.
|
||||
When `share__getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *share__optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `share__getopt'.
|
||||
|
||||
On entry to `share__getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `share__getopt' returns -1, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `share__optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int share__optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `share__getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int share__opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int share__optopt;
|
||||
|
||||
/*[JEC] was:#ifndef __need_getopt */
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to share__getopt_long or share__getopt_long_only is a vector
|
||||
of `struct share__option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
share__no_argument (or 0) if the option does not take an argument,
|
||||
share__required_argument (or 1) if the option requires an argument,
|
||||
share__optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `share__optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `share__getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct share__option
|
||||
{
|
||||
# if defined __STDC__ && __STDC__
|
||||
const char *name;
|
||||
# else
|
||||
char *name;
|
||||
# endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct share__option'. */
|
||||
|
||||
# define share__no_argument 0
|
||||
# define share__required_argument 1
|
||||
# define share__optional_argument 2
|
||||
/*[JEC] was:#endif*/ /* need getopt */
|
||||
|
||||
|
||||
/* Get definitions and prototypes for functions to process the
|
||||
arguments in ARGV (ARGC of them, minus the program name) for
|
||||
options given in OPTS.
|
||||
|
||||
Return the option character from OPTS just read. Return -1 when
|
||||
there are no more options. For unrecognized options, or options
|
||||
missing arguments, `share__optopt' is set to the option letter, and '?' is
|
||||
returned.
|
||||
|
||||
The OPTS string is a list of characters which are recognized option
|
||||
letters, optionally followed by colons, specifying that that letter
|
||||
takes an argument, to be placed in `share__optarg'.
|
||||
|
||||
If a letter in OPTS is followed by two colons, its argument is
|
||||
optional. This behavior is specific to the GNU `share__getopt'.
|
||||
|
||||
The argument `--' causes premature termination of argument
|
||||
scanning, explicitly telling `share__getopt' that there are no more
|
||||
options.
|
||||
|
||||
If OPTS begins with `--', then non-option arguments are treated as
|
||||
arguments to the option '\0'. This behavior is specific to the GNU
|
||||
`share__getopt'. */
|
||||
|
||||
/*[JEC] was:#if defined __STDC__ && __STDC__*/
|
||||
/*[JEC] was:# ifdef __GNU_LIBRARY__*/
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int share__getopt (int argc, char *const *argv, const char *shortopts);
|
||||
/*[JEC] was:# else*/ /* not __GNU_LIBRARY__ */
|
||||
/*[JEC] was:extern int getopt ();*/
|
||||
/*[JEC] was:# endif*/ /* __GNU_LIBRARY__ */
|
||||
|
||||
/*[JEC] was:# ifndef __need_getopt*/
|
||||
extern int share__getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||
const struct share__option *longopts, int *longind);
|
||||
extern int share__getopt_long_only (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct share__option *longopts, int *longind);
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int share___getopt_internal (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct share__option *longopts, int *longind,
|
||||
int long_only);
|
||||
/*[JEC] was:# endif*/
|
||||
/*[JEC] was:#else*/ /* not __STDC__ */
|
||||
/*[JEC] was:extern int getopt ();*/
|
||||
/*[JEC] was:# ifndef __need_getopt*/
|
||||
/*[JEC] was:extern int getopt_long ();*/
|
||||
/*[JEC] was:extern int getopt_long_only ();*/
|
||||
|
||||
/*[JEC] was:extern int _getopt_internal ();*/
|
||||
/*[JEC] was:# endif*/
|
||||
/*[JEC] was:#endif*/ /* __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make sure we later can get all the definitions and declarations. */
|
||||
/*[JEC] was:#undef __need_getopt*/
|
||||
|
||||
#endif /* getopt.h */
|
||||
41
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/macros.h
vendored
Normal file
41
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/macros.h
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2013-2014 Xiph.org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* FLAC_CHECK_RETURN : Check the return value of of the provided function and
|
||||
* print and error message if it fails (ie returns a value < 0).
|
||||
*/
|
||||
|
||||
#define FLAC_CHECK_RETURN(x) \
|
||||
{ if ((x) < 0) \
|
||||
printf ("%s : %s\n", #x, strerror (errno)) ; \
|
||||
}
|
||||
45
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/private.h
vendored
Normal file
45
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/private.h
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2013-2014 Xiph.org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__SHARE__PRIVATE_H
|
||||
#define FLAC__SHARE__PRIVATE_H
|
||||
|
||||
/*
|
||||
* Unpublished debug routines from libFLAC> This should not be used from any
|
||||
* client code other than code shipped with the FLAC sources.
|
||||
*/
|
||||
FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
|
||||
FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
|
||||
FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
|
||||
FLAC_API FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value);
|
||||
FLAC_API FLAC__bool FLAC__stream_encoder_get_do_md5(const FLAC__StreamEncoder *encoder);
|
||||
|
||||
#endif /* FLAC__SHARE__PRIVATE_H */
|
||||
69
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/safe_str.h
vendored
Normal file
69
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/safe_str.h
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2013-2014 Xiph.org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Safe string handling functions to replace things like strcpy, strncpy,
|
||||
* strcat, strncat etc.
|
||||
* All of these functions guarantee a correctly NUL terminated string but
|
||||
* the string may be truncated if the destination buffer was too short.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__SHARE_SAFE_STR_H
|
||||
#define FLAC__SHARE_SAFE_STR_H
|
||||
|
||||
static inline char *
|
||||
safe_strncat(char *dest, const char *src, size_t dest_size)
|
||||
{
|
||||
char * ret;
|
||||
|
||||
if (dest_size < 1)
|
||||
return dest;
|
||||
|
||||
ret = strncat(dest, src, dest_size - strlen (dest));
|
||||
dest [dest_size - 1] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
safe_strncpy(char *dest, const char *src, size_t dest_size)
|
||||
{
|
||||
char * ret;
|
||||
|
||||
if (dest_size < 1)
|
||||
return dest;
|
||||
|
||||
ret = strncpy(dest, src, dest_size);
|
||||
dest [dest_size - 1] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* FLAC__SHARE_SAFE_STR_H */
|
||||
25
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/utf8.h
vendored
Normal file
25
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/utf8.h
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef SHARE__UTF8_H
|
||||
#define SHARE__UTF8_H
|
||||
|
||||
/*
|
||||
* Convert a string between UTF-8 and the locale's charset.
|
||||
* Invalid bytes are replaced by '#', and characters that are
|
||||
* not available in the target encoding are replaced by '?'.
|
||||
*
|
||||
* If the locale's charset is not set explicitly then it is
|
||||
* obtained using nl_langinfo(CODESET), where available, the
|
||||
* environment variable CHARSET, or assumed to be US-ASCII.
|
||||
*
|
||||
* Return value of conversion functions:
|
||||
*
|
||||
* -1 : memory allocation failed
|
||||
* 0 : data was converted exactly
|
||||
* 1 : valid data was converted approximately (using '?')
|
||||
* 2 : input was invalid (but still converted, using '#')
|
||||
* 3 : unknown encoding (but still converted, using '?')
|
||||
*/
|
||||
|
||||
int utf8_encode(const char *from, char **to);
|
||||
int utf8_decode(const char *from, char **to);
|
||||
|
||||
#endif
|
||||
69
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/win_utf8_io.h
vendored
Normal file
69
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/include/share/win_utf8_io.h
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2013-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef flac__win_utf8_io_h
|
||||
#define flac__win_utf8_io_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdarg.h>
|
||||
#include <windows.h>
|
||||
|
||||
int get_utf8_argv(int *argc, char ***argv);
|
||||
|
||||
int printf_utf8(const char *format, ...);
|
||||
int fprintf_utf8(FILE *stream, const char *format, ...);
|
||||
int vfprintf_utf8(FILE *stream, const char *format, va_list argptr);
|
||||
|
||||
FILE *fopen_utf8(const char *filename, const char *mode);
|
||||
int stat_utf8(const char *path, struct stat *buffer);
|
||||
int _stat64_utf8(const char *path, struct __stat64 *buffer);
|
||||
int chmod_utf8(const char *filename, int pmode);
|
||||
int utime_utf8(const char *filename, struct utimbuf *times);
|
||||
int unlink_utf8(const char *filename);
|
||||
int rename_utf8(const char *oldname, const char *newname);
|
||||
size_t strlen_utf8(const char *str);
|
||||
int win_get_console_width(void);
|
||||
int print_console(FILE *stream, const wchar_t *text, size_t len);
|
||||
HANDLE WINAPI CreateFile_utf8(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
1120
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/lpc_intrin_avx2.c
vendored
Normal file
1120
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/lpc_intrin_avx2.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
451
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/lpc_intrin_sse.c
vendored
Normal file
451
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/lpc_intrin_sse.c
vendored
Normal file
|
|
@ -0,0 +1,451 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
#ifndef FLAC__NO_ASM
|
||||
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
|
||||
#include "private/lpc.h"
|
||||
#ifdef FLAC__SSE_SUPPORTED
|
||||
|
||||
#include "FLAC/assert.h"
|
||||
#include "FLAC/format.h"
|
||||
|
||||
#include <xmmintrin.h> /* SSE */
|
||||
|
||||
#if 1
|
||||
/* Faster on current Intel (starting from Core i aka Nehalem) and all AMD CPUs */
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
int i;
|
||||
int limit = data_len - 4;
|
||||
__m128 sum0;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag <= 4);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
|
||||
sum0 = _mm_setzero_ps();
|
||||
|
||||
for(i = 0; i <= limit; i++) {
|
||||
__m128 d, d0;
|
||||
d0 = _mm_loadu_ps(data+i);
|
||||
d = d0; d = _mm_shuffle_ps(d, d, 0);
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d));
|
||||
}
|
||||
|
||||
{
|
||||
__m128 d0 = _mm_setzero_ps();
|
||||
limit++; if(limit < 0) limit = 0;
|
||||
|
||||
for(i = data_len-1; i >= limit; i--) {
|
||||
__m128 d;
|
||||
d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0);
|
||||
d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3));
|
||||
d0 = _mm_move_ss(d0, d);
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0));
|
||||
}
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, sum0);
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
int i;
|
||||
int limit = data_len - 8;
|
||||
__m128 sum0, sum1;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag <= 8);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
|
||||
sum0 = _mm_setzero_ps();
|
||||
sum1 = _mm_setzero_ps();
|
||||
|
||||
for(i = 0; i <= limit; i++) {
|
||||
__m128 d, d0, d1;
|
||||
d0 = _mm_loadu_ps(data+i);
|
||||
d1 = _mm_loadu_ps(data+i+4);
|
||||
d = d0; d = _mm_shuffle_ps(d, d, 0);
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d));
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d));
|
||||
}
|
||||
|
||||
{
|
||||
__m128 d0 = _mm_setzero_ps();
|
||||
__m128 d1 = _mm_setzero_ps();
|
||||
limit++; if(limit < 0) limit = 0;
|
||||
|
||||
for(i = data_len-1; i >= limit; i--) {
|
||||
__m128 d;
|
||||
d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0);
|
||||
d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3));
|
||||
d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3));
|
||||
d1 = _mm_move_ss(d1, d0);
|
||||
d0 = _mm_move_ss(d0, d);
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1));
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0));
|
||||
}
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, sum0);
|
||||
_mm_storeu_ps(autoc+4, sum1);
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
int i;
|
||||
int limit = data_len - 12;
|
||||
__m128 sum0, sum1, sum2;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag <= 12);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
|
||||
sum0 = _mm_setzero_ps();
|
||||
sum1 = _mm_setzero_ps();
|
||||
sum2 = _mm_setzero_ps();
|
||||
|
||||
for(i = 0; i <= limit; i++) {
|
||||
__m128 d, d0, d1, d2;
|
||||
d0 = _mm_loadu_ps(data+i);
|
||||
d1 = _mm_loadu_ps(data+i+4);
|
||||
d2 = _mm_loadu_ps(data+i+8);
|
||||
d = d0; d = _mm_shuffle_ps(d, d, 0);
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d));
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d));
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(d2, d));
|
||||
}
|
||||
|
||||
{
|
||||
__m128 d0 = _mm_setzero_ps();
|
||||
__m128 d1 = _mm_setzero_ps();
|
||||
__m128 d2 = _mm_setzero_ps();
|
||||
limit++; if(limit < 0) limit = 0;
|
||||
|
||||
for(i = data_len-1; i >= limit; i--) {
|
||||
__m128 d;
|
||||
d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0);
|
||||
d2 = _mm_shuffle_ps(d2, d2, _MM_SHUFFLE(2,1,0,3));
|
||||
d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3));
|
||||
d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3));
|
||||
d2 = _mm_move_ss(d2, d1);
|
||||
d1 = _mm_move_ss(d1, d0);
|
||||
d0 = _mm_move_ss(d0, d);
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(d, d2));
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1));
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0));
|
||||
}
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, sum0);
|
||||
_mm_storeu_ps(autoc+4, sum1);
|
||||
_mm_storeu_ps(autoc+8, sum2);
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
int i;
|
||||
int limit = data_len - 16;
|
||||
__m128 sum0, sum1, sum2, sum3;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag <= 16);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
|
||||
sum0 = _mm_setzero_ps();
|
||||
sum1 = _mm_setzero_ps();
|
||||
sum2 = _mm_setzero_ps();
|
||||
sum3 = _mm_setzero_ps();
|
||||
|
||||
for(i = 0; i <= limit; i++) {
|
||||
__m128 d, d0, d1, d2, d3;
|
||||
d0 = _mm_loadu_ps(data+i);
|
||||
d1 = _mm_loadu_ps(data+i+4);
|
||||
d2 = _mm_loadu_ps(data+i+8);
|
||||
d3 = _mm_loadu_ps(data+i+12);
|
||||
d = d0; d = _mm_shuffle_ps(d, d, 0);
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d));
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d));
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(d2, d));
|
||||
sum3 = _mm_add_ps(sum3, _mm_mul_ps(d3, d));
|
||||
}
|
||||
|
||||
{
|
||||
__m128 d0 = _mm_setzero_ps();
|
||||
__m128 d1 = _mm_setzero_ps();
|
||||
__m128 d2 = _mm_setzero_ps();
|
||||
__m128 d3 = _mm_setzero_ps();
|
||||
limit++; if(limit < 0) limit = 0;
|
||||
|
||||
for(i = data_len-1; i >= limit; i--) {
|
||||
__m128 d;
|
||||
d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0);
|
||||
d3 = _mm_shuffle_ps(d3, d3, _MM_SHUFFLE(2,1,0,3));
|
||||
d2 = _mm_shuffle_ps(d2, d2, _MM_SHUFFLE(2,1,0,3));
|
||||
d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3));
|
||||
d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3));
|
||||
d3 = _mm_move_ss(d3, d2);
|
||||
d2 = _mm_move_ss(d2, d1);
|
||||
d1 = _mm_move_ss(d1, d0);
|
||||
d0 = _mm_move_ss(d0, d);
|
||||
sum3 = _mm_add_ps(sum3, _mm_mul_ps(d, d3));
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(d, d2));
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1));
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0));
|
||||
}
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, sum0);
|
||||
_mm_storeu_ps(autoc+4, sum1);
|
||||
_mm_storeu_ps(autoc+8, sum2);
|
||||
_mm_storeu_ps(autoc+12,sum3);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Faster on older Intel CPUs (up to Core 2) */
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
__m128 xmm0, xmm2, xmm5;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag > 0);
|
||||
FLAC__ASSERT(lag <= 4);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
FLAC__ASSERT(data_len > 0);
|
||||
|
||||
xmm5 = _mm_setzero_ps();
|
||||
|
||||
xmm0 = _mm_load_ss(data++);
|
||||
xmm2 = xmm0;
|
||||
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0);
|
||||
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm2);
|
||||
xmm5 = _mm_add_ps(xmm5, xmm0);
|
||||
|
||||
data_len--;
|
||||
|
||||
while(data_len)
|
||||
{
|
||||
xmm0 = _mm_load1_ps(data++);
|
||||
|
||||
xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm2 = _mm_move_ss(xmm2, xmm0);
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm2);
|
||||
xmm5 = _mm_add_ps(xmm5, xmm0);
|
||||
|
||||
data_len--;
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, xmm5);
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
__m128 xmm0, xmm1, xmm2, xmm3, xmm5, xmm6;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag > 0);
|
||||
FLAC__ASSERT(lag <= 8);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
FLAC__ASSERT(data_len > 0);
|
||||
|
||||
xmm5 = _mm_setzero_ps();
|
||||
xmm6 = _mm_setzero_ps();
|
||||
|
||||
xmm0 = _mm_load_ss(data++);
|
||||
xmm2 = xmm0;
|
||||
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0);
|
||||
xmm3 = _mm_setzero_ps();
|
||||
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm2);
|
||||
xmm5 = _mm_add_ps(xmm5, xmm0);
|
||||
|
||||
data_len--;
|
||||
|
||||
while(data_len)
|
||||
{
|
||||
xmm0 = _mm_load1_ps(data++);
|
||||
|
||||
xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm3 = _mm_move_ss(xmm3, xmm2);
|
||||
xmm2 = _mm_move_ss(xmm2, xmm0);
|
||||
|
||||
xmm1 = xmm0;
|
||||
xmm1 = _mm_mul_ps(xmm1, xmm3);
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm2);
|
||||
xmm6 = _mm_add_ps(xmm6, xmm1);
|
||||
xmm5 = _mm_add_ps(xmm5, xmm0);
|
||||
|
||||
data_len--;
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, xmm5);
|
||||
_mm_storeu_ps(autoc+4, xmm6);
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
__m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag > 0);
|
||||
FLAC__ASSERT(lag <= 12);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
FLAC__ASSERT(data_len > 0);
|
||||
|
||||
xmm5 = _mm_setzero_ps();
|
||||
xmm6 = _mm_setzero_ps();
|
||||
xmm7 = _mm_setzero_ps();
|
||||
|
||||
xmm0 = _mm_load_ss(data++);
|
||||
xmm2 = xmm0;
|
||||
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0);
|
||||
xmm3 = _mm_setzero_ps();
|
||||
xmm4 = _mm_setzero_ps();
|
||||
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm2);
|
||||
xmm5 = _mm_add_ps(xmm5, xmm0);
|
||||
|
||||
data_len--;
|
||||
|
||||
while(data_len)
|
||||
{
|
||||
xmm0 = _mm_load1_ps(data++);
|
||||
|
||||
xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm4 = _mm_shuffle_ps(xmm4, xmm4, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm4 = _mm_move_ss(xmm4, xmm3);
|
||||
xmm3 = _mm_move_ss(xmm3, xmm2);
|
||||
xmm2 = _mm_move_ss(xmm2, xmm0);
|
||||
|
||||
xmm1 = xmm0;
|
||||
xmm1 = _mm_mul_ps(xmm1, xmm2);
|
||||
xmm5 = _mm_add_ps(xmm5, xmm1);
|
||||
xmm1 = xmm0;
|
||||
xmm1 = _mm_mul_ps(xmm1, xmm3);
|
||||
xmm6 = _mm_add_ps(xmm6, xmm1);
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm4);
|
||||
xmm7 = _mm_add_ps(xmm7, xmm0);
|
||||
|
||||
data_len--;
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, xmm5);
|
||||
_mm_storeu_ps(autoc+4, xmm6);
|
||||
_mm_storeu_ps(autoc+8, xmm7);
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
__m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag > 0);
|
||||
FLAC__ASSERT(lag <= 16);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
FLAC__ASSERT(data_len > 0);
|
||||
|
||||
xmm6 = _mm_setzero_ps();
|
||||
xmm7 = _mm_setzero_ps();
|
||||
xmm8 = _mm_setzero_ps();
|
||||
xmm9 = _mm_setzero_ps();
|
||||
|
||||
xmm0 = _mm_load_ss(data++);
|
||||
xmm2 = xmm0;
|
||||
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0);
|
||||
xmm3 = _mm_setzero_ps();
|
||||
xmm4 = _mm_setzero_ps();
|
||||
xmm5 = _mm_setzero_ps();
|
||||
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm2);
|
||||
xmm6 = _mm_add_ps(xmm6, xmm0);
|
||||
|
||||
data_len--;
|
||||
|
||||
while(data_len)
|
||||
{
|
||||
xmm0 = _mm_load1_ps(data++);
|
||||
|
||||
/* shift xmm5:xmm4:xmm3:xmm2 left by one float */
|
||||
xmm5 = _mm_shuffle_ps(xmm5, xmm5, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm4 = _mm_shuffle_ps(xmm4, xmm4, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm5 = _mm_move_ss(xmm5, xmm4);
|
||||
xmm4 = _mm_move_ss(xmm4, xmm3);
|
||||
xmm3 = _mm_move_ss(xmm3, xmm2);
|
||||
xmm2 = _mm_move_ss(xmm2, xmm0);
|
||||
|
||||
/* xmm9|xmm8|xmm7|xmm6 += xmm0|xmm0|xmm0|xmm0 * xmm5|xmm4|xmm3|xmm2 */
|
||||
xmm1 = xmm0;
|
||||
xmm1 = _mm_mul_ps(xmm1, xmm5);
|
||||
xmm9 = _mm_add_ps(xmm9, xmm1);
|
||||
xmm1 = xmm0;
|
||||
xmm1 = _mm_mul_ps(xmm1, xmm4);
|
||||
xmm8 = _mm_add_ps(xmm8, xmm1);
|
||||
xmm1 = xmm0;
|
||||
xmm1 = _mm_mul_ps(xmm1, xmm3);
|
||||
xmm7 = _mm_add_ps(xmm7, xmm1);
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm2);
|
||||
xmm6 = _mm_add_ps(xmm6, xmm0);
|
||||
|
||||
data_len--;
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, xmm6);
|
||||
_mm_storeu_ps(autoc+4, xmm7);
|
||||
_mm_storeu_ps(autoc+8, xmm8);
|
||||
_mm_storeu_ps(autoc+12,xmm9);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FLAC__SSE_SUPPORTED */
|
||||
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
|
||||
#endif /* FLAC__NO_ASM */
|
||||
#endif /* FLAC__INTEGER_ONLY_LIBRARY */
|
||||
1088
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/lpc_intrin_sse2.c
vendored
Normal file
1088
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/lpc_intrin_sse2.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1312
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/lpc_intrin_sse41.c
vendored
Normal file
1312
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/lpc_intrin_sse41.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,518 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> /* for malloc() */
|
||||
#include <string.h> /* for memcpy() */
|
||||
|
||||
#include "private/md5.h"
|
||||
#include "share/alloc.h"
|
||||
#include "share/endswap.h"
|
||||
|
||||
/*
|
||||
* This code implements the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
*
|
||||
* Changed so as no longer to depend on Colin Plumb's `usual.h' header
|
||||
* definitions; now uses stuff from dpkg's config.h.
|
||||
* - Ian Jackson <ijackson@nyx.cs.du.edu>.
|
||||
* Still in the public domain.
|
||||
*
|
||||
* Josh Coalson: made some changes to integrate with libFLAC.
|
||||
* Still in the public domain.
|
||||
*/
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f,w,x,y,z,in,s) \
|
||||
(w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
|
||||
|
||||
/*
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
static void FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16])
|
||||
{
|
||||
register FLAC__uint32 a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
#if WORDS_BIGENDIAN
|
||||
//@@@@@@ OPT: use bswap/intrinsics
|
||||
static void byteSwap(FLAC__uint32 *buf, unsigned words)
|
||||
{
|
||||
register FLAC__uint32 x;
|
||||
do {
|
||||
x = *buf;
|
||||
x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff);
|
||||
*buf++ = (x >> 16) | (x << 16);
|
||||
} while (--words);
|
||||
}
|
||||
static void byteSwapX16(FLAC__uint32 *buf)
|
||||
{
|
||||
register FLAC__uint32 x;
|
||||
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf = (x >> 16) | (x << 16);
|
||||
}
|
||||
#else
|
||||
#define byteSwap(buf, words)
|
||||
#define byteSwapX16(buf)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Update context to reflect the concatenation of another buffer full
|
||||
* of bytes.
|
||||
*/
|
||||
static void FLAC__MD5Update(FLAC__MD5Context *ctx, FLAC__byte const *buf, unsigned len)
|
||||
{
|
||||
FLAC__uint32 t;
|
||||
|
||||
/* Update byte count */
|
||||
|
||||
t = ctx->bytes[0];
|
||||
if ((ctx->bytes[0] = t + len) < t)
|
||||
ctx->bytes[1]++; /* Carry from low to high */
|
||||
|
||||
t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
|
||||
if (t > len) {
|
||||
memcpy((FLAC__byte *)ctx->in + 64 - t, buf, len);
|
||||
return;
|
||||
}
|
||||
/* First chunk is an odd size */
|
||||
memcpy((FLAC__byte *)ctx->in + 64 - t, buf, t);
|
||||
byteSwapX16(ctx->in);
|
||||
FLAC__MD5Transform(ctx->buf, ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
|
||||
/* Process data in 64-byte chunks */
|
||||
while (len >= 64) {
|
||||
memcpy(ctx->in, buf, 64);
|
||||
byteSwapX16(ctx->in);
|
||||
FLAC__MD5Transform(ctx->buf, ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
memcpy(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
* initialization constants.
|
||||
*/
|
||||
void FLAC__MD5Init(FLAC__MD5Context *ctx)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bytes[0] = 0;
|
||||
ctx->bytes[1] = 0;
|
||||
|
||||
ctx->internal_buf.p8= 0;
|
||||
ctx->capacity = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||
*/
|
||||
void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx)
|
||||
{
|
||||
int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
|
||||
FLAC__byte *p = (FLAC__byte *)ctx->in + count;
|
||||
|
||||
/* Set the first char of padding to 0x80. There is always room. */
|
||||
*p++ = 0x80;
|
||||
|
||||
/* Bytes of padding needed to make 56 bytes (-8..55) */
|
||||
count = 56 - 1 - count;
|
||||
|
||||
if (count < 0) { /* Padding forces an extra block */
|
||||
memset(p, 0, count + 8);
|
||||
byteSwapX16(ctx->in);
|
||||
FLAC__MD5Transform(ctx->buf, ctx->in);
|
||||
p = (FLAC__byte *)ctx->in;
|
||||
count = 56;
|
||||
}
|
||||
memset(p, 0, count);
|
||||
byteSwap(ctx->in, 14);
|
||||
|
||||
/* Append length in bits and transform */
|
||||
ctx->in[14] = ctx->bytes[0] << 3;
|
||||
ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
|
||||
FLAC__MD5Transform(ctx->buf, ctx->in);
|
||||
|
||||
byteSwap(ctx->buf, 4);
|
||||
memcpy(digest, ctx->buf, 16);
|
||||
if (0 != ctx->internal_buf.p8) {
|
||||
free(ctx->internal_buf.p8);
|
||||
ctx->internal_buf.p8= 0;
|
||||
ctx->capacity = 0;
|
||||
}
|
||||
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the incoming audio signal to a byte stream
|
||||
*/
|
||||
static void format_input_(FLAC__multibyte *mbuf, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample)
|
||||
{
|
||||
FLAC__byte *buf_ = mbuf->p8;
|
||||
FLAC__int16 *buf16 = mbuf->p16;
|
||||
FLAC__int32 *buf32 = mbuf->p32;
|
||||
FLAC__int32 a_word;
|
||||
unsigned channel, sample;
|
||||
|
||||
/* Storage in the output buffer, buf, is little endian. */
|
||||
|
||||
#define BYTES_CHANNEL_SELECTOR(bytes, channels) (bytes * 100 + channels)
|
||||
|
||||
/* First do the most commonly used combinations. */
|
||||
switch (BYTES_CHANNEL_SELECTOR (bytes_per_sample, channels)) {
|
||||
/* One byte per sample. */
|
||||
case (BYTES_CHANNEL_SELECTOR (1, 1)):
|
||||
for (sample = 0; sample < samples; sample++)
|
||||
*buf_++ = signal[0][sample];
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (1, 2)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf_++ = signal[0][sample];
|
||||
*buf_++ = signal[1][sample];
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (1, 4)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf_++ = signal[0][sample];
|
||||
*buf_++ = signal[1][sample];
|
||||
*buf_++ = signal[2][sample];
|
||||
*buf_++ = signal[3][sample];
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (1, 6)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf_++ = signal[0][sample];
|
||||
*buf_++ = signal[1][sample];
|
||||
*buf_++ = signal[2][sample];
|
||||
*buf_++ = signal[3][sample];
|
||||
*buf_++ = signal[4][sample];
|
||||
*buf_++ = signal[5][sample];
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (1, 8)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf_++ = signal[0][sample];
|
||||
*buf_++ = signal[1][sample];
|
||||
*buf_++ = signal[2][sample];
|
||||
*buf_++ = signal[3][sample];
|
||||
*buf_++ = signal[4][sample];
|
||||
*buf_++ = signal[5][sample];
|
||||
*buf_++ = signal[6][sample];
|
||||
*buf_++ = signal[7][sample];
|
||||
}
|
||||
return;
|
||||
|
||||
/* Two bytes per sample. */
|
||||
case (BYTES_CHANNEL_SELECTOR (2, 1)):
|
||||
for (sample = 0; sample < samples; sample++)
|
||||
*buf16++ = H2LE_16(signal[0][sample]);
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (2, 2)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf16++ = H2LE_16(signal[0][sample]);
|
||||
*buf16++ = H2LE_16(signal[1][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (2, 4)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf16++ = H2LE_16(signal[0][sample]);
|
||||
*buf16++ = H2LE_16(signal[1][sample]);
|
||||
*buf16++ = H2LE_16(signal[2][sample]);
|
||||
*buf16++ = H2LE_16(signal[3][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (2, 6)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf16++ = H2LE_16(signal[0][sample]);
|
||||
*buf16++ = H2LE_16(signal[1][sample]);
|
||||
*buf16++ = H2LE_16(signal[2][sample]);
|
||||
*buf16++ = H2LE_16(signal[3][sample]);
|
||||
*buf16++ = H2LE_16(signal[4][sample]);
|
||||
*buf16++ = H2LE_16(signal[5][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (2, 8)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf16++ = H2LE_16(signal[0][sample]);
|
||||
*buf16++ = H2LE_16(signal[1][sample]);
|
||||
*buf16++ = H2LE_16(signal[2][sample]);
|
||||
*buf16++ = H2LE_16(signal[3][sample]);
|
||||
*buf16++ = H2LE_16(signal[4][sample]);
|
||||
*buf16++ = H2LE_16(signal[5][sample]);
|
||||
*buf16++ = H2LE_16(signal[6][sample]);
|
||||
*buf16++ = H2LE_16(signal[7][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
/* Three bytes per sample. */
|
||||
case (BYTES_CHANNEL_SELECTOR (3, 1)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
a_word = signal[0][sample];
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word;
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (3, 2)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
a_word = signal[0][sample];
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word;
|
||||
a_word = signal[1][sample];
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word;
|
||||
}
|
||||
return;
|
||||
|
||||
/* Four bytes per sample. */
|
||||
case (BYTES_CHANNEL_SELECTOR (4, 1)):
|
||||
for (sample = 0; sample < samples; sample++)
|
||||
*buf32++ = H2LE_32(signal[0][sample]);
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (4, 2)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf32++ = H2LE_32(signal[0][sample]);
|
||||
*buf32++ = H2LE_32(signal[1][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (4, 4)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf32++ = H2LE_32(signal[0][sample]);
|
||||
*buf32++ = H2LE_32(signal[1][sample]);
|
||||
*buf32++ = H2LE_32(signal[2][sample]);
|
||||
*buf32++ = H2LE_32(signal[3][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (4, 6)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf32++ = H2LE_32(signal[0][sample]);
|
||||
*buf32++ = H2LE_32(signal[1][sample]);
|
||||
*buf32++ = H2LE_32(signal[2][sample]);
|
||||
*buf32++ = H2LE_32(signal[3][sample]);
|
||||
*buf32++ = H2LE_32(signal[4][sample]);
|
||||
*buf32++ = H2LE_32(signal[5][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (4, 8)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf32++ = H2LE_32(signal[0][sample]);
|
||||
*buf32++ = H2LE_32(signal[1][sample]);
|
||||
*buf32++ = H2LE_32(signal[2][sample]);
|
||||
*buf32++ = H2LE_32(signal[3][sample]);
|
||||
*buf32++ = H2LE_32(signal[4][sample]);
|
||||
*buf32++ = H2LE_32(signal[5][sample]);
|
||||
*buf32++ = H2LE_32(signal[6][sample]);
|
||||
*buf32++ = H2LE_32(signal[7][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* General version. */
|
||||
switch (bytes_per_sample) {
|
||||
case 1:
|
||||
for (sample = 0; sample < samples; sample++)
|
||||
for (channel = 0; channel < channels; channel++)
|
||||
*buf_++ = signal[channel][sample];
|
||||
return;
|
||||
|
||||
case 2:
|
||||
for (sample = 0; sample < samples; sample++)
|
||||
for (channel = 0; channel < channels; channel++)
|
||||
*buf16++ = H2LE_16(signal[channel][sample]);
|
||||
return;
|
||||
|
||||
case 3:
|
||||
for (sample = 0; sample < samples; sample++)
|
||||
for (channel = 0; channel < channels; channel++) {
|
||||
a_word = signal[channel][sample];
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word;
|
||||
}
|
||||
return;
|
||||
|
||||
case 4:
|
||||
for (sample = 0; sample < samples; sample++)
|
||||
for (channel = 0; channel < channels; channel++)
|
||||
*buf32++ = H2LE_32(signal[channel][sample]);
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the incoming audio signal to a byte stream and FLAC__MD5Update it.
|
||||
*/
|
||||
FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample)
|
||||
{
|
||||
const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample;
|
||||
|
||||
/* overflow check */
|
||||
if ((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample)
|
||||
return false;
|
||||
if ((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples)
|
||||
return false;
|
||||
|
||||
if (ctx->capacity < bytes_needed) {
|
||||
FLAC__byte *tmp = realloc(ctx->internal_buf.p8, bytes_needed);
|
||||
if (0 == tmp) {
|
||||
free(ctx->internal_buf.p8);
|
||||
if (0 == (ctx->internal_buf.p8= safe_malloc_(bytes_needed)))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
ctx->internal_buf.p8= tmp;
|
||||
ctx->capacity = bytes_needed;
|
||||
}
|
||||
|
||||
format_input_(&ctx->internal_buf, signal, channels, samples, bytes_per_sample);
|
||||
|
||||
FLAC__MD5Update(ctx, ctx->internal_buf.p8, bytes_needed);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,218 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "private/memory.h"
|
||||
#include "FLAC/assert.h"
|
||||
#include "share/alloc.h"
|
||||
|
||||
void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
|
||||
{
|
||||
void *x;
|
||||
|
||||
FLAC__ASSERT(0 != aligned_address);
|
||||
|
||||
#ifdef FLAC__ALIGN_MALLOC_DATA
|
||||
/* align on 32-byte (256-bit) boundary */
|
||||
x = safe_malloc_add_2op_(bytes, /*+*/31L);
|
||||
*aligned_address = (void*)(((uintptr_t)x + 31L) & -32L);
|
||||
#else
|
||||
x = safe_malloc_(bytes);
|
||||
*aligned_address = x;
|
||||
#endif
|
||||
return x;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer)
|
||||
{
|
||||
FLAC__int32 *pu; /* unaligned pointer */
|
||||
union { /* union needed to comply with C99 pointer aliasing rules */
|
||||
FLAC__int32 *pa; /* aligned pointer */
|
||||
void *pv; /* aligned pointer alias */
|
||||
} u;
|
||||
|
||||
FLAC__ASSERT(elements > 0);
|
||||
FLAC__ASSERT(0 != unaligned_pointer);
|
||||
FLAC__ASSERT(0 != aligned_pointer);
|
||||
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
|
||||
|
||||
if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
|
||||
return false;
|
||||
|
||||
pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
|
||||
if(0 == pu) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*unaligned_pointer != 0)
|
||||
free(*unaligned_pointer);
|
||||
*unaligned_pointer = pu;
|
||||
*aligned_pointer = u.pa;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer)
|
||||
{
|
||||
FLAC__uint32 *pu; /* unaligned pointer */
|
||||
union { /* union needed to comply with C99 pointer aliasing rules */
|
||||
FLAC__uint32 *pa; /* aligned pointer */
|
||||
void *pv; /* aligned pointer alias */
|
||||
} u;
|
||||
|
||||
FLAC__ASSERT(elements > 0);
|
||||
FLAC__ASSERT(0 != unaligned_pointer);
|
||||
FLAC__ASSERT(0 != aligned_pointer);
|
||||
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
|
||||
|
||||
if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
|
||||
return false;
|
||||
|
||||
pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
|
||||
if(0 == pu) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*unaligned_pointer != 0)
|
||||
free(*unaligned_pointer);
|
||||
*unaligned_pointer = pu;
|
||||
*aligned_pointer = u.pa;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer)
|
||||
{
|
||||
FLAC__uint64 *pu; /* unaligned pointer */
|
||||
union { /* union needed to comply with C99 pointer aliasing rules */
|
||||
FLAC__uint64 *pa; /* aligned pointer */
|
||||
void *pv; /* aligned pointer alias */
|
||||
} u;
|
||||
|
||||
FLAC__ASSERT(elements > 0);
|
||||
FLAC__ASSERT(0 != unaligned_pointer);
|
||||
FLAC__ASSERT(0 != aligned_pointer);
|
||||
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
|
||||
|
||||
if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
|
||||
return false;
|
||||
|
||||
pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
|
||||
if(0 == pu) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*unaligned_pointer != 0)
|
||||
free(*unaligned_pointer);
|
||||
*unaligned_pointer = pu;
|
||||
*aligned_pointer = u.pa;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, unsigned **unaligned_pointer, unsigned **aligned_pointer)
|
||||
{
|
||||
unsigned *pu; /* unaligned pointer */
|
||||
union { /* union needed to comply with C99 pointer aliasing rules */
|
||||
unsigned *pa; /* aligned pointer */
|
||||
void *pv; /* aligned pointer alias */
|
||||
} u;
|
||||
|
||||
FLAC__ASSERT(elements > 0);
|
||||
FLAC__ASSERT(0 != unaligned_pointer);
|
||||
FLAC__ASSERT(0 != aligned_pointer);
|
||||
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
|
||||
|
||||
if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
|
||||
return false;
|
||||
|
||||
pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
|
||||
if(0 == pu) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*unaligned_pointer != 0)
|
||||
free(*unaligned_pointer);
|
||||
*unaligned_pointer = pu;
|
||||
*aligned_pointer = u.pa;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
|
||||
FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer)
|
||||
{
|
||||
FLAC__real *pu; /* unaligned pointer */
|
||||
union { /* union needed to comply with C99 pointer aliasing rules */
|
||||
FLAC__real *pa; /* aligned pointer */
|
||||
void *pv; /* aligned pointer alias */
|
||||
} u;
|
||||
|
||||
FLAC__ASSERT(elements > 0);
|
||||
FLAC__ASSERT(0 != unaligned_pointer);
|
||||
FLAC__ASSERT(0 != aligned_pointer);
|
||||
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
|
||||
|
||||
if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
|
||||
return false;
|
||||
|
||||
pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
|
||||
if(0 == pu) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*unaligned_pointer != 0)
|
||||
free(*unaligned_pointer);
|
||||
*unaligned_pointer = pu;
|
||||
*aligned_pointer = u.pa;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void *safe_malloc_mul_2op_p(size_t size1, size_t size2)
|
||||
{
|
||||
if(!size1 || !size2)
|
||||
return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
return malloc(size1*size2);
|
||||
}
|
||||
3402
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/metadata_iterators.c
vendored
Normal file
3402
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/metadata_iterators.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1824
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/metadata_object.c
vendored
Normal file
1824
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/metadata_object.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
251
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/ogg_decoder_aspect.c
vendored
Normal file
251
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/ogg_decoder_aspect.c
vendored
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
/* libFLAC - Free Lossless Audio Codec
|
||||
* Copyright (C) 2002-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h> /* for memcpy() */
|
||||
#include "FLAC/assert.h"
|
||||
#include "private/ogg_decoder_aspect.h"
|
||||
#include "private/ogg_mapping.h"
|
||||
#include "private/macros.h"
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Public class methods
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
FLAC__bool FLAC__ogg_decoder_aspect_init(FLAC__OggDecoderAspect *aspect)
|
||||
{
|
||||
/* we will determine the serial number later if necessary */
|
||||
if(ogg_stream_init(&aspect->stream_state, aspect->serial_number) != 0)
|
||||
return false;
|
||||
|
||||
if(ogg_sync_init(&aspect->sync_state) != 0)
|
||||
return false;
|
||||
|
||||
aspect->version_major = ~(0u);
|
||||
aspect->version_minor = ~(0u);
|
||||
|
||||
aspect->need_serial_number = aspect->use_first_serial_number;
|
||||
|
||||
aspect->end_of_stream = false;
|
||||
aspect->have_working_page = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FLAC__ogg_decoder_aspect_finish(FLAC__OggDecoderAspect *aspect)
|
||||
{
|
||||
(void)ogg_sync_clear(&aspect->sync_state);
|
||||
(void)ogg_stream_clear(&aspect->stream_state);
|
||||
}
|
||||
|
||||
void FLAC__ogg_decoder_aspect_set_serial_number(FLAC__OggDecoderAspect *aspect, long value)
|
||||
{
|
||||
aspect->use_first_serial_number = false;
|
||||
aspect->serial_number = value;
|
||||
}
|
||||
|
||||
void FLAC__ogg_decoder_aspect_set_defaults(FLAC__OggDecoderAspect *aspect)
|
||||
{
|
||||
aspect->use_first_serial_number = true;
|
||||
}
|
||||
|
||||
void FLAC__ogg_decoder_aspect_flush(FLAC__OggDecoderAspect *aspect)
|
||||
{
|
||||
(void)ogg_stream_reset(&aspect->stream_state);
|
||||
(void)ogg_sync_reset(&aspect->sync_state);
|
||||
aspect->end_of_stream = false;
|
||||
aspect->have_working_page = false;
|
||||
}
|
||||
|
||||
void FLAC__ogg_decoder_aspect_reset(FLAC__OggDecoderAspect *aspect)
|
||||
{
|
||||
FLAC__ogg_decoder_aspect_flush(aspect);
|
||||
|
||||
if(aspect->use_first_serial_number)
|
||||
aspect->need_serial_number = true;
|
||||
}
|
||||
|
||||
FLAC__OggDecoderAspectReadStatus FLAC__ogg_decoder_aspect_read_callback_wrapper(FLAC__OggDecoderAspect *aspect, FLAC__byte buffer[], size_t *bytes, FLAC__OggDecoderAspectReadCallbackProxy read_callback, const FLAC__StreamDecoder *decoder, void *client_data)
|
||||
{
|
||||
static const size_t OGG_BYTES_CHUNK = 8192;
|
||||
const size_t bytes_requested = *bytes;
|
||||
|
||||
/*
|
||||
* The FLAC decoding API uses pull-based reads, whereas Ogg decoding
|
||||
* is push-based. In libFLAC, when you ask to decode a frame, the
|
||||
* decoder will eventually call the read callback to supply some data,
|
||||
* but how much it asks for depends on how much free space it has in
|
||||
* its internal buffer. It does not try to grow its internal buffer
|
||||
* to accomodate a whole frame because then the internal buffer size
|
||||
* could not be limited, which is necessary in embedded applications.
|
||||
*
|
||||
* Ogg however grows its internal buffer until a whole page is present;
|
||||
* only then can you get decoded data out. So we can't just ask for
|
||||
* the same number of bytes from Ogg, then pass what's decoded down to
|
||||
* libFLAC. If what libFLAC is asking for will not contain a whole
|
||||
* page, then we will get no data from ogg_sync_pageout(), and at the
|
||||
* same time cannot just read more data from the client for the purpose
|
||||
* of getting a whole decoded page because the decoded size might be
|
||||
* larger than libFLAC's internal buffer.
|
||||
*
|
||||
* Instead, whenever this read callback wrapper is called, we will
|
||||
* continually request data from the client until we have at least one
|
||||
* page, and manage pages internally so that we can send pieces of
|
||||
* pages down to libFLAC in such a way that we obey its size
|
||||
* requirement. To limit the amount of callbacks, we will always try
|
||||
* to read in enough pages to return the full number of bytes
|
||||
* requested.
|
||||
*/
|
||||
*bytes = 0;
|
||||
while (*bytes < bytes_requested && !aspect->end_of_stream) {
|
||||
if (aspect->have_working_page) {
|
||||
if (aspect->have_working_packet) {
|
||||
size_t n = bytes_requested - *bytes;
|
||||
if ((size_t)aspect->working_packet.bytes <= n) {
|
||||
/* the rest of the packet will fit in the buffer */
|
||||
n = aspect->working_packet.bytes;
|
||||
memcpy(buffer, aspect->working_packet.packet, n);
|
||||
*bytes += n;
|
||||
buffer += n;
|
||||
aspect->have_working_packet = false;
|
||||
}
|
||||
else {
|
||||
/* only n bytes of the packet will fit in the buffer */
|
||||
memcpy(buffer, aspect->working_packet.packet, n);
|
||||
*bytes += n;
|
||||
buffer += n;
|
||||
aspect->working_packet.packet += n;
|
||||
aspect->working_packet.bytes -= n;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* try and get another packet */
|
||||
const int ret = ogg_stream_packetout(&aspect->stream_state, &aspect->working_packet);
|
||||
if (ret > 0) {
|
||||
aspect->have_working_packet = true;
|
||||
/* if it is the first header packet, check for magic and a supported Ogg FLAC mapping version */
|
||||
if (aspect->working_packet.bytes > 0 && aspect->working_packet.packet[0] == FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE) {
|
||||
const FLAC__byte *b = aspect->working_packet.packet;
|
||||
const unsigned header_length =
|
||||
FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH +
|
||||
FLAC__OGG_MAPPING_MAGIC_LENGTH +
|
||||
FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH +
|
||||
FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH +
|
||||
FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH;
|
||||
if (aspect->working_packet.bytes < (long)header_length)
|
||||
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC;
|
||||
b += FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH;
|
||||
if (memcmp(b, FLAC__OGG_MAPPING_MAGIC, FLAC__OGG_MAPPING_MAGIC_LENGTH))
|
||||
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC;
|
||||
b += FLAC__OGG_MAPPING_MAGIC_LENGTH;
|
||||
aspect->version_major = (unsigned)(*b);
|
||||
b += FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH;
|
||||
aspect->version_minor = (unsigned)(*b);
|
||||
if (aspect->version_major != 1)
|
||||
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION;
|
||||
aspect->working_packet.packet += header_length;
|
||||
aspect->working_packet.bytes -= header_length;
|
||||
}
|
||||
}
|
||||
else if (ret == 0) {
|
||||
aspect->have_working_page = false;
|
||||
}
|
||||
else { /* ret < 0 */
|
||||
/* lost sync, we'll leave the working page for the next call */
|
||||
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* try and get another page */
|
||||
const int ret = ogg_sync_pageout(&aspect->sync_state, &aspect->working_page);
|
||||
if (ret > 0) {
|
||||
/* got a page, grab the serial number if necessary */
|
||||
if(aspect->need_serial_number) {
|
||||
aspect->stream_state.serialno = aspect->serial_number = ogg_page_serialno(&aspect->working_page);
|
||||
aspect->need_serial_number = false;
|
||||
}
|
||||
if(ogg_stream_pagein(&aspect->stream_state, &aspect->working_page) == 0) {
|
||||
aspect->have_working_page = true;
|
||||
aspect->have_working_packet = false;
|
||||
}
|
||||
/* else do nothing, could be a page from another stream */
|
||||
}
|
||||
else if (ret == 0) {
|
||||
/* need more data */
|
||||
const size_t ogg_bytes_to_read = flac_max(bytes_requested - *bytes, OGG_BYTES_CHUNK);
|
||||
char *oggbuf = ogg_sync_buffer(&aspect->sync_state, ogg_bytes_to_read);
|
||||
|
||||
if(0 == oggbuf) {
|
||||
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
else {
|
||||
size_t ogg_bytes_read = ogg_bytes_to_read;
|
||||
|
||||
switch(read_callback(decoder, (FLAC__byte*)oggbuf, &ogg_bytes_read, client_data)) {
|
||||
case FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK:
|
||||
break;
|
||||
case FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM:
|
||||
aspect->end_of_stream = true;
|
||||
break;
|
||||
case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT:
|
||||
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
|
||||
default:
|
||||
FLAC__ASSERT(0);
|
||||
}
|
||||
|
||||
if(ogg_sync_wrote(&aspect->sync_state, ogg_bytes_read) < 0) {
|
||||
/* double protection; this will happen if the read callback returns more bytes than the max requested, which would overflow Ogg's internal buffer */
|
||||
FLAC__ASSERT(0);
|
||||
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* ret < 0 */
|
||||
/* lost sync, bail out */
|
||||
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aspect->end_of_stream && *bytes == 0) {
|
||||
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM;
|
||||
}
|
||||
|
||||
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK;
|
||||
}
|
||||
228
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/ogg_encoder_aspect.c
vendored
Normal file
228
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/ogg_encoder_aspect.c
vendored
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
/* libFLAC - Free Lossless Audio Codec
|
||||
* Copyright (C) 2002-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h> /* for memset() */
|
||||
#include "FLAC/assert.h"
|
||||
#include "private/ogg_encoder_aspect.h"
|
||||
#include "private/ogg_mapping.h"
|
||||
|
||||
static const FLAC__byte FLAC__OGG_MAPPING_VERSION_MAJOR = 1;
|
||||
static const FLAC__byte FLAC__OGG_MAPPING_VERSION_MINOR = 0;
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Public class methods
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
FLAC__bool FLAC__ogg_encoder_aspect_init(FLAC__OggEncoderAspect *aspect)
|
||||
{
|
||||
/* we will determine the serial number later if necessary */
|
||||
if(ogg_stream_init(&aspect->stream_state, aspect->serial_number) != 0)
|
||||
return false;
|
||||
|
||||
aspect->seen_magic = false;
|
||||
aspect->is_first_packet = true;
|
||||
aspect->samples_written = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FLAC__ogg_encoder_aspect_finish(FLAC__OggEncoderAspect *aspect)
|
||||
{
|
||||
(void)ogg_stream_clear(&aspect->stream_state);
|
||||
/*@@@ what about the page? */
|
||||
}
|
||||
|
||||
void FLAC__ogg_encoder_aspect_set_serial_number(FLAC__OggEncoderAspect *aspect, long value)
|
||||
{
|
||||
aspect->serial_number = value;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__ogg_encoder_aspect_set_num_metadata(FLAC__OggEncoderAspect *aspect, unsigned value)
|
||||
{
|
||||
if(value < (1u << FLAC__OGG_MAPPING_NUM_HEADERS_LEN)) {
|
||||
aspect->num_metadata = value;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void FLAC__ogg_encoder_aspect_set_defaults(FLAC__OggEncoderAspect *aspect)
|
||||
{
|
||||
aspect->serial_number = 0;
|
||||
aspect->num_metadata = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The basic FLAC -> Ogg mapping goes like this:
|
||||
*
|
||||
* - 'fLaC' magic and STREAMINFO block get combined into the first
|
||||
* packet. The packet is prefixed with
|
||||
* + the one-byte packet type 0x7F
|
||||
* + 'FLAC' magic
|
||||
* + the 2 byte Ogg FLAC mapping version number
|
||||
* + tne 2 byte big-endian # of header packets
|
||||
* - The first packet is flushed to the first page.
|
||||
* - Each subsequent metadata block goes into its own packet.
|
||||
* - Each metadata packet is flushed to page (this is not required,
|
||||
* the mapping only requires that a flush must occur after all
|
||||
* metadata is written).
|
||||
* - Each subsequent FLAC audio frame goes into its own packet.
|
||||
*
|
||||
* WATCHOUT:
|
||||
* This depends on the behavior of FLAC__StreamEncoder that we get a
|
||||
* separate write callback for the fLaC magic, and then separate write
|
||||
* callbacks for each metadata block and audio frame.
|
||||
*/
|
||||
FLAC__StreamEncoderWriteStatus FLAC__ogg_encoder_aspect_write_callback_wrapper(FLAC__OggEncoderAspect *aspect, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, FLAC__bool is_last_block, FLAC__OggEncoderAspectWriteCallbackProxy write_callback, void *encoder, void *client_data)
|
||||
{
|
||||
/* WATCHOUT:
|
||||
* This depends on the behavior of FLAC__StreamEncoder that 'samples'
|
||||
* will be 0 for metadata writes.
|
||||
*/
|
||||
const FLAC__bool is_metadata = (samples == 0);
|
||||
|
||||
/*
|
||||
* Treat fLaC magic packet specially. We will note when we see it, then
|
||||
* wait until we get the STREAMINFO and prepend it in that packet
|
||||
*/
|
||||
if(aspect->seen_magic) {
|
||||
ogg_packet packet;
|
||||
FLAC__byte synthetic_first_packet_body[
|
||||
FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH +
|
||||
FLAC__OGG_MAPPING_MAGIC_LENGTH +
|
||||
FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH +
|
||||
FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH +
|
||||
FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH +
|
||||
FLAC__STREAM_SYNC_LENGTH +
|
||||
FLAC__STREAM_METADATA_HEADER_LENGTH +
|
||||
FLAC__STREAM_METADATA_STREAMINFO_LENGTH
|
||||
];
|
||||
|
||||
memset(&packet, 0, sizeof(packet));
|
||||
packet.granulepos = aspect->samples_written + samples;
|
||||
|
||||
if(aspect->is_first_packet) {
|
||||
FLAC__byte *b = synthetic_first_packet_body;
|
||||
if(bytes != FLAC__STREAM_METADATA_HEADER_LENGTH + FLAC__STREAM_METADATA_STREAMINFO_LENGTH) {
|
||||
/*
|
||||
* If we get here, our assumption about the way write callbacks happen
|
||||
* (explained above) is wrong
|
||||
*/
|
||||
FLAC__ASSERT(0);
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
}
|
||||
/* add first header packet type */
|
||||
*b = FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE;
|
||||
b += FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH;
|
||||
/* add 'FLAC' mapping magic */
|
||||
memcpy(b, FLAC__OGG_MAPPING_MAGIC, FLAC__OGG_MAPPING_MAGIC_LENGTH);
|
||||
b += FLAC__OGG_MAPPING_MAGIC_LENGTH;
|
||||
/* add Ogg FLAC mapping major version number */
|
||||
memcpy(b, &FLAC__OGG_MAPPING_VERSION_MAJOR, FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH);
|
||||
b += FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH;
|
||||
/* add Ogg FLAC mapping minor version number */
|
||||
memcpy(b, &FLAC__OGG_MAPPING_VERSION_MINOR, FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH);
|
||||
b += FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH;
|
||||
/* add number of header packets */
|
||||
*b = (FLAC__byte)(aspect->num_metadata >> 8);
|
||||
b++;
|
||||
*b = (FLAC__byte)(aspect->num_metadata);
|
||||
b++;
|
||||
/* add native FLAC 'fLaC' magic */
|
||||
memcpy(b, FLAC__STREAM_SYNC_STRING, FLAC__STREAM_SYNC_LENGTH);
|
||||
b += FLAC__STREAM_SYNC_LENGTH;
|
||||
/* add STREAMINFO */
|
||||
memcpy(b, buffer, bytes);
|
||||
FLAC__ASSERT(b + bytes - synthetic_first_packet_body == sizeof(synthetic_first_packet_body));
|
||||
packet.packet = (unsigned char *)synthetic_first_packet_body;
|
||||
packet.bytes = sizeof(synthetic_first_packet_body);
|
||||
|
||||
packet.b_o_s = 1;
|
||||
aspect->is_first_packet = false;
|
||||
}
|
||||
else {
|
||||
packet.packet = (unsigned char *)buffer;
|
||||
packet.bytes = bytes;
|
||||
}
|
||||
|
||||
if(is_last_block) {
|
||||
/* we used to check:
|
||||
* FLAC__ASSERT(total_samples_estimate == 0 || total_samples_estimate == aspect->samples_written + samples);
|
||||
* but it's really not useful since total_samples_estimate is an estimate and can be inexact
|
||||
*/
|
||||
packet.e_o_s = 1;
|
||||
}
|
||||
|
||||
if(ogg_stream_packetin(&aspect->stream_state, &packet) != 0)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
|
||||
/*@@@ can't figure out a way to pass a useful number for 'samples' to the write_callback, so we'll just pass 0 */
|
||||
if(is_metadata) {
|
||||
while(ogg_stream_flush(&aspect->stream_state, &aspect->page) != 0) {
|
||||
if(write_callback(encoder, aspect->page.header, aspect->page.header_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
if(write_callback(encoder, aspect->page.body, aspect->page.body_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(ogg_stream_pageout(&aspect->stream_state, &aspect->page) != 0) {
|
||||
if(write_callback(encoder, aspect->page.header, aspect->page.header_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
if(write_callback(encoder, aspect->page.body, aspect->page.body_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(is_metadata && current_frame == 0 && samples == 0 && bytes == 4 && 0 == memcmp(buffer, FLAC__STREAM_SYNC_STRING, sizeof(FLAC__STREAM_SYNC_STRING))) {
|
||||
aspect->seen_magic = true;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* If we get here, our assumption about the way write callbacks happen
|
||||
* explained above is wrong
|
||||
*/
|
||||
FLAC__ASSERT(0);
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
aspect->samples_written += samples;
|
||||
|
||||
return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
|
||||
}
|
||||
|
|
@ -0,0 +1,210 @@
|
|||
/* libFLAC - Free Lossless Audio Codec
|
||||
* Copyright (C) 2004-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> /* for malloc() */
|
||||
#include <string.h> /* for memcmp(), memcpy() */
|
||||
#include "FLAC/assert.h"
|
||||
#include "share/alloc.h"
|
||||
#include "private/ogg_helper.h"
|
||||
#include "protected/stream_encoder.h"
|
||||
|
||||
|
||||
static FLAC__bool full_read_(FLAC__StreamEncoder *encoder, FLAC__byte *buffer, size_t bytes, FLAC__StreamEncoderReadCallback read_callback, void *client_data)
|
||||
{
|
||||
while(bytes > 0) {
|
||||
size_t bytes_read = bytes;
|
||||
switch(read_callback(encoder, buffer, &bytes_read, client_data)) {
|
||||
case FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE:
|
||||
bytes -= bytes_read;
|
||||
buffer += bytes_read;
|
||||
break;
|
||||
case FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM:
|
||||
if(bytes_read == 0) {
|
||||
encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
|
||||
return false;
|
||||
}
|
||||
bytes -= bytes_read;
|
||||
buffer += bytes_read;
|
||||
break;
|
||||
case FLAC__STREAM_ENCODER_READ_STATUS_ABORT:
|
||||
encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
|
||||
return false;
|
||||
case FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED:
|
||||
return false;
|
||||
default:
|
||||
/* double protection: */
|
||||
FLAC__ASSERT(0);
|
||||
encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void simple_ogg_page__init(ogg_page *page)
|
||||
{
|
||||
page->header = 0;
|
||||
page->header_len = 0;
|
||||
page->body = 0;
|
||||
page->body_len = 0;
|
||||
}
|
||||
|
||||
void simple_ogg_page__clear(ogg_page *page)
|
||||
{
|
||||
if(page->header)
|
||||
free(page->header);
|
||||
if(page->body)
|
||||
free(page->body);
|
||||
simple_ogg_page__init(page);
|
||||
}
|
||||
|
||||
FLAC__bool simple_ogg_page__get_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderReadCallback read_callback, void *client_data)
|
||||
{
|
||||
static const unsigned OGG_HEADER_FIXED_PORTION_LEN = 27;
|
||||
static const unsigned OGG_MAX_HEADER_LEN = 27/*OGG_HEADER_FIXED_PORTION_LEN*/ + 255;
|
||||
FLAC__byte crc[4];
|
||||
FLAC__StreamEncoderSeekStatus seek_status;
|
||||
|
||||
FLAC__ASSERT(page->header == 0);
|
||||
FLAC__ASSERT(page->header_len == 0);
|
||||
FLAC__ASSERT(page->body == 0);
|
||||
FLAC__ASSERT(page->body_len == 0);
|
||||
|
||||
/* move the stream pointer to the supposed beginning of the page */
|
||||
if(0 == seek_callback)
|
||||
return false;
|
||||
if((seek_status = seek_callback((FLAC__StreamEncoder*)encoder, position, client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) {
|
||||
if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR)
|
||||
encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* allocate space for the page header */
|
||||
if(0 == (page->header = safe_malloc_(OGG_MAX_HEADER_LEN))) {
|
||||
encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* read in the fixed part of the page header (up to but not including
|
||||
* the segment table */
|
||||
if(!full_read_(encoder, page->header, OGG_HEADER_FIXED_PORTION_LEN, read_callback, client_data))
|
||||
return false;
|
||||
|
||||
page->header_len = OGG_HEADER_FIXED_PORTION_LEN + page->header[26];
|
||||
|
||||
/* check to see if it's a correct, "simple" page (one packet only) */
|
||||
if(
|
||||
memcmp(page->header, "OggS", 4) || /* doesn't start with OggS */
|
||||
(page->header[5] & 0x01) || /* continued packet */
|
||||
memcmp(page->header+6, "\0\0\0\0\0\0\0\0", 8) || /* granulepos is non-zero */
|
||||
page->header[26] == 0 /* packet is 0-size */
|
||||
) {
|
||||
encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* read in the segment table */
|
||||
if(!full_read_(encoder, page->header + OGG_HEADER_FIXED_PORTION_LEN, page->header[26], read_callback, client_data))
|
||||
return false;
|
||||
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* check to see that it specifies a single packet */
|
||||
for(i = 0; i < (unsigned)page->header[26] - 1; i++) {
|
||||
if(page->header[i + OGG_HEADER_FIXED_PORTION_LEN] != 255) {
|
||||
encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
page->body_len = 255 * i + page->header[i + OGG_HEADER_FIXED_PORTION_LEN];
|
||||
}
|
||||
|
||||
/* allocate space for the page body */
|
||||
if(0 == (page->body = safe_malloc_(page->body_len))) {
|
||||
encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* read in the page body */
|
||||
if(!full_read_(encoder, page->body, page->body_len, read_callback, client_data))
|
||||
return false;
|
||||
|
||||
/* check the CRC */
|
||||
memcpy(crc, page->header+22, 4);
|
||||
ogg_page_checksum_set(page);
|
||||
if(memcmp(crc, page->header+22, 4)) {
|
||||
encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool simple_ogg_page__set_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderWriteCallback write_callback, void *client_data)
|
||||
{
|
||||
FLAC__StreamEncoderSeekStatus seek_status;
|
||||
|
||||
FLAC__ASSERT(page->header != 0);
|
||||
FLAC__ASSERT(page->header_len != 0);
|
||||
FLAC__ASSERT(page->body != 0);
|
||||
FLAC__ASSERT(page->body_len != 0);
|
||||
|
||||
/* move the stream pointer to the supposed beginning of the page */
|
||||
if(0 == seek_callback)
|
||||
return false;
|
||||
if((seek_status = seek_callback((FLAC__StreamEncoder*)encoder, position, client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) {
|
||||
if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR)
|
||||
encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
ogg_page_checksum_set(page);
|
||||
|
||||
/* re-write the page */
|
||||
if(write_callback((FLAC__StreamEncoder*)encoder, page->header, page->header_len, 0, 0, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
|
||||
encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
|
||||
return false;
|
||||
}
|
||||
if(write_callback((FLAC__StreamEncoder*)encoder, page->body, page->body_len, 0, 0, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
|
||||
encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/* libFLAC - Free Lossless Audio Codec
|
||||
* Copyright (C) 2004-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/ogg_mapping.h"
|
||||
|
||||
const unsigned FLAC__OGG_MAPPING_PACKET_TYPE_LEN = 8; /* bits */
|
||||
|
||||
const FLAC__byte FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE = 0x7f;
|
||||
|
||||
const FLAC__byte * const FLAC__OGG_MAPPING_MAGIC = (const FLAC__byte * const)"FLAC";
|
||||
|
||||
const unsigned FLAC__OGG_MAPPING_VERSION_MAJOR_LEN = 8; /* bits */
|
||||
const unsigned FLAC__OGG_MAPPING_VERSION_MINOR_LEN = 8; /* bits */
|
||||
|
||||
const unsigned FLAC__OGG_MAPPING_NUM_HEADERS_LEN = 16; /* bits */
|
||||
3389
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/stream_decoder.c
vendored
Normal file
3389
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/stream_decoder.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4525
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/stream_encoder.c
vendored
Normal file
4525
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/stream_encoder.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
549
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/stream_encoder_framing.c
vendored
Normal file
549
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/stream_encoder_framing.c
vendored
Normal file
|
|
@ -0,0 +1,549 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> /* for strlen() */
|
||||
#include "private/stream_encoder_framing.h"
|
||||
#include "private/crc.h"
|
||||
#include "FLAC/assert.h"
|
||||
|
||||
static FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCodingMethod *method);
|
||||
static FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order, const FLAC__bool is_extended);
|
||||
|
||||
FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw)
|
||||
{
|
||||
unsigned i, j;
|
||||
const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING);
|
||||
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->is_last, FLAC__STREAM_METADATA_IS_LAST_LEN))
|
||||
return false;
|
||||
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->type, FLAC__STREAM_METADATA_TYPE_LEN))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* First, for VORBIS_COMMENTs, adjust the length to reflect our vendor string
|
||||
*/
|
||||
i = metadata->length;
|
||||
if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
|
||||
FLAC__ASSERT(metadata->data.vorbis_comment.vendor_string.length == 0 || 0 != metadata->data.vorbis_comment.vendor_string.entry);
|
||||
i -= metadata->data.vorbis_comment.vendor_string.length;
|
||||
i += vendor_string_length;
|
||||
}
|
||||
FLAC__ASSERT(i < (1u << FLAC__STREAM_METADATA_LENGTH_LEN));
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, i, FLAC__STREAM_METADATA_LENGTH_LEN))
|
||||
return false;
|
||||
|
||||
switch(metadata->type) {
|
||||
case FLAC__METADATA_TYPE_STREAMINFO:
|
||||
FLAC__ASSERT(metadata->data.stream_info.min_blocksize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN));
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.min_blocksize, FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN))
|
||||
return false;
|
||||
FLAC__ASSERT(metadata->data.stream_info.max_blocksize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN));
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.max_blocksize, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN))
|
||||
return false;
|
||||
FLAC__ASSERT(metadata->data.stream_info.min_framesize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN));
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.min_framesize, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN))
|
||||
return false;
|
||||
FLAC__ASSERT(metadata->data.stream_info.max_framesize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN));
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.max_framesize, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN))
|
||||
return false;
|
||||
FLAC__ASSERT(FLAC__format_sample_rate_is_valid(metadata->data.stream_info.sample_rate));
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.sample_rate, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN))
|
||||
return false;
|
||||
FLAC__ASSERT(metadata->data.stream_info.channels > 0);
|
||||
FLAC__ASSERT(metadata->data.stream_info.channels <= (1u << FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN));
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.channels-1, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN))
|
||||
return false;
|
||||
FLAC__ASSERT(metadata->data.stream_info.bits_per_sample > 0);
|
||||
FLAC__ASSERT(metadata->data.stream_info.bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN));
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.bits_per_sample-1, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.stream_info.md5sum, 16))
|
||||
return false;
|
||||
break;
|
||||
case FLAC__METADATA_TYPE_PADDING:
|
||||
if(!FLAC__bitwriter_write_zeroes(bw, metadata->length * 8))
|
||||
return false;
|
||||
break;
|
||||
case FLAC__METADATA_TYPE_APPLICATION:
|
||||
if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.application.data, metadata->length - (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)))
|
||||
return false;
|
||||
break;
|
||||
case FLAC__METADATA_TYPE_SEEKTABLE:
|
||||
for(i = 0; i < metadata->data.seek_table.num_points; i++) {
|
||||
if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.seek_table.points[i].sample_number, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.seek_table.points[i].stream_offset, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.seek_table.points[i].frame_samples, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
|
||||
if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, vendor_string_length))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)FLAC__VENDOR_STRING, vendor_string_length))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, metadata->data.vorbis_comment.num_comments))
|
||||
return false;
|
||||
for(i = 0; i < metadata->data.vorbis_comment.num_comments; i++) {
|
||||
if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, metadata->data.vorbis_comment.comments[i].length))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.vorbis_comment.comments[i].entry, metadata->data.vorbis_comment.comments[i].length))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case FLAC__METADATA_TYPE_CUESHEET:
|
||||
FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0);
|
||||
if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)metadata->data.cue_sheet.media_catalog_number, FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN/8))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.cue_sheet.lead_in, FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.cue_sheet.is_cd? 1 : 0, FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.cue_sheet.num_tracks, FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN))
|
||||
return false;
|
||||
for(i = 0; i < metadata->data.cue_sheet.num_tracks; i++) {
|
||||
const FLAC__StreamMetadata_CueSheet_Track *track = metadata->data.cue_sheet.tracks + i;
|
||||
|
||||
if(!FLAC__bitwriter_write_raw_uint64(bw, track->offset, FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, track->number, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN))
|
||||
return false;
|
||||
FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0);
|
||||
if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)track->isrc, FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN/8))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, track->type, FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, track->pre_emphasis, FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, track->num_indices, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN))
|
||||
return false;
|
||||
for(j = 0; j < track->num_indices; j++) {
|
||||
const FLAC__StreamMetadata_CueSheet_Index *indx = track->indices + j;
|
||||
|
||||
if(!FLAC__bitwriter_write_raw_uint64(bw, indx->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, indx->number, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FLAC__METADATA_TYPE_PICTURE:
|
||||
{
|
||||
size_t len;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.type, FLAC__STREAM_METADATA_PICTURE_TYPE_LEN))
|
||||
return false;
|
||||
len = strlen(metadata->data.picture.mime_type);
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, len, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)metadata->data.picture.mime_type, len))
|
||||
return false;
|
||||
len = strlen((const char *)metadata->data.picture.description);
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, len, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.picture.description, len))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.width, FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.height, FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.depth, FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.colors, FLAC__STREAM_METADATA_PICTURE_COLORS_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.data_length, FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.picture.data, metadata->data.picture.data_length))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.unknown.data, metadata->length))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(bw));
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWriter *bw)
|
||||
{
|
||||
unsigned u, blocksize_hint, sample_rate_hint;
|
||||
FLAC__byte crc;
|
||||
|
||||
FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(bw));
|
||||
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__FRAME_HEADER_SYNC, FLAC__FRAME_HEADER_SYNC_LEN))
|
||||
return false;
|
||||
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_RESERVED_LEN))
|
||||
return false;
|
||||
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, (header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER)? 0 : 1, FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN))
|
||||
return false;
|
||||
|
||||
FLAC__ASSERT(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE);
|
||||
/* when this assertion holds true, any legal blocksize can be expressed in the frame header */
|
||||
FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535u);
|
||||
blocksize_hint = 0;
|
||||
switch(header->blocksize) {
|
||||
case 192: u = 1; break;
|
||||
case 576: u = 2; break;
|
||||
case 1152: u = 3; break;
|
||||
case 2304: u = 4; break;
|
||||
case 4608: u = 5; break;
|
||||
case 256: u = 8; break;
|
||||
case 512: u = 9; break;
|
||||
case 1024: u = 10; break;
|
||||
case 2048: u = 11; break;
|
||||
case 4096: u = 12; break;
|
||||
case 8192: u = 13; break;
|
||||
case 16384: u = 14; break;
|
||||
case 32768: u = 15; break;
|
||||
default:
|
||||
if(header->blocksize <= 0x100)
|
||||
blocksize_hint = u = 6;
|
||||
else
|
||||
blocksize_hint = u = 7;
|
||||
break;
|
||||
}
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BLOCK_SIZE_LEN))
|
||||
return false;
|
||||
|
||||
FLAC__ASSERT(FLAC__format_sample_rate_is_valid(header->sample_rate));
|
||||
sample_rate_hint = 0;
|
||||
switch(header->sample_rate) {
|
||||
case 88200: u = 1; break;
|
||||
case 176400: u = 2; break;
|
||||
case 192000: u = 3; break;
|
||||
case 8000: u = 4; break;
|
||||
case 16000: u = 5; break;
|
||||
case 22050: u = 6; break;
|
||||
case 24000: u = 7; break;
|
||||
case 32000: u = 8; break;
|
||||
case 44100: u = 9; break;
|
||||
case 48000: u = 10; break;
|
||||
case 96000: u = 11; break;
|
||||
default:
|
||||
if(header->sample_rate <= 255000 && header->sample_rate % 1000 == 0)
|
||||
sample_rate_hint = u = 12;
|
||||
else if(header->sample_rate % 10 == 0)
|
||||
sample_rate_hint = u = 14;
|
||||
else if(header->sample_rate <= 0xffff)
|
||||
sample_rate_hint = u = 13;
|
||||
else
|
||||
u = 0;
|
||||
break;
|
||||
}
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_SAMPLE_RATE_LEN))
|
||||
return false;
|
||||
|
||||
FLAC__ASSERT(header->channels > 0 && header->channels <= (1u << FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN) && header->channels <= FLAC__MAX_CHANNELS);
|
||||
switch(header->channel_assignment) {
|
||||
case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
|
||||
u = header->channels - 1;
|
||||
break;
|
||||
case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
|
||||
FLAC__ASSERT(header->channels == 2);
|
||||
u = 8;
|
||||
break;
|
||||
case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
|
||||
FLAC__ASSERT(header->channels == 2);
|
||||
u = 9;
|
||||
break;
|
||||
case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
|
||||
FLAC__ASSERT(header->channels == 2);
|
||||
u = 10;
|
||||
break;
|
||||
default:
|
||||
FLAC__ASSERT(0);
|
||||
}
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN))
|
||||
return false;
|
||||
|
||||
FLAC__ASSERT(header->bits_per_sample > 0 && header->bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN));
|
||||
switch(header->bits_per_sample) {
|
||||
case 8 : u = 1; break;
|
||||
case 12: u = 2; break;
|
||||
case 16: u = 4; break;
|
||||
case 20: u = 5; break;
|
||||
case 24: u = 6; break;
|
||||
default: u = 0; break;
|
||||
}
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN))
|
||||
return false;
|
||||
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_ZERO_PAD_LEN))
|
||||
return false;
|
||||
|
||||
if(header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) {
|
||||
if(!FLAC__bitwriter_write_utf8_uint32(bw, header->number.frame_number))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(!FLAC__bitwriter_write_utf8_uint64(bw, header->number.sample_number))
|
||||
return false;
|
||||
}
|
||||
|
||||
if(blocksize_hint)
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, header->blocksize-1, (blocksize_hint==6)? 8:16))
|
||||
return false;
|
||||
|
||||
switch(sample_rate_hint) {
|
||||
case 12:
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate / 1000, 8))
|
||||
return false;
|
||||
break;
|
||||
case 13:
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate, 16))
|
||||
return false;
|
||||
break;
|
||||
case 14:
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate / 10, 16))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
/* write the CRC */
|
||||
if(!FLAC__bitwriter_get_write_crc8(bw, &crc))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, crc, FLAC__FRAME_HEADER_CRC_LEN))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw)
|
||||
{
|
||||
FLAC__bool ok;
|
||||
|
||||
ok =
|
||||
FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN) &&
|
||||
(wasted_bits? FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1) : true) &&
|
||||
FLAC__bitwriter_write_raw_int32(bw, subframe->value, subframe_bps)
|
||||
;
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK | (subframe->order<<1) | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN))
|
||||
return false;
|
||||
if(wasted_bits)
|
||||
if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1))
|
||||
return false;
|
||||
|
||||
for(i = 0; i < subframe->order; i++)
|
||||
if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps))
|
||||
return false;
|
||||
|
||||
if(!add_entropy_coding_method_(bw, &subframe->entropy_coding_method))
|
||||
return false;
|
||||
switch(subframe->entropy_coding_method.type) {
|
||||
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
|
||||
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
|
||||
if(!add_residual_partitioned_rice_(
|
||||
bw,
|
||||
subframe->residual,
|
||||
residual_samples,
|
||||
subframe->order,
|
||||
subframe->entropy_coding_method.data.partitioned_rice.contents->parameters,
|
||||
subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits,
|
||||
subframe->entropy_coding_method.data.partitioned_rice.order,
|
||||
/*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2
|
||||
))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
FLAC__ASSERT(0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK | ((subframe->order-1)<<1) | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN))
|
||||
return false;
|
||||
if(wasted_bits)
|
||||
if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1))
|
||||
return false;
|
||||
|
||||
for(i = 0; i < subframe->order; i++)
|
||||
if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps))
|
||||
return false;
|
||||
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, subframe->qlp_coeff_precision-1, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_int32(bw, subframe->quantization_level, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN))
|
||||
return false;
|
||||
for(i = 0; i < subframe->order; i++)
|
||||
if(!FLAC__bitwriter_write_raw_int32(bw, subframe->qlp_coeff[i], subframe->qlp_coeff_precision))
|
||||
return false;
|
||||
|
||||
if(!add_entropy_coding_method_(bw, &subframe->entropy_coding_method))
|
||||
return false;
|
||||
switch(subframe->entropy_coding_method.type) {
|
||||
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
|
||||
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
|
||||
if(!add_residual_partitioned_rice_(
|
||||
bw,
|
||||
subframe->residual,
|
||||
residual_samples,
|
||||
subframe->order,
|
||||
subframe->entropy_coding_method.data.partitioned_rice.contents->parameters,
|
||||
subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits,
|
||||
subframe->entropy_coding_method.data.partitioned_rice.order,
|
||||
/*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2
|
||||
))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
FLAC__ASSERT(0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, unsigned samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw)
|
||||
{
|
||||
unsigned i;
|
||||
const FLAC__int32 *signal = subframe->data;
|
||||
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN))
|
||||
return false;
|
||||
if(wasted_bits)
|
||||
if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1))
|
||||
return false;
|
||||
|
||||
for(i = 0; i < samples; i++)
|
||||
if(!FLAC__bitwriter_write_raw_int32(bw, signal[i], subframe_bps))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCodingMethod *method)
|
||||
{
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, method->type, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN))
|
||||
return false;
|
||||
switch(method->type) {
|
||||
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
|
||||
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, method->data.partitioned_rice.order, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
FLAC__ASSERT(0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order, const FLAC__bool is_extended)
|
||||
{
|
||||
const unsigned plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
|
||||
const unsigned pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
|
||||
|
||||
if(partition_order == 0) {
|
||||
unsigned i;
|
||||
|
||||
if(raw_bits[0] == 0) {
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[0], plen))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_rice_signed_block(bw, residual, residual_samples, rice_parameters[0]))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
FLAC__ASSERT(rice_parameters[0] == 0);
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, pesc, plen))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN))
|
||||
return false;
|
||||
for(i = 0; i < residual_samples; i++) {
|
||||
if(!FLAC__bitwriter_write_raw_int32(bw, residual[i], raw_bits[0]))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
unsigned i, j, k = 0, k_last = 0;
|
||||
unsigned partition_samples;
|
||||
const unsigned default_partition_samples = (residual_samples+predictor_order) >> partition_order;
|
||||
for(i = 0; i < (1u<<partition_order); i++) {
|
||||
partition_samples = default_partition_samples;
|
||||
if(i == 0)
|
||||
partition_samples -= predictor_order;
|
||||
k += partition_samples;
|
||||
if(raw_bits[i] == 0) {
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[i], plen))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_rice_signed_block(bw, residual+k_last, k-k_last, rice_parameters[i]))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, pesc, plen))
|
||||
return false;
|
||||
if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[i], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN))
|
||||
return false;
|
||||
for(j = k_last; j < k; j++) {
|
||||
if(!FLAC__bitwriter_write_raw_int32(bw, residual[j], raw_bits[i]))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
k_last = k;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
142
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/stream_encoder_intrin_avx2.c
vendored
Normal file
142
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/stream_encoder_intrin_avx2.c
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifndef FLAC__NO_ASM
|
||||
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
|
||||
#include "private/stream_encoder.h"
|
||||
#include "private/bitmath.h"
|
||||
#ifdef FLAC__AVX2_SUPPORTED
|
||||
|
||||
#include <stdlib.h> /* for abs() */
|
||||
#include <immintrin.h> /* AVX2 */
|
||||
#include "FLAC/assert.h"
|
||||
|
||||
FLAC__SSE_TARGET("avx2")
|
||||
void FLAC__precompute_partition_info_sums_intrin_avx2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[],
|
||||
unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps)
|
||||
{
|
||||
const unsigned default_partition_samples = (residual_samples + predictor_order) >> max_partition_order;
|
||||
unsigned partitions = 1u << max_partition_order;
|
||||
|
||||
FLAC__ASSERT(default_partition_samples > predictor_order);
|
||||
|
||||
/* first do max_partition_order */
|
||||
{
|
||||
unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order);
|
||||
__m256i res256, sum256;
|
||||
__m128i res128, sum128;
|
||||
|
||||
if(FLAC__bitmath_ilog2(default_partition_samples) + bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < 32) {
|
||||
for(partition = residual_sample = 0; partition < partitions; partition++) {
|
||||
end += default_partition_samples;
|
||||
sum256 = _mm256_setzero_si256();
|
||||
|
||||
for( ; (int)residual_sample < (int)end-7; residual_sample+=8) {
|
||||
res256 = _mm256_abs_epi32(_mm256_loadu_si256((const __m256i*)(residual+residual_sample)));
|
||||
sum256 = _mm256_add_epi32(sum256, res256);
|
||||
}
|
||||
|
||||
sum128 = _mm_add_epi32(_mm256_extracti128_si256(sum256, 1), _mm256_castsi256_si128(sum256));
|
||||
|
||||
for( ; (int)residual_sample < (int)end-3; residual_sample+=4) {
|
||||
res128 = _mm_abs_epi32(_mm_loadu_si128((const __m128i*)(residual+residual_sample)));
|
||||
sum128 = _mm_add_epi32(sum128, res128);
|
||||
}
|
||||
|
||||
for( ; residual_sample < end; residual_sample++) {
|
||||
res128 = _mm_cvtsi32_si128(residual[residual_sample]);
|
||||
res128 = _mm_abs_epi32(res128);
|
||||
sum128 = _mm_add_epi32(sum128, res128);
|
||||
}
|
||||
|
||||
sum128 = _mm_hadd_epi32(sum128, sum128);
|
||||
sum128 = _mm_hadd_epi32(sum128, sum128);
|
||||
abs_residual_partition_sums[partition] = (FLAC__uint32)_mm_cvtsi128_si32(sum128);
|
||||
}
|
||||
}
|
||||
else { /* have to pessimistically use 64 bits for accumulator */
|
||||
for(partition = residual_sample = 0; partition < partitions; partition++) {
|
||||
end += default_partition_samples;
|
||||
sum256 = _mm256_setzero_si256();
|
||||
|
||||
for( ; (int)residual_sample < (int)end-3; residual_sample+=4) {
|
||||
res128 = _mm_abs_epi32(_mm_loadu_si128((const __m128i*)(residual+residual_sample)));
|
||||
res256 = _mm256_cvtepu32_epi64(res128);
|
||||
sum256 = _mm256_add_epi64(sum256, res256);
|
||||
}
|
||||
|
||||
sum128 = _mm_add_epi64(_mm256_extracti128_si256(sum256, 1), _mm256_castsi256_si128(sum256));
|
||||
|
||||
for( ; (int)residual_sample < (int)end-1; residual_sample+=2) {
|
||||
res128 = _mm_loadl_epi64((const __m128i*)(residual+residual_sample));
|
||||
res128 = _mm_abs_epi32(res128);
|
||||
res128 = _mm_cvtepu32_epi64(res128);
|
||||
sum128 = _mm_add_epi64(sum128, res128);
|
||||
}
|
||||
|
||||
for( ; residual_sample < end; residual_sample++) {
|
||||
res128 = _mm_cvtsi32_si128(residual[residual_sample]);
|
||||
res128 = _mm_abs_epi32(res128);
|
||||
sum128 = _mm_add_epi64(sum128, res128);
|
||||
}
|
||||
|
||||
sum128 = _mm_add_epi64(sum128, _mm_srli_si128(sum128, 8));
|
||||
_mm_storel_epi64((__m128i*)(abs_residual_partition_sums+partition), sum128);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* now merge partitions for lower orders */
|
||||
{
|
||||
unsigned from_partition = 0, to_partition = partitions;
|
||||
int partition_order;
|
||||
for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) {
|
||||
unsigned i;
|
||||
partitions >>= 1;
|
||||
for(i = 0; i < partitions; i++) {
|
||||
abs_residual_partition_sums[to_partition++] =
|
||||
abs_residual_partition_sums[from_partition ] +
|
||||
abs_residual_partition_sums[from_partition+1];
|
||||
from_partition += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
_mm256_zeroupper();
|
||||
}
|
||||
|
||||
#endif /* FLAC__AVX2_SUPPORTED */
|
||||
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
|
||||
#endif /* FLAC__NO_ASM */
|
||||
159
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/stream_encoder_intrin_sse2.c
vendored
Normal file
159
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/stream_encoder_intrin_sse2.c
vendored
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifndef FLAC__NO_ASM
|
||||
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
|
||||
#include "private/stream_encoder.h"
|
||||
#include "private/bitmath.h"
|
||||
#ifdef FLAC__SSE2_SUPPORTED
|
||||
|
||||
#include <stdlib.h> /* for abs() */
|
||||
#include <emmintrin.h> /* SSE2 */
|
||||
#include "FLAC/assert.h"
|
||||
|
||||
FLAC__SSE_TARGET("sse2")
|
||||
void FLAC__precompute_partition_info_sums_intrin_sse2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[],
|
||||
unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps)
|
||||
{
|
||||
const unsigned default_partition_samples = (residual_samples + predictor_order) >> max_partition_order;
|
||||
unsigned partitions = 1u << max_partition_order;
|
||||
|
||||
FLAC__ASSERT(default_partition_samples > predictor_order);
|
||||
|
||||
/* first do max_partition_order */
|
||||
{
|
||||
unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order);
|
||||
unsigned e1, e3;
|
||||
__m128i mm_res, mm_sum, mm_mask;
|
||||
|
||||
if(FLAC__bitmath_ilog2(default_partition_samples) + bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < 32) {
|
||||
for(partition = residual_sample = 0; partition < partitions; partition++) {
|
||||
end += default_partition_samples;
|
||||
mm_sum = _mm_setzero_si128();
|
||||
|
||||
e1 = (residual_sample + 3) & ~3; e3 = end & ~3;
|
||||
if(e1 > end)
|
||||
e1 = end; /* try flac -l 1 -b 16 and you'll be here */
|
||||
|
||||
/* assumption: residual[] is properly aligned so (residual + e1) is properly aligned too and _mm_loadu_si128() is fast */
|
||||
for( ; residual_sample < e1; residual_sample++) {
|
||||
mm_res = _mm_cvtsi32_si128(residual[residual_sample]);
|
||||
mm_mask = _mm_srai_epi32(mm_res, 31);
|
||||
mm_res = _mm_xor_si128(mm_res, mm_mask);
|
||||
mm_res = _mm_sub_epi32(mm_res, mm_mask); /* abs(INT_MIN) is undefined, but if the residual is INT_MIN we have bigger problems */
|
||||
mm_sum = _mm_add_epi32(mm_sum, mm_res);
|
||||
}
|
||||
|
||||
for( ; residual_sample < e3; residual_sample+=4) {
|
||||
mm_res = _mm_loadu_si128((const __m128i*)(residual+residual_sample));
|
||||
mm_mask = _mm_srai_epi32(mm_res, 31);
|
||||
mm_res = _mm_xor_si128(mm_res, mm_mask);
|
||||
mm_res = _mm_sub_epi32(mm_res, mm_mask);
|
||||
mm_sum = _mm_add_epi32(mm_sum, mm_res);
|
||||
}
|
||||
|
||||
for( ; residual_sample < end; residual_sample++) {
|
||||
mm_res = _mm_cvtsi32_si128(residual[residual_sample]);
|
||||
mm_mask = _mm_srai_epi32(mm_res, 31);
|
||||
mm_res = _mm_xor_si128(mm_res, mm_mask);
|
||||
mm_res = _mm_sub_epi32(mm_res, mm_mask);
|
||||
mm_sum = _mm_add_epi32(mm_sum, mm_res);
|
||||
}
|
||||
|
||||
mm_sum = _mm_add_epi32(mm_sum, _mm_srli_si128(mm_sum, 8));
|
||||
mm_sum = _mm_add_epi32(mm_sum, _mm_srli_si128(mm_sum, 4));
|
||||
abs_residual_partition_sums[partition] = (FLAC__uint32)_mm_cvtsi128_si32(mm_sum);
|
||||
}
|
||||
}
|
||||
else { /* have to pessimistically use 64 bits for accumulator */
|
||||
for(partition = residual_sample = 0; partition < partitions; partition++) {
|
||||
end += default_partition_samples;
|
||||
mm_sum = _mm_setzero_si128();
|
||||
|
||||
e1 = (residual_sample + 1) & ~1; e3 = end & ~1;
|
||||
FLAC__ASSERT(e1 <= end);
|
||||
|
||||
for( ; residual_sample < e1; residual_sample++) {
|
||||
mm_res = _mm_cvtsi32_si128(residual[residual_sample]); /* 0 0 0 r0 */
|
||||
mm_mask = _mm_srai_epi32(mm_res, 31);
|
||||
mm_res = _mm_xor_si128(mm_res, mm_mask);
|
||||
mm_res = _mm_sub_epi32(mm_res, mm_mask); /* 0 0 0 |r0| == 00 |r0_64| */
|
||||
mm_sum = _mm_add_epi64(mm_sum, mm_res);
|
||||
}
|
||||
|
||||
for( ; residual_sample < e3; residual_sample+=2) {
|
||||
mm_res = _mm_loadl_epi64((const __m128i*)(residual+residual_sample)); /* 0 0 r1 r0 */
|
||||
mm_mask = _mm_srai_epi32(mm_res, 31);
|
||||
mm_res = _mm_xor_si128(mm_res, mm_mask);
|
||||
mm_res = _mm_sub_epi32(mm_res, mm_mask); /* 0 0 |r1| |r0| */
|
||||
mm_res = _mm_shuffle_epi32(mm_res, _MM_SHUFFLE(3,1,2,0)); /* 0 |r1| 0 |r0| == |r1_64| |r0_64| */
|
||||
mm_sum = _mm_add_epi64(mm_sum, mm_res);
|
||||
}
|
||||
|
||||
for( ; residual_sample < end; residual_sample++) {
|
||||
mm_res = _mm_cvtsi32_si128(residual[residual_sample]);
|
||||
mm_mask = _mm_srai_epi32(mm_res, 31);
|
||||
mm_res = _mm_xor_si128(mm_res, mm_mask);
|
||||
mm_res = _mm_sub_epi32(mm_res, mm_mask);
|
||||
mm_sum = _mm_add_epi64(mm_sum, mm_res);
|
||||
}
|
||||
|
||||
mm_sum = _mm_add_epi64(mm_sum, _mm_srli_si128(mm_sum, 8));
|
||||
_mm_storel_epi64((__m128i*)(abs_residual_partition_sums+partition), mm_sum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* now merge partitions for lower orders */
|
||||
{
|
||||
unsigned from_partition = 0, to_partition = partitions;
|
||||
int partition_order;
|
||||
for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) {
|
||||
unsigned i;
|
||||
partitions >>= 1;
|
||||
for(i = 0; i < partitions; i++) {
|
||||
abs_residual_partition_sums[to_partition++] =
|
||||
abs_residual_partition_sums[from_partition ] +
|
||||
abs_residual_partition_sums[from_partition+1];
|
||||
from_partition += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FLAC__SSE2_SUPPORTED */
|
||||
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
|
||||
#endif /* FLAC__NO_ASM */
|
||||
147
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/stream_encoder_intrin_ssse3.c
vendored
Normal file
147
sources/LabSound/third_party/libnyquist/third_party/FLAC/src/stream_encoder_intrin_ssse3.c
vendored
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifndef FLAC__NO_ASM
|
||||
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
|
||||
#include "private/stream_encoder.h"
|
||||
#include "private/bitmath.h"
|
||||
#ifdef FLAC__SSSE3_SUPPORTED
|
||||
|
||||
#include <stdlib.h> /* for abs() */
|
||||
#include <tmmintrin.h> /* SSSE3 */
|
||||
#include "FLAC/assert.h"
|
||||
|
||||
FLAC__SSE_TARGET("ssse3")
|
||||
void FLAC__precompute_partition_info_sums_intrin_ssse3(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[],
|
||||
unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps)
|
||||
{
|
||||
const unsigned default_partition_samples = (residual_samples + predictor_order) >> max_partition_order;
|
||||
unsigned partitions = 1u << max_partition_order;
|
||||
|
||||
FLAC__ASSERT(default_partition_samples > predictor_order);
|
||||
|
||||
/* first do max_partition_order */
|
||||
{
|
||||
unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order);
|
||||
unsigned e1, e3;
|
||||
__m128i mm_res, mm_sum;
|
||||
|
||||
if(FLAC__bitmath_ilog2(default_partition_samples) + bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < 32) {
|
||||
for(partition = residual_sample = 0; partition < partitions; partition++) {
|
||||
end += default_partition_samples;
|
||||
mm_sum = _mm_setzero_si128();
|
||||
|
||||
e1 = (residual_sample + 3) & ~3; e3 = end & ~3;
|
||||
if(e1 > end)
|
||||
e1 = end; /* try flac -l 1 -b 16 and you'll be here */
|
||||
|
||||
/* assumption: residual[] is properly aligned so (residual + e1) is properly aligned too and _mm_loadu_si128() is fast */
|
||||
for( ; residual_sample < e1; residual_sample++) {
|
||||
mm_res = _mm_cvtsi32_si128(residual[residual_sample]);
|
||||
mm_res = _mm_abs_epi32(mm_res); /* abs(INT_MIN) is undefined, but if the residual is INT_MIN we have bigger problems */
|
||||
mm_sum = _mm_add_epi32(mm_sum, mm_res);
|
||||
}
|
||||
|
||||
for( ; residual_sample < e3; residual_sample+=4) {
|
||||
mm_res = _mm_loadu_si128((const __m128i*)(residual+residual_sample));
|
||||
mm_res = _mm_abs_epi32(mm_res);
|
||||
mm_sum = _mm_add_epi32(mm_sum, mm_res);
|
||||
}
|
||||
|
||||
for( ; residual_sample < end; residual_sample++) {
|
||||
mm_res = _mm_cvtsi32_si128(residual[residual_sample]);
|
||||
mm_res = _mm_abs_epi32(mm_res);
|
||||
mm_sum = _mm_add_epi32(mm_sum, mm_res);
|
||||
}
|
||||
|
||||
mm_sum = _mm_hadd_epi32(mm_sum, mm_sum);
|
||||
mm_sum = _mm_hadd_epi32(mm_sum, mm_sum);
|
||||
abs_residual_partition_sums[partition] = (FLAC__uint32)_mm_cvtsi128_si32(mm_sum);
|
||||
}
|
||||
}
|
||||
else { /* have to pessimistically use 64 bits for accumulator */
|
||||
for(partition = residual_sample = 0; partition < partitions; partition++) {
|
||||
end += default_partition_samples;
|
||||
mm_sum = _mm_setzero_si128();
|
||||
|
||||
e1 = (residual_sample + 1) & ~1; e3 = end & ~1;
|
||||
FLAC__ASSERT(e1 <= end);
|
||||
|
||||
for( ; residual_sample < e1; residual_sample++) {
|
||||
mm_res = _mm_cvtsi32_si128(residual[residual_sample]); /* 0 0 0 r0 */
|
||||
mm_res = _mm_abs_epi32(mm_res); /* 0 0 0 |r0| == 00 |r0_64| */
|
||||
mm_sum = _mm_add_epi64(mm_sum, mm_res);
|
||||
}
|
||||
|
||||
for( ; residual_sample < e3; residual_sample+=2) {
|
||||
mm_res = _mm_loadl_epi64((const __m128i*)(residual+residual_sample)); /* 0 0 r1 r0 */
|
||||
mm_res = _mm_abs_epi32(mm_res); /* 0 0 |r1| |r0| */
|
||||
mm_res = _mm_shuffle_epi32(mm_res, _MM_SHUFFLE(3,1,2,0)); /* 0 |r1| 0 |r0| == |r1_64| |r0_64| */
|
||||
mm_sum = _mm_add_epi64(mm_sum, mm_res);
|
||||
}
|
||||
|
||||
for( ; residual_sample < end; residual_sample++) {
|
||||
mm_res = _mm_cvtsi32_si128(residual[residual_sample]);
|
||||
mm_res = _mm_abs_epi32(mm_res);
|
||||
mm_sum = _mm_add_epi64(mm_sum, mm_res);
|
||||
}
|
||||
|
||||
mm_sum = _mm_add_epi64(mm_sum, _mm_srli_si128(mm_sum, 8));
|
||||
_mm_storel_epi64((__m128i*)(abs_residual_partition_sums+partition), mm_sum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* now merge partitions for lower orders */
|
||||
{
|
||||
unsigned from_partition = 0, to_partition = partitions;
|
||||
int partition_order;
|
||||
for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) {
|
||||
unsigned i;
|
||||
partitions >>= 1;
|
||||
for(i = 0; i < partitions; i++) {
|
||||
abs_residual_partition_sums[to_partition++] =
|
||||
abs_residual_partition_sums[from_partition ] +
|
||||
abs_residual_partition_sums[from_partition+1];
|
||||
from_partition += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FLAC__SSSE3_SUPPORTED */
|
||||
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
|
||||
#endif /* FLAC__NO_ASM */
|
||||
|
|
@ -0,0 +1,373 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2013-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/utime.h>
|
||||
#include <io.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h> /* for WideCharToMultiByte and MultiByteToWideChar */
|
||||
|
||||
#include "share/win_utf8_io.h"
|
||||
|
||||
#define UTF8_BUFFER_SIZE 32768
|
||||
|
||||
static
|
||||
int local_vsnprintf(char *str, size_t size, const char *fmt, va_list va)
|
||||
{
|
||||
int rc;
|
||||
|
||||
#if defined _MSC_VER
|
||||
if (size == 0)
|
||||
return 1024;
|
||||
rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va);
|
||||
if (rc < 0)
|
||||
rc = size - 1;
|
||||
#elif defined __MINGW32__
|
||||
rc = __mingw_vsnprintf (str, size, fmt, va);
|
||||
#else
|
||||
rc = vsnprintf (str, size, fmt, va);
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static UINT win_utf8_io_codepage = CP_ACP;
|
||||
|
||||
/* convert WCHAR stored Unicode string to UTF-8. Caller is responsible for freeing memory */
|
||||
static
|
||||
char *utf8_from_wchar(const wchar_t *wstr)
|
||||
{
|
||||
char *utf8str;
|
||||
int len;
|
||||
|
||||
if (!wstr) return NULL;
|
||||
if ((len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL)) == 0) return NULL;
|
||||
if ((utf8str = (char *)malloc(++len)) == NULL) return NULL;
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, wstr, -1, utf8str, len, NULL, NULL) == 0) {
|
||||
free(utf8str);
|
||||
utf8str = NULL;
|
||||
}
|
||||
|
||||
return utf8str;
|
||||
}
|
||||
|
||||
/* convert UTF-8 back to WCHAR. Caller is responsible for freeing memory */
|
||||
static
|
||||
wchar_t *wchar_from_utf8(const char *str)
|
||||
{
|
||||
wchar_t *widestr;
|
||||
int len;
|
||||
|
||||
if (!str) return NULL;
|
||||
len=(int)strlen(str)+1;
|
||||
if ((widestr = (wchar_t *)malloc(len*sizeof(wchar_t))) != NULL) {
|
||||
if (MultiByteToWideChar(win_utf8_io_codepage, 0, str, len, widestr, len) == 0) {
|
||||
if (MultiByteToWideChar(CP_ACP, 0, str, len, widestr, len) == 0) { /* try conversion from Ansi in case the initial UTF-8 conversion had failed */
|
||||
free(widestr);
|
||||
widestr = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return widestr;
|
||||
}
|
||||
|
||||
/* retrieve WCHAR commandline, expand wildcards and convert everything to UTF-8 */
|
||||
int get_utf8_argv(int *argc, char ***argv)
|
||||
{
|
||||
typedef int (__cdecl *wgetmainargs_t)(int*, wchar_t***, wchar_t***, int, int*);
|
||||
wgetmainargs_t wgetmainargs;
|
||||
HMODULE handle;
|
||||
int wargc;
|
||||
wchar_t **wargv;
|
||||
wchar_t **wenv;
|
||||
char **utf8argv;
|
||||
int ret, i;
|
||||
|
||||
if ((handle = LoadLibrary("msvcrt.dll")) == NULL) return 1;
|
||||
if ((wgetmainargs = (wgetmainargs_t)GetProcAddress(handle, "__wgetmainargs")) == NULL) return 1;
|
||||
i = 0;
|
||||
/* if __wgetmainargs expands wildcards then it also erroneously converts \\?\c:\path\to\file.flac to \\file.flac */
|
||||
if (wgetmainargs(&wargc, &wargv, &wenv, 1, &i) != 0) return 1;
|
||||
if ((utf8argv = (char **)calloc(wargc, sizeof(char*))) == NULL) return 1;
|
||||
ret = 0;
|
||||
|
||||
for (i=0; i<wargc; i++) {
|
||||
if ((utf8argv[i] = utf8_from_wchar(wargv[i])) == NULL) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FreeLibrary(handle);
|
||||
|
||||
if (ret == 0) {
|
||||
win_utf8_io_codepage = CP_UTF8;
|
||||
*argc = wargc;
|
||||
*argv = utf8argv;
|
||||
} else {
|
||||
for (i=0; i<wargc; i++)
|
||||
free(utf8argv[i]);
|
||||
free(utf8argv);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* return number of characters in the UTF-8 string */
|
||||
size_t strlen_utf8(const char *str)
|
||||
{
|
||||
size_t len;
|
||||
if ((len = MultiByteToWideChar(win_utf8_io_codepage, 0, str, -1, NULL, 0)) == 0)
|
||||
len = strlen(str);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* get the console width in characters */
|
||||
int win_get_console_width(void)
|
||||
{
|
||||
int width = 80;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (GetConsoleScreenBufferInfo(hOut, &csbi) != 0) width = csbi.dwSize.X;
|
||||
return width;
|
||||
}
|
||||
|
||||
/* print functions */
|
||||
|
||||
int print_console(FILE *stream, const wchar_t *text, size_t len)
|
||||
{
|
||||
static HANDLE hOut;
|
||||
static HANDLE hErr;
|
||||
DWORD out;
|
||||
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
hErr = GetStdHandle(STD_ERROR_HANDLE);
|
||||
if (stream == stdout && hOut != INVALID_HANDLE_VALUE && GetFileType(hOut) == FILE_TYPE_CHAR) {
|
||||
if (WriteConsoleW(hOut, text, len, &out, NULL) == 0) return -1;
|
||||
return out;
|
||||
} else if (stream == stderr && hErr != INVALID_HANDLE_VALUE && GetFileType(hErr) == FILE_TYPE_CHAR) {
|
||||
if (WriteConsoleW(hErr, text, len, &out, NULL) == 0) return -1;
|
||||
return out;
|
||||
} else {
|
||||
int ret = fputws(text, stream);
|
||||
if (ret < 0) return ret;
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
int printf_utf8(const char *format, ...)
|
||||
{
|
||||
char *utmp = NULL;
|
||||
wchar_t *wout = NULL;
|
||||
int ret = -1;
|
||||
|
||||
while (1) {
|
||||
va_list argptr;
|
||||
if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE*sizeof(char)))) break;
|
||||
va_start(argptr, format);
|
||||
ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr);
|
||||
va_end(argptr);
|
||||
if (ret < 0) break;
|
||||
if (!(wout = wchar_from_utf8(utmp))) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
ret = print_console(stdout, wout, wcslen(wout));
|
||||
break;
|
||||
}
|
||||
if (utmp) free(utmp);
|
||||
if (wout) free(wout);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fprintf_utf8(FILE *stream, const char *format, ...)
|
||||
{
|
||||
char *utmp = NULL;
|
||||
wchar_t *wout = NULL;
|
||||
int ret = -1;
|
||||
|
||||
while (1) {
|
||||
va_list argptr;
|
||||
if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE*sizeof(char)))) break;
|
||||
va_start(argptr, format);
|
||||
ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr);
|
||||
va_end(argptr);
|
||||
if (ret < 0) break;
|
||||
if (!(wout = wchar_from_utf8(utmp))) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
ret = print_console(stream, wout, wcslen(wout));
|
||||
break;
|
||||
}
|
||||
if (utmp) free(utmp);
|
||||
if (wout) free(wout);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vfprintf_utf8(FILE *stream, const char *format, va_list argptr)
|
||||
{
|
||||
char *utmp = NULL;
|
||||
wchar_t *wout = NULL;
|
||||
int ret = -1;
|
||||
|
||||
while (1) {
|
||||
if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE*sizeof(char)))) break;
|
||||
if ((ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr)) < 0) break;
|
||||
if (!(wout = wchar_from_utf8(utmp))) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
ret = print_console(stream, wout, wcslen(wout));
|
||||
break;
|
||||
}
|
||||
if (utmp) free(utmp);
|
||||
if (wout) free(wout);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* file functions */
|
||||
|
||||
FILE *fopen_utf8(const char *filename, const char *mode)
|
||||
{
|
||||
wchar_t *wname = NULL;
|
||||
wchar_t *wmode = NULL;
|
||||
FILE *f = NULL;
|
||||
|
||||
while (1) {
|
||||
if (!(wname = wchar_from_utf8(filename))) break;
|
||||
if (!(wmode = wchar_from_utf8(mode))) break;
|
||||
f = _wfopen(wname, wmode);
|
||||
break;
|
||||
}
|
||||
if (wname) free(wname);
|
||||
if (wmode) free(wmode);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
int _stat64_utf8(const char *path, struct __stat64 *buffer)
|
||||
{
|
||||
wchar_t *wpath;
|
||||
int ret;
|
||||
|
||||
if (!(wpath = wchar_from_utf8(path))) return -1;
|
||||
ret = _wstat64(wpath, buffer);
|
||||
free(wpath);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int chmod_utf8(const char *filename, int pmode)
|
||||
{
|
||||
wchar_t *wname;
|
||||
int ret;
|
||||
|
||||
if (!(wname = wchar_from_utf8(filename))) return -1;
|
||||
ret = _wchmod(wname, pmode);
|
||||
free(wname);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int utime_utf8(const char *filename, struct utimbuf *times)
|
||||
{
|
||||
wchar_t *wname;
|
||||
struct __utimbuf64 ut;
|
||||
int ret;
|
||||
|
||||
if (sizeof(*times) == sizeof(ut)) {
|
||||
memcpy(&ut, times, sizeof(ut));
|
||||
} else {
|
||||
ut.actime = times->actime;
|
||||
ut.modtime = times->modtime;
|
||||
}
|
||||
|
||||
if (!(wname = wchar_from_utf8(filename))) return -1;
|
||||
ret = _wutime64(wname, &ut);
|
||||
free(wname);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int unlink_utf8(const char *filename)
|
||||
{
|
||||
wchar_t *wname;
|
||||
int ret;
|
||||
|
||||
if (!(wname = wchar_from_utf8(filename))) return -1;
|
||||
ret = _wunlink(wname);
|
||||
free(wname);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rename_utf8(const char *oldname, const char *newname)
|
||||
{
|
||||
wchar_t *wold = NULL;
|
||||
wchar_t *wnew = NULL;
|
||||
int ret = -1;
|
||||
|
||||
while (1) {
|
||||
if (!(wold = wchar_from_utf8(oldname))) break;
|
||||
if (!(wnew = wchar_from_utf8(newname))) break;
|
||||
ret = _wrename(wold, wnew);
|
||||
break;
|
||||
}
|
||||
if (wold) free(wold);
|
||||
if (wnew) free(wnew);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
HANDLE WINAPI CreateFile_utf8(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
|
||||
{
|
||||
wchar_t *wname;
|
||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||
|
||||
if ((wname = wchar_from_utf8(lpFileName)) != NULL) {
|
||||
handle = CreateFileW(wname, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
|
||||
free(wname);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
|
@ -0,0 +1,282 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2006-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2014 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include "share/compat.h"
|
||||
#include "FLAC/assert.h"
|
||||
#include "FLAC/format.h"
|
||||
#include "private/window.h"
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
|
||||
|
||||
void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
if (L & 1) {
|
||||
for (n = 0; n <= N/2; n++)
|
||||
window[n] = 2.0f * n / (float)N;
|
||||
for (; n <= N; n++)
|
||||
window[n] = 2.0f - 2.0f * n / (float)N;
|
||||
}
|
||||
else {
|
||||
for (n = 0; n <= L/2-1; n++)
|
||||
window[n] = 2.0f * n / (float)N;
|
||||
for (; n <= N; n++)
|
||||
window[n] = 2.0f - 2.0f * n / (float)N;
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = (FLAC__real)(0.62f - 0.48f * fabs((float)n/(float)N-0.5f) - 0.38f * cos(2.0f * M_PI * ((float)n/(float)N)));
|
||||
}
|
||||
|
||||
void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = (FLAC__real)(0.42f - 0.5f * cos(2.0f * M_PI * n / N) + 0.08f * cos(4.0f * M_PI * n / N));
|
||||
}
|
||||
|
||||
/* 4-term -92dB side-lobe */
|
||||
void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n <= N; n++)
|
||||
window[n] = (FLAC__real)(0.35875f - 0.48829f * cos(2.0f * M_PI * n / N) + 0.14128f * cos(4.0f * M_PI * n / N) - 0.01168f * cos(6.0f * M_PI * n / N));
|
||||
}
|
||||
|
||||
void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
const double N2 = (double)N / 2.;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n <= N; n++) {
|
||||
double k = ((double)n - N2) / N2;
|
||||
k = 1.0f - k * k;
|
||||
window[n] = (FLAC__real)(k * k);
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = (FLAC__real)(1.0f - 1.93f * cos(2.0f * M_PI * n / N) + 1.29f * cos(4.0f * M_PI * n / N) - 0.388f * cos(6.0f * M_PI * n / N) + 0.0322f * cos(8.0f * M_PI * n / N));
|
||||
}
|
||||
|
||||
void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
const double N2 = (double)N / 2.;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n <= N; n++) {
|
||||
const double k = ((double)n - N2) / (stddev * N2);
|
||||
window[n] = (FLAC__real)exp(-0.5f * k * k);
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = (FLAC__real)(0.54f - 0.46f * cos(2.0f * M_PI * n / N));
|
||||
}
|
||||
|
||||
void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(2.0f * M_PI * n / N));
|
||||
}
|
||||
|
||||
void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = (FLAC__real)(0.402f - 0.498f * cos(2.0f * M_PI * n / N) + 0.098f * cos(4.0f * M_PI * n / N) - 0.001f * cos(6.0f * M_PI * n / N));
|
||||
}
|
||||
|
||||
void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = (FLAC__real)(0.3635819f - 0.4891775f*cos(2.0f*M_PI*n/N) + 0.1365995f*cos(4.0f*M_PI*n/N) - 0.0106411f*cos(6.0f*M_PI*n/N));
|
||||
}
|
||||
|
||||
void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = 1.0f;
|
||||
}
|
||||
|
||||
void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
FLAC__int32 n;
|
||||
|
||||
if (L & 1) {
|
||||
for (n = 1; n <= (L+1)/2; n++)
|
||||
window[n-1] = 2.0f * n / ((float)L + 1.0f);
|
||||
for (; n <= L; n++)
|
||||
window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f);
|
||||
}
|
||||
else {
|
||||
for (n = 1; n <= L/2; n++)
|
||||
window[n-1] = 2.0f * n / ((float)L + 1.0f);
|
||||
for (; n <= L; n++)
|
||||
window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p)
|
||||
{
|
||||
if (p <= 0.0)
|
||||
FLAC__window_rectangle(window, L);
|
||||
else if (p >= 1.0)
|
||||
FLAC__window_hann(window, L);
|
||||
else {
|
||||
const FLAC__int32 Np = (FLAC__int32)(p / 2.0f * L) - 1;
|
||||
FLAC__int32 n;
|
||||
/* start with rectangle... */
|
||||
FLAC__window_rectangle(window, L);
|
||||
/* ...replace ends with hann */
|
||||
if (Np > 0) {
|
||||
for (n = 0; n <= Np; n++) {
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * n / Np));
|
||||
window[L-Np-1+n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * (n+Np) / Np));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end)
|
||||
{
|
||||
const FLAC__int32 start_n = (FLAC__int32)(start * L);
|
||||
const FLAC__int32 end_n = (FLAC__int32)(end * L);
|
||||
const FLAC__int32 N = end_n - start_n;
|
||||
FLAC__int32 Np, n, i;
|
||||
|
||||
if (p <= 0.0f)
|
||||
FLAC__window_partial_tukey(window, L, 0.05f, start, end);
|
||||
else if (p >= 1.0f)
|
||||
FLAC__window_partial_tukey(window, L, 0.95f, start, end);
|
||||
else {
|
||||
|
||||
Np = (FLAC__int32)(p / 2.0f * N);
|
||||
|
||||
for (n = 0; n < start_n && n < L; n++)
|
||||
window[n] = 0.0f;
|
||||
for (i = 1; n < (start_n+Np) && n < L; n++, i++)
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np));
|
||||
for (; n < (end_n-Np) && n < L; n++)
|
||||
window[n] = 1.0f;
|
||||
for (i = Np; n < end_n && n < L; n++, i--)
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np));
|
||||
for (; n < L; n++)
|
||||
window[n] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end)
|
||||
{
|
||||
const FLAC__int32 start_n = (FLAC__int32)(start * L);
|
||||
const FLAC__int32 end_n = (FLAC__int32)(end * L);
|
||||
FLAC__int32 Ns, Ne, n, i;
|
||||
|
||||
if (p <= 0.0f)
|
||||
FLAC__window_punchout_tukey(window, L, 0.05f, start, end);
|
||||
else if (p >= 1.0f)
|
||||
FLAC__window_punchout_tukey(window, L, 0.95f, start, end);
|
||||
else {
|
||||
|
||||
Ns = (FLAC__int32)(p / 2.0f * start_n);
|
||||
Ne = (FLAC__int32)(p / 2.0f * (L - end_n));
|
||||
|
||||
for (n = 0, i = 1; n < Ns && n < L; n++, i++)
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns));
|
||||
for (; n < start_n-Ns && n < L; n++)
|
||||
window[n] = 1.0f;
|
||||
for (i = Ns; n < start_n && n < L; n++, i--)
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns));
|
||||
for (; n < end_n && n < L; n++)
|
||||
window[n] = 0.0f;
|
||||
for (i = 1; n < end_n+Ne && n < L; n++, i++)
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne));
|
||||
for (; n < L - (Ne) && n < L; n++)
|
||||
window[n] = 1.0f;
|
||||
for (i = Ne; n < L; n++, i--)
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne));
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
const double N2 = (double)N / 2.;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n <= N; n++) {
|
||||
const double k = ((double)n - N2) / N2;
|
||||
window[n] = (FLAC__real)(1.0f - k * k);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
210
sources/LabSound/third_party/libnyquist/third_party/libogg/include/ogg/ogg.h
vendored
Normal file
210
sources/LabSound/third_party/libnyquist/third_party/libogg/include/ogg/ogg.h
vendored
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: toplevel libogg include
|
||||
last mod: $Id: ogg.h 18044 2011-08-01 17:55:20Z gmaxwell $
|
||||
|
||||
********************************************************************/
|
||||
#ifndef _OGG_H
|
||||
#define _OGG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <ogg/os_types.h>
|
||||
|
||||
typedef struct {
|
||||
void *iov_base;
|
||||
size_t iov_len;
|
||||
} ogg_iovec_t;
|
||||
|
||||
typedef struct {
|
||||
long endbyte;
|
||||
int endbit;
|
||||
|
||||
unsigned char *buffer;
|
||||
unsigned char *ptr;
|
||||
long storage;
|
||||
} oggpack_buffer;
|
||||
|
||||
/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
|
||||
|
||||
typedef struct {
|
||||
unsigned char *header;
|
||||
long header_len;
|
||||
unsigned char *body;
|
||||
long body_len;
|
||||
} ogg_page;
|
||||
|
||||
/* ogg_stream_state contains the current encode/decode state of a logical
|
||||
Ogg bitstream **********************************************************/
|
||||
|
||||
typedef struct {
|
||||
unsigned char *body_data; /* bytes from packet bodies */
|
||||
long body_storage; /* storage elements allocated */
|
||||
long body_fill; /* elements stored; fill mark */
|
||||
long body_returned; /* elements of fill returned */
|
||||
|
||||
|
||||
int *lacing_vals; /* The values that will go to the segment table */
|
||||
ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact
|
||||
this way, but it is simple coupled to the
|
||||
lacing fifo */
|
||||
long lacing_storage;
|
||||
long lacing_fill;
|
||||
long lacing_packet;
|
||||
long lacing_returned;
|
||||
|
||||
unsigned char header[282]; /* working space for header encode */
|
||||
int header_fill;
|
||||
|
||||
int e_o_s; /* set when we have buffered the last packet in the
|
||||
logical bitstream */
|
||||
int b_o_s; /* set after we've written the initial page
|
||||
of a logical bitstream */
|
||||
long serialno;
|
||||
long pageno;
|
||||
ogg_int64_t packetno; /* sequence number for decode; the framing
|
||||
knows where there's a hole in the data,
|
||||
but we need coupling so that the codec
|
||||
(which is in a separate abstraction
|
||||
layer) also knows about the gap */
|
||||
ogg_int64_t granulepos;
|
||||
|
||||
} ogg_stream_state;
|
||||
|
||||
/* ogg_packet is used to encapsulate the data and metadata belonging
|
||||
to a single raw Ogg/Vorbis packet *************************************/
|
||||
|
||||
typedef struct {
|
||||
unsigned char *packet;
|
||||
long bytes;
|
||||
long b_o_s;
|
||||
long e_o_s;
|
||||
|
||||
ogg_int64_t granulepos;
|
||||
|
||||
ogg_int64_t packetno; /* sequence number for decode; the framing
|
||||
knows where there's a hole in the data,
|
||||
but we need coupling so that the codec
|
||||
(which is in a separate abstraction
|
||||
layer) also knows about the gap */
|
||||
} ogg_packet;
|
||||
|
||||
typedef struct {
|
||||
unsigned char *data;
|
||||
int storage;
|
||||
int fill;
|
||||
int returned;
|
||||
|
||||
int unsynced;
|
||||
int headerbytes;
|
||||
int bodybytes;
|
||||
} ogg_sync_state;
|
||||
|
||||
/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
|
||||
|
||||
extern void oggpack_writeinit(oggpack_buffer *b);
|
||||
extern int oggpack_writecheck(oggpack_buffer *b);
|
||||
extern void oggpack_writetrunc(oggpack_buffer *b,long bits);
|
||||
extern void oggpack_writealign(oggpack_buffer *b);
|
||||
extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits);
|
||||
extern void oggpack_reset(oggpack_buffer *b);
|
||||
extern void oggpack_writeclear(oggpack_buffer *b);
|
||||
extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
|
||||
extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits);
|
||||
extern long oggpack_look(oggpack_buffer *b,int bits);
|
||||
extern long oggpack_look1(oggpack_buffer *b);
|
||||
extern void oggpack_adv(oggpack_buffer *b,int bits);
|
||||
extern void oggpack_adv1(oggpack_buffer *b);
|
||||
extern long oggpack_read(oggpack_buffer *b,int bits);
|
||||
extern long oggpack_read1(oggpack_buffer *b);
|
||||
extern long oggpack_bytes(oggpack_buffer *b);
|
||||
extern long oggpack_bits(oggpack_buffer *b);
|
||||
extern unsigned char *oggpack_get_buffer(oggpack_buffer *b);
|
||||
|
||||
extern void oggpackB_writeinit(oggpack_buffer *b);
|
||||
extern int oggpackB_writecheck(oggpack_buffer *b);
|
||||
extern void oggpackB_writetrunc(oggpack_buffer *b,long bits);
|
||||
extern void oggpackB_writealign(oggpack_buffer *b);
|
||||
extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits);
|
||||
extern void oggpackB_reset(oggpack_buffer *b);
|
||||
extern void oggpackB_writeclear(oggpack_buffer *b);
|
||||
extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
|
||||
extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits);
|
||||
extern long oggpackB_look(oggpack_buffer *b,int bits);
|
||||
extern long oggpackB_look1(oggpack_buffer *b);
|
||||
extern void oggpackB_adv(oggpack_buffer *b,int bits);
|
||||
extern void oggpackB_adv1(oggpack_buffer *b);
|
||||
extern long oggpackB_read(oggpack_buffer *b,int bits);
|
||||
extern long oggpackB_read1(oggpack_buffer *b);
|
||||
extern long oggpackB_bytes(oggpack_buffer *b);
|
||||
extern long oggpackB_bits(oggpack_buffer *b);
|
||||
extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);
|
||||
|
||||
/* Ogg BITSTREAM PRIMITIVES: encoding **************************/
|
||||
|
||||
extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
|
||||
extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov,
|
||||
int count, long e_o_s, ogg_int64_t granulepos);
|
||||
extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
|
||||
extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill);
|
||||
extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
|
||||
extern int ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill);
|
||||
|
||||
/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
|
||||
|
||||
extern int ogg_sync_init(ogg_sync_state *oy);
|
||||
extern int ogg_sync_clear(ogg_sync_state *oy);
|
||||
extern int ogg_sync_reset(ogg_sync_state *oy);
|
||||
extern int ogg_sync_destroy(ogg_sync_state *oy);
|
||||
extern int ogg_sync_check(ogg_sync_state *oy);
|
||||
|
||||
extern char *ogg_sync_buffer(ogg_sync_state *oy, long size);
|
||||
extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes);
|
||||
extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og);
|
||||
extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og);
|
||||
extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og);
|
||||
extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op);
|
||||
extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op);
|
||||
|
||||
/* Ogg BITSTREAM PRIMITIVES: general ***************************/
|
||||
|
||||
extern int ogg_stream_init(ogg_stream_state *os,int serialno);
|
||||
extern int ogg_stream_clear(ogg_stream_state *os);
|
||||
extern int ogg_stream_reset(ogg_stream_state *os);
|
||||
extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno);
|
||||
extern int ogg_stream_destroy(ogg_stream_state *os);
|
||||
extern int ogg_stream_check(ogg_stream_state *os);
|
||||
extern int ogg_stream_eos(ogg_stream_state *os);
|
||||
|
||||
extern void ogg_page_checksum_set(ogg_page *og);
|
||||
|
||||
extern int ogg_page_version(const ogg_page *og);
|
||||
extern int ogg_page_continued(const ogg_page *og);
|
||||
extern int ogg_page_bos(const ogg_page *og);
|
||||
extern int ogg_page_eos(const ogg_page *og);
|
||||
extern ogg_int64_t ogg_page_granulepos(const ogg_page *og);
|
||||
extern int ogg_page_serialno(const ogg_page *og);
|
||||
extern long ogg_page_pageno(const ogg_page *og);
|
||||
extern int ogg_page_packets(const ogg_page *og);
|
||||
|
||||
extern void ogg_packet_clear(ogg_packet *op);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OGG_H */
|
||||
152
sources/LabSound/third_party/libnyquist/third_party/libogg/include/ogg/os_types.h
vendored
Normal file
152
sources/LabSound/third_party/libnyquist/third_party/libogg/include/ogg/os_types.h
vendored
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: #ifdef jail to whip a few platforms into the UNIX ideal.
|
||||
last mod: $Id: os_types.h 19098 2014-02-26 19:06:45Z giles $
|
||||
|
||||
********************************************************************/
|
||||
#ifndef _OS_TYPES_H
|
||||
#define _OS_TYPES_H
|
||||
|
||||
/* make it easy on the folks that want to compile the libs with a
|
||||
different malloc than stdlib */
|
||||
#define _ogg_malloc malloc
|
||||
#define _ogg_calloc calloc
|
||||
#define _ogg_realloc realloc
|
||||
#define _ogg_free free
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
# if defined(__CYGWIN__)
|
||||
# include <stdint.h>
|
||||
typedef int16_t ogg_int16_t;
|
||||
typedef uint16_t ogg_uint16_t;
|
||||
typedef int32_t ogg_int32_t;
|
||||
typedef uint32_t ogg_uint32_t;
|
||||
typedef int64_t ogg_int64_t;
|
||||
typedef uint64_t ogg_uint64_t;
|
||||
# elif defined(__MINGW32__)
|
||||
# include <sys/types.h>
|
||||
typedef short ogg_int16_t;
|
||||
typedef unsigned short ogg_uint16_t;
|
||||
typedef int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef long long ogg_int64_t;
|
||||
typedef unsigned long long ogg_uint64_t;
|
||||
# elif defined(__MWERKS__)
|
||||
typedef long long ogg_int64_t;
|
||||
typedef int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef short ogg_int16_t;
|
||||
typedef unsigned short ogg_uint16_t;
|
||||
# else
|
||||
/* MSVC/Borland */
|
||||
typedef __int64 ogg_int64_t;
|
||||
typedef __int32 ogg_int32_t;
|
||||
typedef unsigned __int32 ogg_uint32_t;
|
||||
typedef __int16 ogg_int16_t;
|
||||
typedef unsigned __int16 ogg_uint16_t;
|
||||
# endif
|
||||
|
||||
#elif defined(__MACOS__)
|
||||
|
||||
# include <sys/types.h>
|
||||
typedef SInt16 ogg_int16_t;
|
||||
typedef UInt16 ogg_uint16_t;
|
||||
typedef SInt32 ogg_int32_t;
|
||||
typedef UInt32 ogg_uint32_t;
|
||||
typedef SInt64 ogg_int64_t;
|
||||
|
||||
#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
|
||||
|
||||
# include <inttypes.h>
|
||||
typedef int16_t ogg_int16_t;
|
||||
typedef uint16_t ogg_uint16_t;
|
||||
typedef int32_t ogg_int32_t;
|
||||
typedef uint32_t ogg_uint32_t;
|
||||
typedef int64_t ogg_int64_t;
|
||||
|
||||
#elif defined(__HAIKU__)
|
||||
|
||||
/* Haiku */
|
||||
# include <sys/types.h>
|
||||
typedef short ogg_int16_t;
|
||||
typedef unsigned short ogg_uint16_t;
|
||||
typedef int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef long long ogg_int64_t;
|
||||
|
||||
#elif defined(__BEOS__)
|
||||
|
||||
/* Be */
|
||||
# include <inttypes.h>
|
||||
typedef int16_t ogg_int16_t;
|
||||
typedef uint16_t ogg_uint16_t;
|
||||
typedef int32_t ogg_int32_t;
|
||||
typedef uint32_t ogg_uint32_t;
|
||||
typedef int64_t ogg_int64_t;
|
||||
|
||||
#elif defined (__EMX__)
|
||||
|
||||
/* OS/2 GCC */
|
||||
typedef short ogg_int16_t;
|
||||
typedef unsigned short ogg_uint16_t;
|
||||
typedef int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef long long ogg_int64_t;
|
||||
|
||||
#elif defined (DJGPP)
|
||||
|
||||
/* DJGPP */
|
||||
typedef short ogg_int16_t;
|
||||
typedef int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef long long ogg_int64_t;
|
||||
|
||||
#elif defined(R5900)
|
||||
|
||||
/* PS2 EE */
|
||||
typedef long ogg_int64_t;
|
||||
typedef int ogg_int32_t;
|
||||
typedef unsigned ogg_uint32_t;
|
||||
typedef short ogg_int16_t;
|
||||
|
||||
#elif defined(__SYMBIAN32__)
|
||||
|
||||
/* Symbian GCC */
|
||||
typedef signed short ogg_int16_t;
|
||||
typedef unsigned short ogg_uint16_t;
|
||||
typedef signed int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef long long int ogg_int64_t;
|
||||
|
||||
#elif defined(__TMS320C6X__)
|
||||
|
||||
/* TI C64x compiler */
|
||||
typedef signed short ogg_int16_t;
|
||||
typedef unsigned short ogg_uint16_t;
|
||||
typedef signed int ogg_int32_t;
|
||||
typedef unsigned int ogg_uint32_t;
|
||||
typedef long long int ogg_int64_t;
|
||||
|
||||
#else
|
||||
|
||||
#include <inttypes.h>
|
||||
typedef int16_t ogg_int16_t;
|
||||
typedef uint16_t ogg_uint16_t;
|
||||
typedef int32_t ogg_int32_t;
|
||||
typedef uint32_t ogg_uint32_t;
|
||||
typedef int64_t ogg_int64_t;
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _OS_TYPES_H */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue