Compare commits

..

1 Commits

Author SHA1 Message Date
dimitri 7db47361cd wip magic number format detection 8 years ago

@ -1,34 +0,0 @@
language: cpp
sudo: true
matrix:
include:
- os: linux
env: CXXFLAGS="-std=c++11"
- os: osx
env: CXXFLAGS="-std=c++11"
install:
# install latest cmake
- |
if [ "$TRAVIS_OS_NAME" == "linux" ]; then
CMAKE_URL="https://cmake.org/files/v3.11/cmake-3.11.1-Linux-x86_64.tar.gz";
mkdir cmake_latest && travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake_latest;
export PATH=$(pwd)/cmake_latest/bin:${PATH};
fi
- |
if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
brew update;
brew uninstall cmake;
brew install cmake;
fi
- which ${CC}
- which ${CXX}
- which cmake
script:
- mkdir build
- cd build
- cmake -DBUILD_EXAMPLE=FALSE ..
- cmake --build .

@ -1,296 +0,0 @@
cmake_minimum_required(VERSION 3.13)
set(LIBNYQUIST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}")
set(CMAKE_MODULE_PATH ${LIBNYQUIST_ROOT}/cmake)
include(CXXhelpers)
if (CMAKE_OSX_ARCHITECTURES)
if(CMAKE_OSX_SYSROOT MATCHES ".*iphoneos.*")
# RtAudio is not portable to ios currently
option(BUILD_EXAMPLE "Build example application" OFF)
else()
option(BUILD_EXAMPLE "Build example application" ON)
endif()
else()
option(BUILD_EXAMPLE "Build example application" ON)
endif()
#-------------------------------------------------------------------------------
# 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 STATIC
${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()

@ -237,3 +237,29 @@ 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.
Catch (Boost)
===============================================================================
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute, execute,
and transmit the Software, and to prepare derivative works of the Software,
and to permit third-parties to whom the Software is furnished to do so, all
subject to the following:
The copyright notices in the Software and this entire statement, including the
above license grant, this restriction and the following disclaimer, must be
included in all copies of the Software, in whole or in part, and all
derivative works of the Software, unless such copies or derivative works are
solely in the form of machine-executable object code generated by a source
language processor.
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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR
ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

@ -1,4 +1,4 @@
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:

@ -1,14 +1,10 @@
# Libnyquist
[![Build status](https://ci.appveyor.com/api/projects/status/2xeuyuxy618ndf4r?svg=true)](https://ci.appveyor.com/project/ddiakopoulos/libnyquist)
Platform | Build Status |
-------- | ------------ |
Microsoft VS2017 x64 | [![Build status](https://ci.appveyor.com/api/projects/status/2xeuyuxy618ndf4r?svg=true)](https://ci.appveyor.com/project/ddiakopoulos/libnyquist) |
Clang (OSX) & GCC (Linux) | [![Build Status](https://travis-ci.org/ddiakopoulos/libnyquist.svg?branch=master)](https://travis-ci.org/ddiakopoulos/libnyquist) |
Libnyquist is a small C++11 library for reading sampled audio data from disk or memory. It's ideal to use as an audio asset frontend for games, audio sequencers, music players, and more.
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.
The library steers away from patent or GPL license encumbered formats (such as MP3 and 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).
@ -16,15 +12,24 @@ While untested, there are no technical conditions that preclude compilation on o
## 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.
Regardless of input bit depth, the library hands over an interleaved float array, normalized between [-1.0,+1.0]. At present, the library does not provide resampling functionality.
* Wave (+ IMA-ADPCM encoding)
* MP3
* Ogg Vorbis
* Ogg Opus
* FLAC
* WavPack
* Musepack
* [MIDI files (with soundfonts)](midi-playback.md)
* libmodplug formats (669, amf, ams, dbm, dmf, dsm, far, it, j2b, mdl, med, mod, mt2, mtm, okt, pat, psm, ptm, s3m, stm, ult, umx, xm)
## Encoding
Simple but robust WAV format encoder now included. Extentions in the near future might include Ogg.
## Supported Project Files
* Visual Studio 2013
* Visual Studio 2015
* XCode 6
## Known Issues & Bugs
* See the Github issue tracker.

@ -2,12 +2,12 @@
# http://www.appveyor.com/docs/appveyor-yml
os: Visual Studio 2017
environment:
VisualStudioVersion: 14.0
platform:
- x64
configuration: Release
platform: x64
build_script:
- mkdir build
- cd build
- cmake -G "Visual Studio 15 2017 Win64" ..
- cmake --build . --config Release
build:
verbosity: minimal
project: libnyquist.vcxproj/v141/libnyquist.sln

@ -1,24 +0,0 @@
function(_add_define definition)
list(APPEND _NQR_CXX_DEFINITIONS "-D${definition}")
set(_NQR_CXX_DEFINITIONS ${_NQR_CXX_DEFINITIONS} PARENT_SCOPE)
endfunction()
function(_disable_warning flag)
if(MSVC)
list(APPEND _NQR_CXX_WARNING_FLAGS "/wd${flag}")
else()
list(APPEND _NQR_CXX_WARNING_FLAGS "-Wno-${flag}")
endif()
set(_NQR_CXX_WARNING_FLAGS ${_NQR_CXX_WARNING_FLAGS} PARENT_SCOPE)
endfunction()
function(_set_compile_options proj)
if(MSVC)
target_compile_options(${proj} PRIVATE /arch:AVX /Zi )
endif()
endfunction()
function(set_cxx_version proj)
target_compile_features(${proj} INTERFACE cxx_std_14)
endfunction()

@ -0,0 +1,347 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
083DB3F11B0871D700FB0661 /* RtAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 083DB3EF1B0871D700FB0661 /* RtAudio.cpp */; };
08B91D791AC273A900335131 /* libpthread.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 08B91D781AC273A900335131 /* libpthread.dylib */; };
08B91D7B1AC273AE00335131 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08B91D7A1AC273AE00335131 /* CoreAudio.framework */; };
08B91D7D1AC273E400335131 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08B91D7C1AC273E400335131 /* CoreFoundation.framework */; };
08B91D7F1AC273EA00335131 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08B91D7E1AC273EA00335131 /* CoreServices.framework */; };
08B91D9F1AC73B8A00335131 /* Main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D951AC73B8A00335131 /* Main.cpp */; };
08BD8BD61B087097006C227C /* libnyquist.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 08BD8BD51B087097006C227C /* libnyquist.a */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
08B91D241AC26FC100335131 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
083DB3EF1B0871D700FB0661 /* RtAudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RtAudio.cpp; path = ../third_party/rtaudio/RtAudio.cpp; sourceTree = SOURCE_ROOT; };
083DB3F01B0871D700FB0661 /* RtAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RtAudio.h; path = ../third_party/rtaudio/RtAudio.h; sourceTree = SOURCE_ROOT; };
08B91D261AC26FC100335131 /* nyquist-example */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "nyquist-example"; sourceTree = BUILT_PRODUCTS_DIR; };
08B91D781AC273A900335131 /* libpthread.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpthread.dylib; path = usr/lib/libpthread.dylib; sourceTree = SDKROOT; };
08B91D7A1AC273AE00335131 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
08B91D7C1AC273E400335131 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
08B91D7E1AC273EA00335131 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
08B91D951AC73B8A00335131 /* Main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Main.cpp; path = src/Main.cpp; sourceTree = SOURCE_ROOT; };
08BD8BD51B087097006C227C /* libnyquist.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libnyquist.a; path = ../../../Library/Developer/Xcode/DerivedData/bin/Debug/libnyquist.a; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
08B91D231AC26FC100335131 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
08BD8BD61B087097006C227C /* libnyquist.a in Frameworks */,
08B91D7F1AC273EA00335131 /* CoreServices.framework in Frameworks */,
08B91D7D1AC273E400335131 /* CoreFoundation.framework in Frameworks */,
08B91D7B1AC273AE00335131 /* CoreAudio.framework in Frameworks */,
08B91D791AC273A900335131 /* libpthread.dylib in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
083DB3EB1B0871B300FB0661 /* third_party */ = {
isa = PBXGroup;
children = (
083DB3EF1B0871D700FB0661 /* RtAudio.cpp */,
083DB3F01B0871D700FB0661 /* RtAudio.h */,
);
name = third_party;
sourceTree = "<group>";
};
08B91D1D1AC26FC100335131 = {
isa = PBXGroup;
children = (
08B91D281AC26FC100335131 /* Example */,
08B91D801AC73B3B00335131 /* Frameworks */,
08B91D271AC26FC100335131 /* Products */,
);
sourceTree = "<group>";
};
08B91D271AC26FC100335131 /* Products */ = {
isa = PBXGroup;
children = (
08B91D261AC26FC100335131 /* nyquist-example */,
);
name = Products;
sourceTree = "<group>";
};
08B91D281AC26FC100335131 /* Example */ = {
isa = PBXGroup;
children = (
08B91D821AC73B6900335131 /* src */,
083DB3EB1B0871B300FB0661 /* third_party */,
);
name = Example;
path = libnyquist;
sourceTree = "<group>";
};
08B91D801AC73B3B00335131 /* Frameworks */ = {
isa = PBXGroup;
children = (
08B91D7E1AC273EA00335131 /* CoreServices.framework */,
08B91D7C1AC273E400335131 /* CoreFoundation.framework */,
08B91D7A1AC273AE00335131 /* CoreAudio.framework */,
08B91D781AC273A900335131 /* libpthread.dylib */,
08BD8BD51B087097006C227C /* libnyquist.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
08B91D821AC73B6900335131 /* src */ = {
isa = PBXGroup;
children = (
08B91D951AC73B8A00335131 /* Main.cpp */,
);
name = src;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
08B91D251AC26FC100335131 /* nyquist-example */ = {
isa = PBXNativeTarget;
buildConfigurationList = 08B91D2D1AC26FC100335131 /* Build configuration list for PBXNativeTarget "nyquist-example" */;
buildPhases = (
08B91D221AC26FC100335131 /* Sources */,
08B91D231AC26FC100335131 /* Frameworks */,
08B91D241AC26FC100335131 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = "nyquist-example";
productName = libnyquist;
productReference = 08B91D261AC26FC100335131 /* nyquist-example */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08B91D1E1AC26FC100335131 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0610;
ORGANIZATIONNAME = "Dimitri Diakopoulos";
TargetAttributes = {
08B91D251AC26FC100335131 = {
CreatedOnToolsVersion = 6.1.1;
};
};
};
buildConfigurationList = 08B91D211AC26FC100335131 /* Build configuration list for PBXProject "libnyquist-example" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 08B91D1D1AC26FC100335131;
productRefGroup = 08B91D271AC26FC100335131 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
08B91D251AC26FC100335131 /* nyquist-example */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
08B91D221AC26FC100335131 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
083DB3F11B0871D700FB0661 /* RtAudio.cpp in Sources */,
08B91D9F1AC73B8A00335131 /* Main.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
08B91D2B1AC26FC100335131 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
08B91D2C1AC26FC100335131 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
};
name = Release;
};
08B91D2E1AC26FC100335131 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
GCC_CHAR_IS_UNSIGNED_CHAR = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_BUILTIN_FUNCTIONS = YES;
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_INPUT_FILETYPE = automatic;
GCC_LINK_WITH_DYNAMIC_LIBRARIES = YES;
GCC_NO_COMMON_BLOCKS = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
__MACOSX_CORE__,
USE_ALLOCA,
OPUS_BUILD,
);
GCC_STRICT_ALIASING = NO;
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../include",
"$(SRCROOT)/../third_party",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/bin/Debug",
);
PRODUCT_NAME = "$(TARGET_NAME)";
SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES;
};
name = Debug;
};
08B91D2F1AC26FC100335131 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
GCC_CHAR_IS_UNSIGNED_CHAR = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_BUILTIN_FUNCTIONS = YES;
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_INPUT_FILETYPE = automatic;
GCC_LINK_WITH_DYNAMIC_LIBRARIES = YES;
GCC_NO_COMMON_BLOCKS = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
__MACOSX_CORE__,
USE_ALLOCA,
OPUS_BUILD,
);
GCC_STRICT_ALIASING = NO;
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../include",
"$(SRCROOT)/../third_party",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/bin/Debug",
);
PRODUCT_NAME = "$(TARGET_NAME)";
SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
08B91D211AC26FC100335131 /* Build configuration list for PBXProject "libnyquist-example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
08B91D2B1AC26FC100335131 /* Debug */,
08B91D2C1AC26FC100335131 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
08B91D2D1AC26FC100335131 /* Build configuration list for PBXNativeTarget "nyquist-example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
08B91D2E1AC26FC100335131 /* Debug */,
08B91D2F1AC26FC100335131 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 08B91D1E1AC26FC100335131 /* Project object */;
}

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:libnyquist-example.xcodeproj">
</FileRef>
</Workspace>

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "08B91D251AC26FC100335131"
BuildableName = "libnyquist"
BlueprintName = "libnyquist"
ReferencedContainer = "container:libnyquist.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "08B91D251AC26FC100335131"
BuildableName = "nyquist-example"
BlueprintName = "nyquist-example"
ReferencedContainer = "container:libnyquist-example.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "YES"
customWorkingDirectory = "$(PROJECT_DIR)/../"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "08B91D251AC26FC100335131"
BuildableName = "nyquist-example"
BlueprintName = "nyquist-example"
ReferencedContainer = "container:libnyquist-example.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "08B91D251AC26FC100335131"
BuildableName = "libnyquist"
BlueprintName = "libnyquist"
ReferencedContainer = "container:libnyquist.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

@ -0,0 +1,41 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnyquist-examples", "libnyquist-examples.vcxproj", "{C0C0C270-FB9E-4EEB-8F22-180BB2FA800B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnyquist", "..\..\..\libnyquist.vcxproj\v141\libnyquist.vcxproj", "{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C0C0C270-FB9E-4EEB-8F22-180BB2FA800B}.Debug|Win32.ActiveCfg = Debug|Win32
{C0C0C270-FB9E-4EEB-8F22-180BB2FA800B}.Debug|Win32.Build.0 = Debug|Win32
{C0C0C270-FB9E-4EEB-8F22-180BB2FA800B}.Debug|x64.ActiveCfg = Debug|x64
{C0C0C270-FB9E-4EEB-8F22-180BB2FA800B}.Debug|x64.Build.0 = Debug|x64
{C0C0C270-FB9E-4EEB-8F22-180BB2FA800B}.Release|Win32.ActiveCfg = Release|Win32
{C0C0C270-FB9E-4EEB-8F22-180BB2FA800B}.Release|Win32.Build.0 = Release|Win32
{C0C0C270-FB9E-4EEB-8F22-180BB2FA800B}.Release|x64.ActiveCfg = Release|x64
{C0C0C270-FB9E-4EEB-8F22-180BB2FA800B}.Release|x64.Build.0 = Release|x64
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Debug|Win32.ActiveCfg = Debug|Win32
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Debug|Win32.Build.0 = Debug|Win32
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Debug|x64.ActiveCfg = Debug|x64
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Debug|x64.Build.0 = Debug|x64
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Release|Win32.ActiveCfg = Release|Win32
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Release|Win32.Build.0 = Release|Win32
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Release|x64.ActiveCfg = Release|x64
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {1FD1AD23-26D0-4E89-9C5F-3C8FCCBE22E1}
EndGlobalSection
EndGlobal

@ -0,0 +1,146 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C0C0C270-FB9E-4EEB-8F22-180BB2FA800B}</ProjectGuid>
<RootNamespace>libnyquistexamples</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)../../../include;$(SolutionDir)../../../third_party;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__WINDOWS_DS__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)../../../include;$(SolutionDir)../../../third_party;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__WINDOWS_DS__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)../../../include;$(SolutionDir)../../../third_party;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__WINDOWS_DS__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)../../../include;$(SolutionDir)../../../third_party;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__WINDOWS_DS__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\third_party\rtaudio\RtAudio.cpp" />
<ClCompile Include="..\..\src\AudioDevice.cpp" />
<ClCompile Include="..\..\src\Main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\third_party\rtaudio\RtAudio.h" />
<ClInclude Include="..\..\src\AudioDevice.h" />
<ClInclude Include="..\..\src\RingBuffer.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\libnyquist.vcxproj\v141\libnyquist.vcxproj">
<Project>{0eec3739-f60a-4b90-8b75-9e1aff28106a}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="third_party">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="src">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\Main.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\..\third_party\rtaudio\RtAudio.cpp">
<Filter>third_party</Filter>
</ClCompile>
<ClCompile Include="..\..\src\AudioDevice.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\third_party\rtaudio\RtAudio.h">
<Filter>third_party</Filter>
</ClInclude>
<ClInclude Include="..\..\src\AudioDevice.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\..\src\RingBuffer.h">
<Filter>src</Filter>
</ClInclude>
</ItemGroup>
</Project>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:../libnyquist.xcodeproj">
</FileRef>
<FileRef
location = "container:libnyquist-example.xcodeproj">
</FileRef>
</Workspace>

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:
@ -37,12 +37,12 @@ static int rt_callback(void * output_buffer, void * input_buffer, uint32_t num_b
{
if (status) std::cerr << "[rtaudio] buffer over or underflow" << std::endl;
// Playback
// Playback
if (buffer.getAvailableRead()) buffer.read((float*) output_buffer, BUFFER_LENGTH);
else memset(output_buffer, 0, BUFFER_LENGTH * sizeof(float));
// Recording
if (record_buffer.getAvailableWrite()) record_buffer.write((float*) input_buffer, BUFFER_LENGTH / 2);
// Recording
if (record_buffer.getAvailableWrite()) record_buffer.write((float*) input_buffer, BUFFER_LENGTH / 2);
return 0;
}
@ -62,9 +62,9 @@ AudioDevice::~AudioDevice()
{
rtaudio->stopStream();
if (rtaudio->isStreamOpen())
{
{
rtaudio->closeStream();
}
}
}
}
@ -77,7 +77,7 @@ bool AudioDevice::Open(const int deviceId)
outputParams.nChannels = info.numChannels;
outputParams.firstChannel = 0;
RtAudio::StreamParameters inputParams;
RtAudio::StreamParameters inputParams;
inputParams.deviceId = rtaudio->getDefaultInputDevice();
inputParams.nChannels = 1;
inputParams.firstChannel = 0;
@ -129,21 +129,21 @@ bool AudioDevice::Play(const std::vector<float> & data)
bool AudioDevice::Record(const uint32_t lengthInSamples, std::vector<float> & recordingBuffer)
{
uint64_t recordedSamples = 0;
uint64_t recordedSamples = 0;
// Allocate memory upfront (revisit this later...)
recordingBuffer.resize(lengthInSamples + (BUFFER_LENGTH)); // + a little padding
// Allocate memory upfront (revisit this later...)
recordingBuffer.resize(lengthInSamples + (BUFFER_LENGTH)); // + a little padding
while (recordedSamples < lengthInSamples)
{
if (record_buffer.getAvailableRead())
{
if (record_buffer.read(recordingBuffer.data() + recordedSamples, BUFFER_LENGTH / 2))
{
recordedSamples += (BUFFER_LENGTH / 2);
}
}
}
while (recordedSamples < lengthInSamples)
{
if (record_buffer.getAvailableRead())
{
if (record_buffer.read(recordingBuffer.data() + recordedSamples, BUFFER_LENGTH / 2))
{
recordedSamples += (BUFFER_LENGTH / 2);
}
}
}
return true;
return true;
}

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:
@ -39,27 +39,27 @@ static const int32_t BUFFER_LENGTH = FRAME_SIZE * CHANNELS;
struct AudioDeviceInfo
{
uint32_t id;
uint32_t numChannels;
uint32_t sampleRate;
uint32_t frameSize;
bool isPlaying = false;
uint32_t id;
uint32_t numChannels;
uint32_t sampleRate;
uint32_t frameSize;
bool isPlaying = false;
};
class AudioDevice
{
std::unique_ptr<RtAudio> rtaudio;
std::unique_ptr<RtAudio> rtaudio;
protected:
AudioDevice(const AudioDevice& r) = delete;
AudioDevice & operator = (const AudioDevice& r) = delete;
AudioDevice(const AudioDevice& r) = delete;
AudioDevice & operator = (const AudioDevice& r) = delete;
public:
AudioDeviceInfo info;
AudioDevice(int numChannels, int sampleRate, int deviceId = -1);
~AudioDevice();
static void ListAudioDevices();
bool Open(const int deviceId);
bool Play(const std::vector<float> & data);
bool Record(const uint32_t lengthInSamples, std::vector<float> & recordingBuffer);
AudioDeviceInfo info;
AudioDevice(int numChannels, int sampleRate, int deviceId = -1);
~AudioDevice();
static void ListAudioDevices();
bool Open(const int deviceId);
bool Play(const std::vector<float> & data);
bool Record(const uint32_t lengthInSamples, std::vector<float> & recordingBuffer);
};
#endif

@ -1,5 +1,5 @@
// Note to Visual Studio / Windows users: you must set the working directory manually on the project file
// to $(ProjectDir)../ since these settings are not saved directly in project. The loader
// to $(ProjectDir)../../../ since these settings are not saved directly in project. The loader
// will be unable to find the example assets unless the proper working directory is set.
#if defined(_MSC_VER)
@ -8,8 +8,9 @@
#include "AudioDevice.h"
#include "libnyquist/Decoders.h"
#include "libnyquist/Encoders.h"
#include "libnyquist/AudioDecoder.h"
#include "libnyquist/WavEncoder.h"
#include "libnyquist/PostProcess.h"
#include <thread>
@ -17,151 +18,136 @@ using namespace nqr;
int main(int argc, const char **argv) try
{
AudioDevice::ListAudioDevices();
AudioDevice::ListAudioDevices();
const int desiredSampleRate = 44100;
const int desiredChannelCount = 2;
AudioDevice myDevice(desiredChannelCount, desiredSampleRate);
myDevice.Open(myDevice.info.id);
int desiredSampleRate = 44100;
AudioDevice myDevice(2, desiredSampleRate);
myDevice.Open(myDevice.info.id);
std::shared_ptr<AudioData> fileData = std::make_shared<AudioData>();
std::shared_ptr<AudioData> fileData = std::make_shared<AudioData>();
NyquistIO loader;
NyquistIO loader;
if (argc > 1)
{
std::string cli_arg = std::string(argv[1]);
loader.Load(fileData.get(), cli_arg);
}
else
{
// Circular libnyquist testing
//loader.Load(fileData.get(), "libnyquist_example_output.opus");
if (argc > 1)
{
std::string cli_arg = std::string(argv[1]);
loader.Load(fileData.get(), cli_arg);
}
else
{
// Circular libnyquist testing
//loader.Load(fileData.get(), "encoded.opus");
// 1-channel wave
//loader.Load(fileData.get(), "test_data/1ch/44100/8/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/16/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/24/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/32/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/64/test.wav");
// 1-channel wave
//loader.Load(fileData.get(), "test_data/1ch/44100/8/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/16/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/24/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/32/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/64/test.wav");
// 2-channel wave
//loader.Load(fileData.get(), "test_data/2ch/44100/8/test.wav");
//loader.Load(fileData.get(), "test_data/2ch/44100/16/test.wav");
//loader.Load(fileData.get(), "test_data/2ch/44100/24/test.wav");
//loader.Load(fileData.get(), "test_data/2ch/44100/32/test.wav");
//loader.Load(fileData.get(), "test_data/2ch/44100/64/test.wav");
// 2-channel wave
//loader.Load(fileData.get(), "test_data/2ch/44100/8/test.wav");
//loader.Load(fileData.get(), "test_data/2ch/44100/16/test.wav");
//loader.Load(fileData.get(), "test_data/2ch/44100/24/test.wav");
//loader.Load(fileData.get(), "test_data/2ch/44100/32/test.wav");
//loader.Load(fileData.get(), "test_data/2ch/44100/64/test.wav");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_44_16_mono-ima4-reaper.wav");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_44_16_stereo-ima4-reaper.wav");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_44_16_mono-ima4-reaper.wav");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_44_16_stereo-ima4-reaper.wav");
// Multi-channel wave
//loader.Load(fileData.get(), "test_data/ad_hoc/6_channel_44k_16b.wav");
// Multi-channel wave
//loader.Load(fileData.get(), "test_data/ad_hoc/6_channel_44k_16b.wav");
// 1 + 2 channel ogg
//loader.Load(fileData.get(), "test_data/ad_hoc/LR_Stereo.ogg");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestLaugh_44k.ogg");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat.ogg");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeatMono.ogg");
//loader.Load(fileData.get(), "test_data/ad_hoc/BlockWoosh_Stereo.ogg");
// 1 + 2 channel ogg
//loader.Load(fileData.get(), "test_data/ad_hoc/LR_Stereo.ogg");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestLaugh_44k.ogg");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat.ogg");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeatMono.ogg");
//loader.Load(fileData.get(), "test_data/ad_hoc/BlockWoosh_Stereo.ogg");
// 1 + 2 channel flac
//loader.Load(fileData.get(), "test_data/ad_hoc/KittyPurr8_Stereo_Dithered.flac");
//loader.Load(fileData.get(), "test_data/ad_hoc/KittyPurr16_Stereo.flac");
//loader.Load(fileData.get(), "test_data/ad_hoc/KittyPurr16_Mono.flac");
//loader.Load(fileData.get(), "test_data/ad_hoc/KittyPurr24_Stereo.flac");
// 1 + 2 channel flac
//loader.Load(fileData.get(), "test_data/ad_hoc/KittyPurr8_Stereo_Dithered.flac");
//loader.Load(fileData.get(), "test_data/ad_hoc/KittyPurr16_Stereo.flac");
//loader.Load(fileData.get(), "test_data/ad_hoc/KittyPurr16_Mono.flac");
//loader.Load(fileData.get(), "test_data/ad_hoc/KittyPurr24_Stereo.flac");
//auto memory = ReadFile("test_data/ad_hoc/KittyPurr24_Stereo.flac"); // broken
//loader.Load(fileData.get(), "flac", memory.buffer); // broken
// Single-channel opus
//loader.Load(fileData.get(), "test_data/ad_hoc/detodos.opus"); // "Firefox: From All, To All"
// Single-channel opus
//loader.Load(fileData.get(), "test_data/ad_hoc/detodos.opus"); // "Firefox: From All, To All"
// 1 + 2 channel wavepack
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Float32.wv");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Float32_Mono.wv");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Int16.wv");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Int24.wv");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Int32.wv");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Int24_Mono.wv");
// 1 + 2 channel wavpack
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Float32.wv");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Float32_Mono.wv");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Int16.wv");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Int24.wv");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Int32.wv");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Int24_Mono.wv");
// In-memory wavpack
auto memory = ReadFile("test_data/ad_hoc/TestBeat_Float32.wv");
loader.Load(fileData.get(), "wv", memory.buffer);
// 1 + 2 channel musepack
//loader.Load(fileData.get(), "test_data/ad_hoc/44_16_stereo.mpc");
//loader.Load(fileData.get(), "test_data/ad_hoc/44_16_mono.mpc");
// 1 + 2 channel musepack
//loader.Load(fileData.get(), "test_data/ad_hoc/44_16_stereo.mpc");
//loader.Load(fileData.get(), "test_data/ad_hoc/44_16_mono.mpc");
// In-memory ogg
//auto memory = ReadFile("test_data/ad_hoc/BlockWoosh_Stereo.ogg");
//loader.Load(fileData.get(), "ogg", memory.buffer);
auto memory = ReadFile("test_data/ad_hoc/BlockWoosh_Stereo.ogg");
loader.Load(fileData.get(), "ogg", memory.buffer);
}
// In-memory Mp3
//auto memory = ReadFile("test_data/ad_hoc/acetylene.mp3");
//loader.Load(fileData.get(), "mp3", memory.buffer);
}
/*
// Test Recording Capabilities of AudioDevice
fileData->samples.reserve(44100 * 5);
fileData->channelCount = 1;
fileData->frameSize = 32;
fileData->lengthSeconds = 5.0;
fileData->sampleRate = 44100;
std::cout << "Starting recording ..." << std::endl;
myDevice.Record(fileData->sampleRate * fileData->lengthSeconds, fileData->samples);
*/
/* Test Recording Capabilities of AudioDevice
fileData->samples.reserve(44100 * 5);
fileData->channelCount = 1;
fileData->frameSize = 32;
fileData->lengthSeconds = 5.0;
fileData->sampleRate = 44100;
std::cout << "Starting recording ..." << std::endl;
myDevice.Record(fileData->sampleRate * fileData->lengthSeconds, fileData->samples);
*/
if (fileData->sampleRate != desiredSampleRate)
{
std::cout << "[Warning - Sample Rate Mismatch] - file is sampled at " << fileData->sampleRate << " and output is " << desiredSampleRate << std::endl;
}
if (fileData->sampleRate != desiredSampleRate)
{
std::cout << "[Warning - Sample Rate Mismatch] - file is sampled at " << fileData->sampleRate << " and output is " << desiredSampleRate << std::endl;
}
// Resample
std::vector<float> outputBuffer;
outputBuffer.reserve(fileData->samples.size());
linear_resample(44100.0 / 48000.0, fileData->samples, outputBuffer, fileData->samples.size());
std::cout << "Input Samples: " << fileData->samples.size() << std::endl;
std::cout << "Input Samples: " << fileData->samples.size() << std::endl;
std::cout << "Output Samples: " << outputBuffer.size() << std::endl;
// Convert mono to stereo for testing playback
if (fileData->channelCount == 1)
{
std::cout << "Playing MONO for: " << fileData->lengthSeconds << " seconds..." << std::endl;
std::vector<float> stereoCopy(fileData->samples.size() * 2);
MonoToStereo(fileData->samples.data(), stereoCopy.data(), fileData->samples.size());
myDevice.Play(stereoCopy);
}
else
{
std::cout << "Playing STEREO for: " << fileData->lengthSeconds << " seconds..." << std::endl;
myDevice.Play(fileData->samples);
}
// Convert mono to stereo for testing playback
if (fileData->channelCount == 1)
{
std::cout << "Playing MONO for: " << fileData->lengthSeconds << " seconds..." << std::endl;
std::vector<float> stereoCopy(fileData->samples.size() * 2);
MonoToStereo(fileData->samples.data(), stereoCopy.data(), fileData->samples.size());
myDevice.Play(stereoCopy);
}
else
{
std::cout << "Playing for: " << fileData->lengthSeconds << " seconds..." << std::endl;
myDevice.Play(fileData->samples);
}
// Test Opus Encoding
{
// Resample
std::vector<float> outputBuffer;
std::cout << "Output Samples: " << outputBuffer.size() << std::endl;
fileData->samples = outputBuffer;
int encoderStatus = OggOpusEncoder::WriteFile({ 1, PCM_FLT, DITHER_NONE }, fileData.get(), "encoded.opus");
std::cout << "Encoder Status: " << encoderStatus << std::endl;
outputBuffer.reserve(fileData->samples.size() * 2);
linear_resample(fileData->sampleRate / 48000.0f, fileData->samples, outputBuffer, (uint32_t)fileData->samples.size());
fileData->samples = outputBuffer;
int encoderStatus = encode_opus_to_disk({ fileData->channelCount, PCM_FLT, DITHER_NONE }, fileData.get(), "libnyquist_example_output.opus");
std::cout << "Encoder Status: " << encoderStatus << std::endl;
}
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}
catch (const UnsupportedExtensionEx & e)
{
std::cerr << "Caught: " << e.what() << std::endl;
std::cerr << "Caught: " << e.what() << std::endl;
}
catch (const LoadPathNotImplEx & e)
{
std::cerr << "Caught: " << e.what() << std::endl;
std::cerr << "Caught: " << e.what() << std::endl;
}
catch (const LoadBufferNotImplEx & e)
{
std::cerr << "Caught: " << e.what() << std::endl;
std::cerr << "Caught: " << e.what() << std::endl;
}
catch (const std::exception & e)
{
std::cerr << "Caught: " << e.what() << std::endl;
std::cerr << "Caught: " << e.what() << std::endl;
}

@ -36,8 +36,6 @@
#include <atomic>
#include <assert.h>
#include <cstring>
#include <cstdlib>
template <typename T>
class RingBufferT
@ -45,7 +43,7 @@ class RingBufferT
public:
// Constructs a RingBufferT with size = 0
RingBufferT() : mData(nullptr), mAllocatedSize(0), mWriteIndex(0), mReadIndex(0) {}
RingBufferT() : mData(nullptr), mAllocatedSize(0), mWriteIndex(0), mReadIndex(0) {}
// Constructs a RingBufferT with \a count maximum elements.
RingBufferT(size_t count) : mAllocatedSize(0) { resize(count); }
@ -67,9 +65,9 @@ class RingBufferT
size_t allocatedSize = count + 1; // one bin is used to distinguish between the read and write indices when full.
if (mAllocatedSize)
mData = (T *) std::realloc(mData, allocatedSize * sizeof(T));
mData = (T *)::realloc(mData, allocatedSize * sizeof(T));
else
mData = (T *) std::calloc(allocatedSize, sizeof(T));
mData = (T *)::calloc(allocatedSize, sizeof(T));
assert(mData);

@ -0,0 +1,82 @@
/*
Copyright (c) 2015, 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.
*/
#ifndef AUDIO_DECODER_H
#define AUDIO_DECODER_H
#include "Common.h"
#include <utility>
#include <map>
#include <memory>
#include <exception>
namespace nqr
{
struct UnsupportedExtensionEx : public std::runtime_error
{
UnsupportedExtensionEx() : std::runtime_error("Unsupported file extension") {}
};
struct LoadPathNotImplEx : public std::runtime_error
{
LoadPathNotImplEx() : std::runtime_error("Loading from path not implemented") {}
};
struct LoadBufferNotImplEx : public std::runtime_error
{
LoadBufferNotImplEx() : std::runtime_error("Loading from buffer not implemented") {}
};
struct BaseDecoder
{
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) = 0;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) = 0;
virtual std::vector<std::string> GetSupportedFileExtensions() = 0;
virtual ~BaseDecoder() {}
};
typedef std::pair<std::string, std::shared_ptr<nqr::BaseDecoder>> DecoderPair;
class NyquistIO
{
std::string ParsePathForExtension(const std::string & path) const;
std::shared_ptr<nqr::BaseDecoder> GetDecoderForExtension(const std::string & ext);
void BuildDecoderTable();
void AddDecoderToTable(std::shared_ptr<nqr::BaseDecoder> decoder);
std::map<std::string, std::shared_ptr<BaseDecoder>> decoderTable;
NO_MOVE(NyquistIO);
public:
NyquistIO();
~NyquistIO();
void Load(AudioData * data, const std::string & path);
void Load(AudioData * data, const std::vector<uint8_t> & buffer);
void Load(AudioData * data, const std::string & extension, const std::vector<uint8_t> & buffer);
bool IsFileSupported(const std::string & path) const;
};
} // end namespace nqr
#endif

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:
@ -37,8 +37,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <type_traits>
#include <numeric>
#include <array>
#include <map>
#include <random>
#include "PostProcess.h"
#include "Dither.h"
namespace nqr
{
@ -200,90 +201,10 @@ inline std::array<uint8_t, 3> Unpack(uint32_t a)
return output;
}
//////////////////////////
// Resampling Utilities //
//////////////////////////
// This is a naieve implementation of a resampling filter where a lerp is used as a bad low-pass.
// It very far from the ideal case and should be used with caution (or not at all) on signals that matter.
// It is included here to upsample 44.1k to 48k for the purposes of microphone input => Opus, where the the
// nominal frequencies of speech are particularly far from Nyquist.
inline void linear_resample(const double rate, const std::vector<float> & input, std::vector<float> & output, const uint32_t samplesToProcess)
{
double virtualReadIndex = 0;
double a, b, i, sample;
uint32_t n = samplesToProcess - 1;
while (n--)
{
uint32_t readIndex = static_cast<uint32_t>(virtualReadIndex);
i = virtualReadIndex - readIndex;
a = input[readIndex + 0];
b = input[readIndex + 1];
sample = (1.0 - i) * a + i * b; // linear interpolate
output.push_back(static_cast<float>(sample));
virtualReadIndex += rate;
}
}
inline double sample_hermite_4p_3o(double x, double * y)
{
static double c0, c1, c2, c3;
c0 = y[1];
c1 = (1.0 / 2.0)*(y[2] - y[0]);
c2 = (y[0] - (5.0 / 2.0)*y[1]) + (2.0*y[2] - (1.0 / 2.0)*y[3]);
c3 = (1.0 / 2.0)*(y[3] - y[0]) + (3.0 / 2.0)*(y[1] - y[2]);
return ((c3*x + c2)*x + c1)*x + c0;
}
inline void hermite_resample(const double rate, const std::vector<float> & input, std::vector<float> & output, const uint32_t samplesToProcess)
{
double virtualReadIndex = 1;
double i, sample;
uint32_t n = samplesToProcess - 1;
while (n--)
{
uint32_t readIndex = static_cast<uint32_t>(virtualReadIndex);
i = virtualReadIndex - readIndex;
double samps[4] = { input[readIndex - 1], input[readIndex], input[readIndex + 1], input[readIndex + 2] };
sample = sample_hermite_4p_3o(i, samps); // cubic hermite interpolate over 4 samples
output.push_back(static_cast<float>(sample));
virtualReadIndex += rate;
}
}
//////////////////////////
// Conversion Utilities //
//////////////////////////
enum DitherType
{
DITHER_NONE,
DITHER_TRIANGLE
};
class Dither
{
std::uniform_real_distribution<float> distribution;
std::mt19937 gen;
float previous;
DitherType d;
public:
Dither(DitherType d) : distribution(-0.5f, +0.5f), previous(0.f), d(d) {}
float operator()(float s)
{
if (d == DITHER_TRIANGLE)
{
const float value = distribution(gen);
s = s + value - previous;
previous = value;
return s;
}
else return s;
}
};
// Signed maxes, defined for readabilty/convenience
#define NQR_INT16_MAX 32767.f
#define NQR_INT24_MAX 8388608.f
@ -331,9 +252,6 @@ void ConvertToFloat32(float * dst, const int16_t * src, const size_t N, PCMForma
void ConvertFromFloat32(uint8_t * dst, const float * src, const size_t N, PCMFormat f, DitherType t = DITHER_NONE);
int GetFormatBitsPerSample(PCMFormat f);
PCMFormat MakeFormatForBits(int bits, bool floatingPt, bool isSigned);
//////////////////////////
// User Data + File Ops //
//////////////////////////
@ -368,326 +286,8 @@ struct NyquistFileBuffer
NyquistFileBuffer ReadFile(const std::string & pathToFile);
////////////////////
// Encoding Utils //
////////////////////
struct EncoderParams
{
int channelCount;
PCMFormat targetFormat;
DitherType dither;
};
enum EncoderError
{
NoError,
InsufficientSampleData,
FileIOError,
UnsupportedSamplerate,
UnsupportedChannelConfiguration,
UnsupportedBitdepth,
UnsupportedChannelMix,
BufferTooBig,
};
//////////////////////
// Wav Format Utils //
//////////////////////
enum WaveFormatCode
{
FORMAT_UNKNOWN = 0x0, // Unknown Wave Format
FORMAT_PCM = 0x1, // PCM Format
FORMAT_ADPCM = 0x2, // Microsoft ADPCM Format
FORMAT_IEEE = 0x3, // IEEE float/double
FORMAT_ALAW = 0x6, // 8-bit ITU-T G.711 A-law
FORMAT_MULAW = 0x7, // 8-bit ITU-T G.711 µ-law
FORMAT_IMA_ADPCM = 0x11, // IMA ADPCM Format
FORMAT_EXT = 0xFFFE // Set via subformat
};
struct RiffChunkHeader
{
uint32_t id_riff; // Chunk ID: 'RIFF'
uint32_t file_size; // Entire file in bytes
uint32_t id_wave; // Chunk ID: 'WAVE'
};
struct WaveChunkHeader
{
uint32_t fmt_id; // Chunk ID: 'fmt '
uint32_t chunk_size; // Size in bytes
uint16_t format; // Format code
uint16_t channel_count; // Num interleaved channels
uint32_t sample_rate; // SR
uint32_t data_rate; // Data rate
uint16_t frame_size; // 1 frame = channels * bits per sample (also known as block align)
uint16_t bit_depth; // Bits per sample
};
struct BextChunk
{
uint32_t fmt_id; // Chunk ID: 'bext'
uint32_t chunk_size; // Size in bytes
uint8_t description[256]; // Description of the sound (ascii)
uint8_t origin[32]; // Name of the originator (ascii)
uint8_t origin_ref[32]; // Reference of the originator (ascii)
uint8_t orgin_date[10]; // yyyy-mm-dd (ascii)
uint8_t origin_time[8]; // hh-mm-ss (ascii)
uint64_t time_ref; // First sample count since midnight
uint32_t version; // Version of the BWF
uint8_t uimd[64]; // Byte 0 of SMPTE UMID
uint8_t reserved[188]; // 190 bytes, reserved for future use & set to NULL
};
struct FactChunk
{
uint32_t fact_id; // Chunk ID: 'fact'
uint32_t chunk_size; // Size in bytes
uint32_t sample_length; // number of samples per channel
};
struct ExtensibleData
{
uint16_t size;
uint16_t valid_bits_per_sample;
uint32_t channel_mask;
struct GUID
{
uint32_t data0;
uint16_t data1;
uint16_t data2;
uint16_t data3;
uint8_t data4[6];
};
};
template<class C, class R>
std::basic_ostream<C,R> & operator << (std::basic_ostream<C,R> & a, const WaveChunkHeader & b)
{
return a <<
"Format ID:\t\t" << b.fmt_id <<
"\nChunk Size:\t\t" << b.chunk_size <<
"\nFormat Code:\t\t" << b.format <<
"\nChannels:\t\t" << b.channel_count <<
"\nSample Rate:\t\t" << b.sample_rate <<
"\nData Rate:\t\t" << b.data_rate <<
"\nFrame Size:\t\t" << b.frame_size <<
"\nBit Depth:\t\t" << b.bit_depth << std::endl;
}
//@todo expose speaker/channel/layout masks in the API:
enum SpeakerChannelMask
{
SPEAKER_FRONT_LEFT = 0x00000001,
SPEAKER_FRONT_RIGHT = 0x00000002,
SPEAKER_FRONT_CENTER = 0x00000004,
SPEAKER_LOW_FREQUENCY = 0x00000008,
SPEAKER_BACK_LEFT = 0x00000010,
SPEAKER_BACK_RIGHT = 0x00000020,
SPEAKER_FRONT_LEFT_OF_CENTER = 0x00000040,
SPEAKER_FRONT_RIGHT_OF_CENTER = 0x00000080,
SPEAKER_BACK_CENTER = 0x00000100,
SPEAKER_SIDE_LEFT = 0x00000200,
SPEAKER_SIDE_RIGHT = 0x00000400,
SPEAKER_TOP_CENTER = 0x00000800,
SPEAKER_TOP_FRONT_LEFT = 0x00001000,
SPEAKER_TOP_FRONT_CENTER = 0x00002000,
SPEAKER_TOP_FRONT_RIGHT = 0x00004000,
SPEAKER_TOP_BACK_LEFT = 0x00008000,
SPEAKER_TOP_BACK_CENTER = 0x00010000,
SPEAKER_TOP_BACK_RIGHT = 0x00020000,
SPEAKER_RESERVED = 0x7FFC0000,
SPEAKER_ALL = 0x80000000
};
enum SpeakerLayoutMask
{
SPEAKER_MONO = (SPEAKER_FRONT_CENTER),
SPEAKER_STEREO = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT),
SPEAKER_2POINT1 = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY),
SPEAKER_SURROUND = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER),
SPEAKER_QUAD = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT),
SPEAKER_4POINT1 = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT),
SPEAKER_5POINT1 = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT),
SPEAKER_7POINT1 = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER),
SPEAKER_5POINT1_SURROUND = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT),
SPEAKER_7POINT1_SURROUND = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT),
};
//@todo verify mask values
inline int ComputeChannelMask(const size_t channels)
{
switch (channels)
{
case 1: return SPEAKER_MONO;
case 2: return SPEAKER_STEREO;
case 3: return SPEAKER_2POINT1;
case 4: return SPEAKER_QUAD;
case 5: return SPEAKER_4POINT1;
case 6: return SPEAKER_5POINT1;
default: return -1;
}
}
/////////////////////
// Chunk utilities //
/////////////////////
struct ChunkHeaderInfo
{
uint32_t offset; // Byte offset into chunk
uint32_t size; // Size of the chunk in bytes
};
inline uint32_t GenerateChunkCode(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
#ifdef ARCH_CPU_LITTLE_ENDIAN
return ((uint32_t)((a) | ((b) << 8) | ((c) << 16) | (((uint32_t)(d)) << 24)));
#else
return ((uint32_t)((((uint32_t)(a)) << 24) | ((b) << 16) | ((c) << 8) | (d)));
#endif
}
inline char * GenerateChunkCodeChar(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
auto chunk = GenerateChunkCode(a, b, c, d);
char * outArr = new char[4];
uint32_t t = 0x000000FF;
for (size_t i = 0; i < 4; i++)
{
outArr[i] = chunk & t;
chunk >>= 8;
}
return outArr;
}
inline ChunkHeaderInfo ScanForChunk(const std::vector<uint8_t> & fileData, uint32_t chunkMarker)
{
// D[n] aligned to 16 bytes now
const uint16_t * d = reinterpret_cast<const uint16_t *>(fileData.data());
for (size_t i = 0; i < fileData.size() / sizeof(uint16_t); i++)
{
// This will be in machine endianess
uint32_t m = Pack(Read16(d[i]), Read16(d[i + 1]));
if (m == chunkMarker)
{
uint32_t cSz = Pack(Read16(d[i + 2]), Read16(d[i + 3]));
return { (uint32_t(i * sizeof(uint16_t))), cSz }; // return i in bytes to the start of the data
}
else continue;
}
return { 0, 0 };
};
inline WaveChunkHeader MakeWaveHeader(const EncoderParams param, const int sampleRate)
{
WaveChunkHeader header;
int bitdepth = GetFormatBitsPerSample(param.targetFormat);
header.fmt_id = GenerateChunkCode('f', 'm', 't', ' ');
header.chunk_size = 16;
header.format = (param.targetFormat <= PCMFormat::PCM_32) ? WaveFormatCode::FORMAT_PCM : WaveFormatCode::FORMAT_IEEE;
header.channel_count = param.channelCount;
header.sample_rate = sampleRate;
header.data_rate = sampleRate * param.channelCount * (bitdepth / 8);
header.frame_size = param.channelCount * (bitdepth / 8);
header.bit_depth = bitdepth;
return header;
}
// @todo expose this in the FLAC API
inline std::map<int, std::string> GetFlacQualityTable()
{
return {
{ 0, "0 (Fastest)" },
{ 1, "1" },
{ 2, "2" },
{ 3, "3" },
{ 4, "4" },
{ 5, "5 (Default)" },
{ 6, "6" },
{ 7, "7" },
{ 8, "8 (Highest)" },
};
}
template <typename T>
inline void DeinterleaveStereo(T * c1, T * c2, T const * src, size_t count)
{
auto src_end = src + count;
while (src != src_end)
{
*c1 = src[0];
*c2 = src[1];
c1++;
c2++;
src += 2;
}
}
template<typename T>
void InterleaveChannels(const T * src, T * dest, size_t numFramesPerChannel, size_t numChannels, size_t N)
{
for (size_t ch = 0; ch < numChannels; ch++)
{
size_t x = ch;
const T * srcChannel = &src[ch * numFramesPerChannel];
for (size_t i = 0; i < N; i++)
{
dest[x] = srcChannel[i];
x += numChannels;
}
}
}
template<typename T>
void DeinterleaveChannels(const T * src, T * dest, size_t numFramesPerChannel, size_t numChannels, size_t N)
{
for (size_t ch = 0; ch < numChannels; ch++)
{
size_t x = ch;
T *destChannel = &dest[ch * numFramesPerChannel];
for (size_t i = 0; i < N; i++)
{
destChannel[i] = (T)src[x];
x += numChannels;
}
}
}
template <typename T>
void StereoToMono(const T * src, T * dest, size_t N)
{
for (size_t i = 0, j = 0; i < N; i += 2, ++j)
{
dest[j] = (src[i] + src[i + 1]) / 2.0f;
}
}
template <typename T>
void MonoToStereo(const T * src, T * dest, size_t N)
{
for (size_t i = 0, j = 0; i < N; ++i, j += 2)
{
dest[j] = src[i];
dest[j + 1] = src[i];
}
}
inline void TrimSilenceInterleaved(std::vector<float> & buffer, float v, bool fromFront, bool fromEnd)
{
//@todo implement me!
}
int GetFormatBitsPerSample(PCMFormat f);
PCMFormat MakeFormatForBits(int bits, bool floatingPt, bool isSigned);
} // end namespace nqr

@ -1,136 +0,0 @@
/*
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.
*/
#ifndef AUDIO_DECODER_H
#define AUDIO_DECODER_H
#include "Common.h"
#include <utility>
#include <map>
#include <memory>
#include <exception>
namespace nqr
{
struct BaseDecoder
{
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) = 0;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) = 0;
virtual std::vector<std::string> GetSupportedFileExtensions() = 0;
virtual ~BaseDecoder() {}
};
typedef std::pair< std::string, std::shared_ptr<nqr::BaseDecoder> > DecoderPair;
class NyquistIO
{
std::string ParsePathForExtension(const std::string & path) const;
std::shared_ptr<nqr::BaseDecoder> GetDecoderForExtension(const std::string & ext);
void BuildDecoderTable();
void AddDecoderToTable(std::shared_ptr<nqr::BaseDecoder> decoder);
std::map< std::string, std::shared_ptr<BaseDecoder> > decoderTable;
NO_MOVE(NyquistIO);
public:
NyquistIO();
~NyquistIO();
void Load(AudioData * data, const std::string & path);
void Load(AudioData * data, const std::vector<uint8_t> & buffer);
void Load(AudioData * data, const std::string & extension, const std::vector<uint8_t> & buffer);
bool IsFileSupported(const std::string & path) const;
};
struct UnsupportedExtensionEx : public std::runtime_error { UnsupportedExtensionEx() : std::runtime_error("Unsupported file extension") {} };
struct LoadPathNotImplEx : public std::runtime_error { LoadPathNotImplEx() : std::runtime_error("Loading from path not implemented") {} };
struct LoadBufferNotImplEx : public std::runtime_error { LoadBufferNotImplEx() : std::runtime_error("Loading from buffer not implemented") {} };
struct WavDecoder final : public nqr::BaseDecoder
{
WavDecoder() = default;
virtual ~WavDecoder() {}
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override final;
virtual std::vector<std::string> GetSupportedFileExtensions() override final;
};
struct WavPackDecoder final : public nqr::BaseDecoder
{
WavPackDecoder() = default;
virtual ~WavPackDecoder() override {};
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override final;
virtual std::vector<std::string> GetSupportedFileExtensions() override final;
};
struct VorbisDecoder final : public nqr::BaseDecoder
{
VorbisDecoder() = default;
virtual ~VorbisDecoder() override {}
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override final;
virtual std::vector<std::string> GetSupportedFileExtensions() override final;
};
struct OpusDecoder final : public nqr::BaseDecoder
{
OpusDecoder() = default;
virtual ~OpusDecoder() override {}
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override final;
virtual std::vector<std::string> GetSupportedFileExtensions() override final;
};
struct MusepackDecoder final : public nqr::BaseDecoder
{
MusepackDecoder() = default;
virtual ~MusepackDecoder() override {};
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override final;
virtual std::vector<std::string> GetSupportedFileExtensions() override final;
};
struct Mp3Decoder final : public nqr::BaseDecoder
{
Mp3Decoder() = default;
virtual ~Mp3Decoder() override {};
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override final;
virtual std::vector<std::string> GetSupportedFileExtensions() override final;
};
struct FlacDecoder final : public nqr::BaseDecoder
{
FlacDecoder() = default;
virtual ~FlacDecoder() override {}
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override final;
virtual std::vector<std::string> GetSupportedFileExtensions() override final;
};
} // end namespace nqr
#endif

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:
@ -23,22 +23,47 @@ 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 NYQUIST_ENCODERS_H
#define NYQUIST_ENCODERS_H
#ifndef DITHER_OPERATIONS_H
#define DITHER_OPERATIONS_H
#include "Common.h"
#include <random>
namespace nqr
{
// A simplistic encoder that takes a buffer of audio, conforms it to the user's
// EncoderParams preference, and writes to disk. Be warned, does not support resampling!
// @todo support dithering, samplerate conversion, etc.
int encode_wav_to_disk(const EncoderParams p, const AudioData * d, const std::string & path);
// Assume data adheres to EncoderParams, except for bit depth and fmt which are re-formatted
// to satisfy the Ogg/Opus spec.
int encode_opus_to_disk(const EncoderParams p, const AudioData * d, const std::string & path);
enum DitherType
{
DITHER_NONE,
DITHER_TRIANGLE
};
class Dither
{
std::uniform_real_distribution<float> distribution;
std::mt19937 rndGen;
float prev = 0.0f;
DitherType d;
public:
Dither(DitherType d) : distribution(-0.5f, +0.5f), d(d) {}
float operator()(float s)
{
if (d == DITHER_TRIANGLE)
{
const float value = distribution(rndGen);
s = s + value - prev;
prev = value;
return s;
}
else
{
return s;
}
}
};
} // end namespace nqr
#endif // end NYQUIST_ENCODERS_H
#endif

@ -0,0 +1,65 @@
/*
Copyright (c) 2015, 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.
*/
#ifndef FLAC_DECODER_H
#define FLAC_DECODER_H
// http://lists.xiph.org/pipermail/flac-dev/2012-March/003276.html
#define FLAC__NO_DLL
#include "AudioDecoder.h"
#include <map>
namespace nqr
{
//@todo expose this in API
inline std::map<int, std::string> GetQualityTable()
{
return {
{ 0, "0 (Fastest)" },
{ 1, "1" },
{ 2, "2" },
{ 3, "3" },
{ 4, "4" },
{ 5, "5 (Default)" },
{ 6, "6" },
{ 7, "7" },
{ 8, "8 (Highest)" },
};
}
struct FlacDecoder final : public nqr::BaseDecoder
{
FlacDecoder() = default;
virtual ~FlacDecoder() override {}
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override final;
virtual std::vector<std::string> GetSupportedFileExtensions() override final;
};
} // end namespace nqr
#endif

@ -0,0 +1,141 @@
/*
Copyright (c) 2015, 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.
*/
#ifndef IMA4_UTIL_H
#define IMA4_UTIL_H
#include "AudioDecoder.h"
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 (int32_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
}
}
}
} // end namespace nqr
#endif

@ -0,0 +1,45 @@
/*
Copyright (c) 2015, 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.
*/
#ifndef MODPLUG_DECODER_H
#define MODPLUG_DECODER_H
#include "AudioDecoder.h"
namespace nqr
{
struct ModplugDecoder : public nqr::BaseDecoder
{
ModplugDecoder() {};
virtual ~ModplugDecoder() {};
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override;
virtual std::vector<std::string> GetSupportedFileExtensions() override;
};
} // end namespace nqr
#endif

@ -0,0 +1,45 @@
/*
Copyright (c) 2015, 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.
*/
#ifndef MUSEPACK_DECODER_H
#define MUSEPACK_DECODER_H
#include "AudioDecoder.h"
namespace nqr
{
struct MusepackDecoder final : public nqr::BaseDecoder
{
MusepackDecoder() = default;
virtual ~MusepackDecoder() override {};
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override final;
virtual std::vector<std::string> GetSupportedFileExtensions() override final;
};
} // end namespace nqr
#endif

@ -0,0 +1,50 @@
/*
Copyright (c) 2015, 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.
*/
#ifndef OPUS_DECODER_H
#define OPUS_DECODER_H
#include "AudioDecoder.h"
namespace nqr
{
// 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
struct OpusDecoder final : public nqr::BaseDecoder
{
OpusDecoder() = default;
virtual ~OpusDecoder() override {}
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override final;
virtual std::vector<std::string> GetSupportedFileExtensions() override final;
};
} // end namespace nqr
#endif

@ -0,0 +1,104 @@
/*
Copyright (c) 2015, 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.
*/
#ifndef POSTPROCESS_H
#define POSTPROCESS_H
#include <vector>
namespace nqr
{
template <typename T>
inline void DeinterleaveStereo(T * c1, T * c2, T const * src, size_t count)
{
auto src_end = src + count;
while (src != src_end)
{
*c1 = src[0];
*c2 = src[1];
c1++;
c2++;
src += 2;
}
}
template<typename T>
void InterleaveChannels(const T * src, T * dest, size_t numFramesPerChannel, size_t numChannels, size_t N)
{
for (size_t ch = 0; ch < numChannels; ch++)
{
size_t x = ch;
const T * srcChannel = &src[ch * numFramesPerChannel];
for(size_t i = 0; i < N; i++)
{
dest[x] = srcChannel[i];
x += numChannels;
}
}
}
template<typename T>
void DeinterleaveChannels(const T * src, T * dest, size_t numFramesPerChannel, size_t numChannels, size_t N)
{
for(size_t ch = 0; ch < numChannels; ch++)
{
size_t x = ch;
T *destChannel = &dest[ch * numFramesPerChannel];
for (size_t i = 0; i < N; i++)
{
destChannel[i] = (T) src[x];
x += numChannels;
}
}
}
template <typename T>
void StereoToMono(const T * src, T * dest, size_t N)
{
for (size_t i = 0, j = 0; i < N; i += 2, ++j)
{
dest[j] = (src[i] + src[i + 1]) / 2.0f;
}
}
template <typename T>
void MonoToStereo(const T * src, T * dest, size_t N)
{
for(size_t i = 0, j = 0; i < N; ++i, j += 2)
{
dest[j] = src[i];
dest[j + 1] = src[i];
}
}
inline void TrimSilenceInterleaved(std::vector<float> & buffer, float v, bool fromFront, bool fromEnd)
{
//@todo implement me!
}
} // end namespace nqr
#endif

@ -0,0 +1,84 @@
/*
Copyright (c) 2015, 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.
*/
#ifndef RIFF_UTILS_H
#define RIFF_UTILS_H
#include "Common.h"
#include "WavDecoder.h"
#include "Dither.h"
namespace nqr
{
/////////////////////
// Chunk utilities //
/////////////////////
struct EncoderParams
{
int channelCount;
PCMFormat targetFormat;
DitherType dither;
};
struct ChunkHeaderInfo
{
uint32_t offset; // Byte offset into chunk
uint32_t size; // Size of the chunk in bytes
};
inline uint32_t GenerateChunkCode(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
#ifdef ARCH_CPU_LITTLE_ENDIAN
return ((uint32_t) ((a) | ((b) << 8) | ((c) << 16) | (((uint32_t) (d)) << 24)));
#else
return ((uint32_t) ((((uint32_t) (a)) << 24) | ((b) << 16) | ((c) << 8) | (d)));
#endif
}
inline char * GenerateChunkCodeChar(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
auto chunk = GenerateChunkCode(a, b, c, d);
char * outArr = new char[4];
uint32_t t = 0x000000FF;
for(size_t i = 0; i < 4; i++)
{
outArr[i] = chunk & t;
chunk >>= 8;
}
return outArr;
}
ChunkHeaderInfo ScanForChunk(const std::vector<uint8_t> & fileData, uint32_t chunkMarker);
WaveChunkHeader MakeWaveHeader(const EncoderParams param, const int sampleRate);
} // end namespace nqr
#endif

@ -0,0 +1,44 @@
/*
Copyright (c) 2015, 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.
*/
#ifndef VORBIS_DECODER_H
#define VORBIS_DECODER_H
#include "AudioDecoder.h"
namespace nqr
{
struct VorbisDecoder final : public nqr::BaseDecoder
{
VorbisDecoder() = default;
virtual ~VorbisDecoder() override {}
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override final;
virtual std::vector<std::string> GetSupportedFileExtensions() override final;
};
} // end namespace nqr
#endif

@ -0,0 +1,182 @@
/*
Copyright (c) 2015, 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.
*/
#ifndef WAVE_DECODER_H
#define WAVE_DECODER_H
#include "AudioDecoder.h"
namespace nqr
{
enum WaveFormatCode
{
FORMAT_UNKNOWN = 0x0, // Unknown Wave Format
FORMAT_PCM = 0x1, // PCM Format
FORMAT_ADPCM = 0x2, // Microsoft ADPCM Format
FORMAT_IEEE = 0x3, // IEEE float/double
FORMAT_ALAW = 0x6, // 8-bit ITU-T G.711 A-law
FORMAT_MULAW = 0x7, // 8-bit ITU-T G.711 µ-law
FORMAT_IMA_ADPCM = 0x11, // IMA ADPCM Format
FORMAT_EXT = 0xFFFE // Set via subformat
};
struct RiffChunkHeader
{
uint32_t id_riff; // Chunk ID: 'RIFF'
uint32_t file_size; // Entire file in bytes
uint32_t id_wave; // Chunk ID: 'WAVE'
};
struct WaveChunkHeader
{
uint32_t fmt_id; // Chunk ID: 'fmt '
uint32_t chunk_size; // Size in bytes
uint16_t format; // Format code
uint16_t channel_count; // Num interleaved channels
uint32_t sample_rate; // SR
uint32_t data_rate; // Data rate
uint16_t frame_size; // 1 frame = channels * bits per sample (also known as block align)
uint16_t bit_depth; // Bits per sample
};
struct BextChunk
{
uint32_t fmt_id; // Chunk ID: 'bext'
uint32_t chunk_size; // Size in bytes
uint8_t description[256]; // Description of the sound (ascii)
uint8_t origin[32]; // Name of the originator (ascii)
uint8_t origin_ref[32]; // Reference of the originator (ascii)
uint8_t orgin_date[10]; // yyyy-mm-dd (ascii)
uint8_t origin_time[8]; // hh-mm-ss (ascii)
uint64_t time_ref; // First sample count since midnight
uint32_t version; // Version of the BWF
uint8_t uimd[64]; // Byte 0 of SMPTE UMID
uint8_t reserved[188]; // 190 bytes, reserved for future use & set to NULL
};
struct FactChunk
{
uint32_t fact_id; // Chunk ID: 'fact'
uint32_t chunk_size; // Size in bytes
uint32_t sample_length; // number of samples per channel
};
struct ExtensibleData
{
uint16_t size;
uint16_t valid_bits_per_sample;
uint32_t channel_mask;
struct GUID
{
uint32_t data0;
uint16_t data1;
uint16_t data2;
uint16_t data3;
uint8_t data4[6];
};
};
template<class C, class R>
std::basic_ostream<C,R> & operator << (std::basic_ostream<C,R> & a, const WaveChunkHeader & b)
{
return a <<
"Format ID:\t\t" << b.fmt_id <<
"\nChunk Size:\t\t" << b.chunk_size <<
"\nFormat Code:\t\t" << b.format <<
"\nChannels:\t\t" << b.channel_count <<
"\nSample Rate:\t\t" << b.sample_rate <<
"\nData Rate:\t\t" << b.data_rate <<
"\nFrame Size:\t\t" << b.frame_size <<
"\nBit Depth:\t\t" << b.bit_depth << std::endl;
}
//@todo expose speaker/channel/layout masks in the API:
enum SpeakerChannelMask
{
SPEAKER_FRONT_LEFT = 0x00000001,
SPEAKER_FRONT_RIGHT = 0x00000002,
SPEAKER_FRONT_CENTER = 0x00000004,
SPEAKER_LOW_FREQUENCY = 0x00000008,
SPEAKER_BACK_LEFT = 0x00000010,
SPEAKER_BACK_RIGHT = 0x00000020,
SPEAKER_FRONT_LEFT_OF_CENTER = 0x00000040,
SPEAKER_FRONT_RIGHT_OF_CENTER = 0x00000080,
SPEAKER_BACK_CENTER = 0x00000100,
SPEAKER_SIDE_LEFT = 0x00000200,
SPEAKER_SIDE_RIGHT = 0x00000400,
SPEAKER_TOP_CENTER = 0x00000800,
SPEAKER_TOP_FRONT_LEFT = 0x00001000,
SPEAKER_TOP_FRONT_CENTER = 0x00002000,
SPEAKER_TOP_FRONT_RIGHT = 0x00004000,
SPEAKER_TOP_BACK_LEFT = 0x00008000,
SPEAKER_TOP_BACK_CENTER = 0x00010000,
SPEAKER_TOP_BACK_RIGHT = 0x00020000,
SPEAKER_RESERVED = 0x7FFC0000,
SPEAKER_ALL = 0x80000000
};
enum SpeakerLayoutMask
{
SPEAKER_MONO = (SPEAKER_FRONT_CENTER),
SPEAKER_STEREO = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT),
SPEAKER_2POINT1 = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY),
SPEAKER_SURROUND = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER),
SPEAKER_QUAD = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT),
SPEAKER_4POINT1 = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT),
SPEAKER_5POINT1 = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT),
SPEAKER_7POINT1 = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER),
SPEAKER_5POINT1_SURROUND = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT),
SPEAKER_7POINT1_SURROUND = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT),
};
//@todo verify mask values
inline int ComputeChannelMask(const size_t channels)
{
switch (channels)
{
case 1: return SPEAKER_MONO;
case 2: return SPEAKER_STEREO;
case 3: return SPEAKER_2POINT1;
case 4: return SPEAKER_QUAD;
case 5: return SPEAKER_4POINT1;
case 6: return SPEAKER_5POINT1;
default: return -1;
}
}
struct WavDecoder final : public nqr::BaseDecoder
{
WavDecoder() = default;
virtual ~WavDecoder() {}
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override final;
virtual std::vector<std::string> GetSupportedFileExtensions() override final;
};
} // end namespace nqr
#endif

@ -0,0 +1,110 @@
/*
Copyright (c) 2015, 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.
*/
#ifndef WAVE_ENCODER_H
#define WAVE_ENCODER_H
#include "Common.h"
#include "WavDecoder.h"
#include "RiffUtils.h"
namespace nqr
{
// This is a naieve implementation of a resampling filter where a lerp is used as a bad low-pass.
// It very far from the ideal case and should be used with caution (or not at all) on signals that matter.
// It is included here to upsample 44.1k to 48k for the purposes of microphone input => Opus, where the the
// nominal frequencies of speech are particularly far from Nyquist.
static inline void linear_resample(const double rate, const std::vector<float> & input, std::vector<float> & output, size_t samplesToProcess)
{
double virtualReadIndex = 0;
double a, b, i, sample;
uint32_t n = samplesToProcess - 1;
while (n--)
{
uint32_t readIndex = static_cast<uint32_t>(virtualReadIndex);
i = virtualReadIndex - readIndex;
a = input[readIndex + 0];
b = input[readIndex + 1];
sample = (1.0 - i) * a + i * b; // linear interpolate
output.push_back(sample);
virtualReadIndex += rate;
}
}
static inline double sample_hermite_4p_3o(double x, double * y)
{
static double c0, c1, c2, c3;
c0 = y[1];
c1 = (1.0/2.0)*(y[2]-y[0]);
c2 = (y[0] - (5.0/2.0)*y[1]) + (2.0*y[2] - (1.0/2.0)*y[3]);
c3 = (1.0/2.0)*(y[3]-y[0]) + (3.0/2.0)*(y[1]-y[2]);
return ((c3*x+c2)*x+c1)*x+c0;
}
static inline void hermite_resample(const double rate, const std::vector<float> & input, std::vector<float> & output, size_t samplesToProcess)
{
double virtualReadIndex = 1;
double i, sample;
uint32_t n = samplesToProcess - 1;
while (n--)
{
uint32_t readIndex = static_cast<uint32_t>(virtualReadIndex);
i = virtualReadIndex - readIndex;
double samps[4] = {input[readIndex - 1], input[readIndex], input[readIndex + 1], input[readIndex + 2]};
sample = sample_hermite_4p_3o(i, samps); // cubic hermite interpolate over 4 samples
output.push_back(sample);
virtualReadIndex += rate;
}
}
enum EncoderError
{
NoError,
InsufficientSampleData,
FileIOError,
UnsupportedSamplerate,
UnsupportedChannelConfiguration,
UnsupportedBitdepth,
UnsupportedChannelMix,
BufferTooBig,
};
// A simplistic encoder that takes a blob of data, conforms it to the user's
// EncoderParams preference, and writes to disk. Be warned, does not support resampling!
// @todo support dithering, samplerate conversion, etc.
struct WavEncoder
{
// Assume data adheres to EncoderParams, except for bit depth and fmt
static int WriteFile(const EncoderParams p, const AudioData * d, const std::string & path);
};
struct OggOpusEncoder
{
static int WriteFile(const EncoderParams p, const AudioData * d, const std::string & path);
};
} // end namespace nqr
#endif

@ -0,0 +1,45 @@
/*
Copyright (c) 2015, 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.
*/
#ifndef WAVEPACK_DECODER_H
#define WAVEPACK_DECODER_H
#include "AudioDecoder.h"
namespace nqr
{
struct WavPackDecoder final : public nqr::BaseDecoder
{
WavPackDecoder() = default;
virtual ~WavPackDecoder() override {};
virtual void LoadFromPath(nqr::AudioData * data, const std::string & path) override final;
virtual void LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override final;
virtual std::vector<std::string> GetSupportedFileExtensions() override final;
};
} // end namespace nqr
#endif

@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnyquist", "libnyquist.vcxproj", "{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Debug|Win32.ActiveCfg = Debug|Win32
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Debug|Win32.Build.0 = Debug|Win32
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Debug|x64.ActiveCfg = Debug|x64
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Debug|x64.Build.0 = Debug|x64
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Release|Win32.ActiveCfg = Release|Win32
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Release|Win32.Build.0 = Release|Win32
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Release|x64.ActiveCfg = Release|x64
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(ProjectDir)..\..\src\AudioDecoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\Common.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\FlacDecoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\OpusDecoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\WavDecoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\WavPackDecoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\CafDecoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\FlacDependencies.c" />
<ClCompile Include="$(ProjectDir)..\..\src\OpusDependencies.c" />
<ClCompile Include="$(ProjectDir)..\..\src\VorbisDecoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\VorbisDependencies.c" />
<ClCompile Include="$(ProjectDir)..\..\src\WavEncoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\RiffUtils.cpp" />
<ClCompile Include="..\..\src\ModplugDecoder.cpp" />
<ClCompile Include="..\..\src\ModplugDependencies.cpp" />
<ClCompile Include="..\..\src\MusepackDecoder.cpp" />
<ClCompile Include="..\..\src\MusepackDependencies.c" />
<ClCompile Include="..\..\src\WavPackDependencies.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\AudioDecoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\FlacDecoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\OpusDecoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\PostProcess.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\WavDecoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\Common.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\Dither.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\WavPackDecoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\CafDecoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\VorbisDecoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\WavEncoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\RiffUtils.h" />
<ClInclude Include="..\..\include\libnyquist\IMA4Util.h" />
<ClInclude Include="..\..\include\libnyquist\MusepackDecoder.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}</ProjectGuid>
<RootNamespace>libaudiodata</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_MBCS;D_SCL_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNING;WIN32;_WIN32;USE_ALLOCA;OPUS_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\third_party\;$(ProjectDir)..\..\include\libnyquist\;$(ProjectDir)..\..\third_party\libvorbis\include;$(ProjectDir)..\..\third_party\libogg\include;$(ProjectDir)..\..\third_party\wavpack\include;$(ProjectDir)..\..\third_party\flac\src\include;$(ProjectDir)..\..\third_party\opus\celt;$(ProjectDir)..\..\third_party\opus\libopus\include;$(ProjectDir)..\..\third_party\opus\libopus\src;$(ProjectDir)..\..\third_party\opus\opusfile\include;$(ProjectDir)..\..\third_party\opus\opusfile\src;$(ProjectDir)..\..\third_party\opus\opusfile\src\include;$(ProjectDir)..\..\third_party\opus\silk;$(ProjectDir)..\..\third_party\opus\silk\float;$(ProjectDir)..\..\third_party\musepack\include;$(ProjectDir)..\..\third_party\musepack\libmpcenc;$(ProjectDir)..\..\third_party\musepack\libmpcdec;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_MBCS;D_SCL_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNING;WIN32;_WIN32;USE_ALLOCA;OPUS_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\third_party\;$(ProjectDir)..\..\include\libnyquist\;$(ProjectDir)..\..\third_party\libvorbis\include;$(ProjectDir)..\..\third_party\libogg\include;$(ProjectDir)..\..\third_party\wavpack\include;$(ProjectDir)..\..\third_party\flac\src\include;$(ProjectDir)..\..\third_party\opus\celt;$(ProjectDir)..\..\third_party\opus\libopus\include;$(ProjectDir)..\..\third_party\opus\libopus\src;$(ProjectDir)..\..\third_party\opus\opusfile\include;$(ProjectDir)..\..\third_party\opus\opusfile\src;$(ProjectDir)..\..\third_party\opus\opusfile\src\include;$(ProjectDir)..\..\third_party\opus\silk;$(ProjectDir)..\..\third_party\opus\silk\float;$(ProjectDir)..\..\third_party\musepack\include;$(ProjectDir)..\..\third_party\musepack\libmpcenc;$(ProjectDir)..\..\third_party\musepack\libmpcdec;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_MBCS;D_SCL_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNING;WIN32;_WIN32;USE_ALLOCA;OPUS_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\third_party\;$(ProjectDir)..\..\include\libnyquist\;$(ProjectDir)..\..\third_party\libvorbis\include;$(ProjectDir)..\..\third_party\libogg\include;$(ProjectDir)..\..\third_party\wavpack\include;$(ProjectDir)..\..\third_party\flac\src\include;$(ProjectDir)..\..\third_party\opus\celt;$(ProjectDir)..\..\third_party\opus\libopus\include;$(ProjectDir)..\..\third_party\opus\libopus\src;$(ProjectDir)..\..\third_party\opus\opusfile\include;$(ProjectDir)..\..\third_party\opus\opusfile\src;$(ProjectDir)..\..\third_party\opus\opusfile\src\include;$(ProjectDir)..\..\third_party\opus\silk;$(ProjectDir)..\..\third_party\opus\silk\float;$(ProjectDir)..\..\third_party\musepack\include;$(ProjectDir)..\..\third_party\musepack\libmpcenc;$(ProjectDir)..\..\third_party\musepack\libmpcdec;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_MBCS;D_SCL_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNING;WIN32;_WIN32;USE_ALLOCA;OPUS_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\third_party\;$(ProjectDir)..\..\include\libnyquist\;$(ProjectDir)..\..\third_party\libvorbis\include;$(ProjectDir)..\..\third_party\libogg\include;$(ProjectDir)..\..\third_party\wavpack\include;$(ProjectDir)..\..\third_party\flac\src\include;$(ProjectDir)..\..\third_party\opus\celt;$(ProjectDir)..\..\third_party\opus\libopus\include;$(ProjectDir)..\..\third_party\opus\libopus\src;$(ProjectDir)..\..\third_party\opus\opusfile\include;$(ProjectDir)..\..\third_party\opus\opusfile\src;$(ProjectDir)..\..\third_party\opus\opusfile\src\include;$(ProjectDir)..\..\third_party\opus\silk;$(ProjectDir)..\..\third_party\opus\silk\float;$(ProjectDir)..\..\third_party\musepack\include;$(ProjectDir)..\..\third_party\musepack\libmpcenc;$(ProjectDir)..\..\third_party\musepack\libmpcdec;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="$(ProjectDir)..\..\src\VorbisDependencies.c">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\OpusDependencies.c">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\AudioDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\CafDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\FlacDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\VorbisDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\WavDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\WavPackDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\WavEncoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\OpusDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\Common.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\RiffUtils.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\FlacDependencies.c">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="..\..\src\MusepackDependencies.c">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="..\..\src\MusepackDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\src\WavPackDependencies.c">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ModplugDependencies.cpp">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ModplugDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\OpusDecoder.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\AudioDecoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\CafDecoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\Common.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\FlacDecoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\VorbisDecoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\WavDecoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\WavEncoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\WavPackDecoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\PostProcess.h">
<Filter>include\util</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\Dither.h">
<Filter>include\util</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\RiffUtils.h">
<Filter>include\util</Filter>
</ClInclude>
<ClInclude Include="..\..\include\libnyquist\MusepackDecoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\libnyquist\IMA4Util.h">
<Filter>include\util</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="include">
<UniqueIdentifier>{f4ea8340-b8ea-4a42-bafb-6cb461e7a2f3}</UniqueIdentifier>
</Filter>
<Filter Include="src">
<UniqueIdentifier>{a18b19d5-5cd3-49fc-beec-ed17d8e81d6b}</UniqueIdentifier>
</Filter>
<Filter Include="include\util">
<UniqueIdentifier>{f27e7823-c56c-4e03-af63-2ef0b1e83cbd}</UniqueIdentifier>
</Filter>
<Filter Include="src\deps">
<UniqueIdentifier>{d839471f-71d1-471e-95e0-c33af9bb64bc}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnyquist", "libnyquist.vcxproj", "{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Debug|Win32.ActiveCfg = Debug|Win32
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Debug|Win32.Build.0 = Debug|Win32
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Debug|x64.ActiveCfg = Debug|x64
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Debug|x64.Build.0 = Debug|x64
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Release|Win32.ActiveCfg = Release|Win32
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Release|Win32.Build.0 = Release|Win32
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Release|x64.ActiveCfg = Release|x64
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

@ -0,0 +1,163 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(ProjectDir)..\..\src\AudioDecoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\Common.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\FlacDecoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\OpusDecoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\WavDecoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\WavPackDecoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\FlacDependencies.c" />
<ClCompile Include="$(ProjectDir)..\..\src\OpusDependencies.c" />
<ClCompile Include="$(ProjectDir)..\..\src\VorbisDecoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\VorbisDependencies.c" />
<ClCompile Include="$(ProjectDir)..\..\src\WavEncoder.cpp" />
<ClCompile Include="$(ProjectDir)..\..\src\RiffUtils.cpp" />
<ClCompile Include="..\..\src\ModplugDecoder.cpp" />
<ClCompile Include="..\..\src\ModplugDependencies.cpp" />
<ClCompile Include="..\..\src\MusepackDecoder.cpp" />
<ClCompile Include="..\..\src\MusepackDependencies.c" />
<ClCompile Include="..\..\src\WavPackDependencies.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\AudioDecoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\FlacDecoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\OpusDecoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\PostProcess.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\WavDecoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\Common.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\Dither.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\WavPackDecoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\VorbisDecoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\WavEncoder.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\RiffUtils.h" />
<ClInclude Include="..\..\include\libnyquist\IMA4Util.h" />
<ClInclude Include="..\..\include\libnyquist\MusepackDecoder.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}</ProjectGuid>
<RootNamespace>libaudiodata</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_MBCS;D_SCL_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNING;WIN32;_WIN32;USE_ALLOCA;OPUS_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\third_party\;$(ProjectDir)..\..\include\libnyquist\;$(ProjectDir)..\..\third_party\libvorbis\include;$(ProjectDir)..\..\third_party\libogg\include;$(ProjectDir)..\..\third_party\wavpack\include;$(ProjectDir)..\..\third_party\flac\src\include;$(ProjectDir)..\..\third_party\opus\celt;$(ProjectDir)..\..\third_party\opus\libopus\include;$(ProjectDir)..\..\third_party\opus\libopus\src;$(ProjectDir)..\..\third_party\opus\opusfile\include;$(ProjectDir)..\..\third_party\opus\opusfile\src;$(ProjectDir)..\..\third_party\opus\opusfile\src\include;$(ProjectDir)..\..\third_party\opus\silk;$(ProjectDir)..\..\third_party\opus\silk\float;$(ProjectDir)..\..\third_party\musepack\include;$(ProjectDir)..\..\third_party\musepack\libmpcenc;$(ProjectDir)..\..\third_party\musepack\libmpcdec;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_MBCS;D_SCL_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNING;WIN32;_WIN32;USE_ALLOCA;OPUS_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\third_party\;$(ProjectDir)..\..\include\libnyquist\;$(ProjectDir)..\..\third_party\libvorbis\include;$(ProjectDir)..\..\third_party\libogg\include;$(ProjectDir)..\..\third_party\wavpack\include;$(ProjectDir)..\..\third_party\flac\src\include;$(ProjectDir)..\..\third_party\opus\celt;$(ProjectDir)..\..\third_party\opus\libopus\include;$(ProjectDir)..\..\third_party\opus\libopus\src;$(ProjectDir)..\..\third_party\opus\opusfile\include;$(ProjectDir)..\..\third_party\opus\opusfile\src;$(ProjectDir)..\..\third_party\opus\opusfile\src\include;$(ProjectDir)..\..\third_party\opus\silk;$(ProjectDir)..\..\third_party\opus\silk\float;$(ProjectDir)..\..\third_party\musepack\include;$(ProjectDir)..\..\third_party\musepack\libmpcenc;$(ProjectDir)..\..\third_party\musepack\libmpcdec;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_MBCS;D_SCL_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNING;WIN32;_WIN32;USE_ALLOCA;OPUS_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\third_party\;$(ProjectDir)..\..\include\libnyquist\;$(ProjectDir)..\..\third_party\libvorbis\include;$(ProjectDir)..\..\third_party\libogg\include;$(ProjectDir)..\..\third_party\wavpack\include;$(ProjectDir)..\..\third_party\flac\src\include;$(ProjectDir)..\..\third_party\opus\celt;$(ProjectDir)..\..\third_party\opus\libopus\include;$(ProjectDir)..\..\third_party\opus\libopus\src;$(ProjectDir)..\..\third_party\opus\opusfile\include;$(ProjectDir)..\..\third_party\opus\opusfile\src;$(ProjectDir)..\..\third_party\opus\opusfile\src\include;$(ProjectDir)..\..\third_party\opus\silk;$(ProjectDir)..\..\third_party\opus\silk\float;$(ProjectDir)..\..\third_party\musepack\include;$(ProjectDir)..\..\third_party\musepack\libmpcenc;$(ProjectDir)..\..\third_party\musepack\libmpcdec;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_MBCS;D_SCL_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNING;WIN32;_WIN32;USE_ALLOCA;OPUS_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\third_party\;$(ProjectDir)..\..\include\libnyquist\;$(ProjectDir)..\..\third_party\libvorbis\include;$(ProjectDir)..\..\third_party\libogg\include;$(ProjectDir)..\..\third_party\wavpack\include;$(ProjectDir)..\..\third_party\flac\src\include;$(ProjectDir)..\..\third_party\opus\celt;$(ProjectDir)..\..\third_party\opus\libopus\include;$(ProjectDir)..\..\third_party\opus\libopus\src;$(ProjectDir)..\..\third_party\opus\opusfile\include;$(ProjectDir)..\..\third_party\opus\opusfile\src;$(ProjectDir)..\..\third_party\opus\opusfile\src\include;$(ProjectDir)..\..\third_party\opus\silk;$(ProjectDir)..\..\third_party\opus\silk\float;$(ProjectDir)..\..\third_party\musepack\include;$(ProjectDir)..\..\third_party\musepack\libmpcenc;$(ProjectDir)..\..\third_party\musepack\libmpcdec;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="$(ProjectDir)..\..\src\VorbisDependencies.c">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\OpusDependencies.c">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\AudioDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\FlacDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\VorbisDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\WavDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\WavPackDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\WavEncoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\OpusDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\Common.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\RiffUtils.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\src\FlacDependencies.c">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="..\..\src\MusepackDependencies.c">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="..\..\src\MusepackDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\src\WavPackDependencies.c">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ModplugDependencies.cpp">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ModplugDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\OpusDecoder.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\AudioDecoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\Common.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\FlacDecoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\VorbisDecoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\WavDecoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\WavEncoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\WavPackDecoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\PostProcess.h">
<Filter>include\util</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\Dither.h">
<Filter>include\util</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\RiffUtils.h">
<Filter>include\util</Filter>
</ClInclude>
<ClInclude Include="..\..\include\libnyquist\MusepackDecoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\libnyquist\IMA4Util.h">
<Filter>include\util</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="include">
<UniqueIdentifier>{f4ea8340-b8ea-4a42-bafb-6cb461e7a2f3}</UniqueIdentifier>
</Filter>
<Filter Include="src">
<UniqueIdentifier>{a18b19d5-5cd3-49fc-beec-ed17d8e81d6b}</UniqueIdentifier>
</Filter>
<Filter Include="include\util">
<UniqueIdentifier>{f27e7823-c56c-4e03-af63-2ef0b1e83cbd}</UniqueIdentifier>
</Filter>
<Filter Include="src\deps">
<UniqueIdentifier>{d839471f-71d1-471e-95e0-c33af9bb64bc}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

@ -0,0 +1,476 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
0804D13F1AE69F0100F4B1FD /* OpusDependencies.c in Sources */ = {isa = PBXBuildFile; fileRef = 0804D13E1AE69F0100F4B1FD /* OpusDependencies.c */; };
080A58581B0866F600302850 /* RiffUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 080A58571B0866F600302850 /* RiffUtils.cpp */; };
081FFB191ADF803800673073 /* FlacDependencies.c in Sources */ = {isa = PBXBuildFile; fileRef = 081FFB181ADF803800673073 /* FlacDependencies.c */; };
083730B91BE52B9600216BDC /* MusepackDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 083730B81BE52B9600216BDC /* MusepackDecoder.cpp */; settings = {COMPILER_FLAGS = "-w"; }; };
083730BC1BE5350C00216BDC /* MusepackDependencies.c in Sources */ = {isa = PBXBuildFile; fileRef = 083730BB1BE5350C00216BDC /* MusepackDependencies.c */; };
083DB3F31B091C1100FB0661 /* WavEncoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 083DB3F21B091C1100FB0661 /* WavEncoder.cpp */; };
086DADAD1AE029860031F793 /* VorbisDependencies.c in Sources */ = {isa = PBXBuildFile; fileRef = 086DADAB1ADF9DF30031F793 /* VorbisDependencies.c */; };
08B91D9A1AC73B8A00335131 /* CafDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D901AC73B8A00335131 /* CafDecoder.cpp */; };
08B91D9B1AC73B8A00335131 /* AudioDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D911AC73B8A00335131 /* AudioDecoder.cpp */; };
08B91D9D1AC73B8A00335131 /* Common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D931AC73B8A00335131 /* Common.cpp */; };
08B91D9E1AC73B8A00335131 /* FlacDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D941AC73B8A00335131 /* FlacDecoder.cpp */; };
08B91DA01AC73B8A00335131 /* VorbisDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D961AC73B8A00335131 /* VorbisDecoder.cpp */; };
08B91DA11AC73B8A00335131 /* OpusDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D971AC73B8A00335131 /* OpusDecoder.cpp */; };
08B91DA21AC73B8A00335131 /* WavDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D981AC73B8A00335131 /* WavDecoder.cpp */; };
08B91DA31AC73B8A00335131 /* WavPackDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D991AC73B8A00335131 /* WavPackDecoder.cpp */; };
08D0EC751C6DA41300FCDA23 /* WavPackDependencies.c in Sources */ = {isa = PBXBuildFile; fileRef = 08D0EC741C6DA41300FCDA23 /* WavPackDependencies.c */; };
08FFC72D1CA702EC005812D6 /* ModplugDependencies.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08FFC72C1CA702EC005812D6 /* ModplugDependencies.cpp */; };
08FFC72F1CA7038D005812D6 /* ModplugDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08FFC72E1CA7038D005812D6 /* ModplugDecoder.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
08B91D241AC26FC100335131 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
0804D13E1AE69F0100F4B1FD /* OpusDependencies.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = OpusDependencies.c; path = src/OpusDependencies.c; sourceTree = SOURCE_ROOT; };
080A58561B0866AA00302850 /* RiffUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RiffUtils.h; path = include/libnyquist/RiffUtils.h; sourceTree = SOURCE_ROOT; };
080A58571B0866F600302850 /* RiffUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RiffUtils.cpp; path = src/RiffUtils.cpp; sourceTree = SOURCE_ROOT; };
081FFB181ADF803800673073 /* FlacDependencies.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = FlacDependencies.c; path = src/FlacDependencies.c; sourceTree = SOURCE_ROOT; };
083730B81BE52B9600216BDC /* MusepackDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MusepackDecoder.cpp; path = src/MusepackDecoder.cpp; sourceTree = SOURCE_ROOT; };
083730BA1BE52BA900216BDC /* MusepackDecoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MusepackDecoder.h; path = include/libnyquist/MusepackDecoder.h; sourceTree = SOURCE_ROOT; };
083730BB1BE5350C00216BDC /* MusepackDependencies.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = MusepackDependencies.c; path = src/MusepackDependencies.c; sourceTree = SOURCE_ROOT; };
083DB3F21B091C1100FB0661 /* WavEncoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WavEncoder.cpp; path = src/WavEncoder.cpp; sourceTree = SOURCE_ROOT; };
083DB3F41B091C1E00FB0661 /* WavEncoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WavEncoder.h; path = include/libnyquist/WavEncoder.h; sourceTree = SOURCE_ROOT; };
086DADAB1ADF9DF30031F793 /* VorbisDependencies.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = VorbisDependencies.c; path = src/VorbisDependencies.c; sourceTree = SOURCE_ROOT; };
08B91D261AC26FC100335131 /* libnyquist.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libnyquist.a; sourceTree = BUILT_PRODUCTS_DIR; };
08B91D831AC73B8000335131 /* CafDecoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CafDecoder.h; path = include/libnyquist/CafDecoder.h; sourceTree = SOURCE_ROOT; };
08B91D841AC73B8000335131 /* AudioDecoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AudioDecoder.h; path = include/libnyquist/AudioDecoder.h; sourceTree = SOURCE_ROOT; };
08B91D851AC73B8000335131 /* AudioDevice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AudioDevice.h; path = include/libnyquist/AudioDevice.h; sourceTree = SOURCE_ROOT; };
08B91D861AC73B8000335131 /* Common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Common.h; path = include/libnyquist/Common.h; sourceTree = SOURCE_ROOT; };
08B91D871AC73B8000335131 /* Dither.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Dither.h; path = include/libnyquist/Dither.h; sourceTree = SOURCE_ROOT; };
08B91D881AC73B8000335131 /* FlacDecoder.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = FlacDecoder.h; path = include/libnyquist/FlacDecoder.h; sourceTree = SOURCE_ROOT; };
08B91D891AC73B8000335131 /* VorbisDecoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VorbisDecoder.h; path = include/libnyquist/VorbisDecoder.h; sourceTree = SOURCE_ROOT; };
08B91D8A1AC73B8000335131 /* OpusDecoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OpusDecoder.h; path = include/libnyquist/OpusDecoder.h; sourceTree = SOURCE_ROOT; };
08B91D8B1AC73B8000335131 /* PostProcess.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PostProcess.h; path = include/libnyquist/PostProcess.h; sourceTree = SOURCE_ROOT; };
08B91D8C1AC73B8000335131 /* RingBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RingBuffer.h; path = include/libnyquist/RingBuffer.h; sourceTree = SOURCE_ROOT; };
08B91D8E1AC73B8000335131 /* WavDecoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WavDecoder.h; path = include/libnyquist/WavDecoder.h; sourceTree = SOURCE_ROOT; };
08B91D8F1AC73B8000335131 /* WavPackDecoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WavPackDecoder.h; path = include/libnyquist/WavPackDecoder.h; sourceTree = SOURCE_ROOT; };
08B91D901AC73B8A00335131 /* CafDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CafDecoder.cpp; path = src/CafDecoder.cpp; sourceTree = SOURCE_ROOT; };
08B91D911AC73B8A00335131 /* AudioDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioDecoder.cpp; path = src/AudioDecoder.cpp; sourceTree = SOURCE_ROOT; };
08B91D931AC73B8A00335131 /* Common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Common.cpp; path = src/Common.cpp; sourceTree = SOURCE_ROOT; };
08B91D941AC73B8A00335131 /* FlacDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FlacDecoder.cpp; path = src/FlacDecoder.cpp; sourceTree = SOURCE_ROOT; };
08B91D961AC73B8A00335131 /* VorbisDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VorbisDecoder.cpp; path = src/VorbisDecoder.cpp; sourceTree = SOURCE_ROOT; };
08B91D971AC73B8A00335131 /* OpusDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpusDecoder.cpp; path = src/OpusDecoder.cpp; sourceTree = SOURCE_ROOT; };
08B91D981AC73B8A00335131 /* WavDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WavDecoder.cpp; path = src/WavDecoder.cpp; sourceTree = SOURCE_ROOT; };
08B91D991AC73B8A00335131 /* WavPackDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WavPackDecoder.cpp; path = src/WavPackDecoder.cpp; sourceTree = SOURCE_ROOT; };
08C83B7C1C25D7780071EED6 /* IMA4Util.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IMA4Util.h; path = include/libnyquist/IMA4Util.h; sourceTree = SOURCE_ROOT; };
08D0EC741C6DA41300FCDA23 /* WavPackDependencies.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = WavPackDependencies.c; path = src/WavPackDependencies.c; sourceTree = SOURCE_ROOT; };
08FFC72C1CA702EC005812D6 /* ModplugDependencies.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ModplugDependencies.cpp; path = src/ModplugDependencies.cpp; sourceTree = SOURCE_ROOT; };
08FFC72E1CA7038D005812D6 /* ModplugDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ModplugDecoder.cpp; path = src/ModplugDecoder.cpp; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
08B91D231AC26FC100335131 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
080A58551B083D5100302850 /* deps */ = {
isa = PBXGroup;
children = (
08FFC72C1CA702EC005812D6 /* ModplugDependencies.cpp */,
08D0EC741C6DA41300FCDA23 /* WavPackDependencies.c */,
081FFB181ADF803800673073 /* FlacDependencies.c */,
086DADAB1ADF9DF30031F793 /* VorbisDependencies.c */,
0804D13E1AE69F0100F4B1FD /* OpusDependencies.c */,
083730BB1BE5350C00216BDC /* MusepackDependencies.c */,
);
name = deps;
sourceTree = "<group>";
};
080A58591B0867E500302850 /* util */ = {
isa = PBXGroup;
children = (
08B91D871AC73B8000335131 /* Dither.h */,
080A58561B0866AA00302850 /* RiffUtils.h */,
08B91D8C1AC73B8000335131 /* RingBuffer.h */,
08B91D8B1AC73B8000335131 /* PostProcess.h */,
);
name = util;
sourceTree = "<group>";
};
08B91D1D1AC26FC100335131 = {
isa = PBXGroup;
children = (
08B91D281AC26FC100335131 /* libnyquist */,
08B91D511AC270BB00335131 /* third_party */,
08B91D801AC73B3B00335131 /* Frameworks */,
08B91D271AC26FC100335131 /* Products */,
);
sourceTree = "<group>";
};
08B91D271AC26FC100335131 /* Products */ = {
isa = PBXGroup;
children = (
08B91D261AC26FC100335131 /* libnyquist.a */,
);
name = Products;
sourceTree = "<group>";
};
08B91D281AC26FC100335131 /* libnyquist */ = {
isa = PBXGroup;
children = (
08B91D811AC73B5A00335131 /* include */,
08B91D821AC73B6900335131 /* src */,
);
path = libnyquist;
sourceTree = "<group>";
};
08B91D511AC270BB00335131 /* third_party */ = {
isa = PBXGroup;
children = (
);
name = third_party;
path = libnyquist;
sourceTree = "<group>";
};
08B91D801AC73B3B00335131 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
08B91D811AC73B5A00335131 /* include */ = {
isa = PBXGroup;
children = (
080A58591B0867E500302850 /* util */,
08B91D841AC73B8000335131 /* AudioDecoder.h */,
08B91D851AC73B8000335131 /* AudioDevice.h */,
08B91D861AC73B8000335131 /* Common.h */,
08B91D831AC73B8000335131 /* CafDecoder.h */,
083730BA1BE52BA900216BDC /* MusepackDecoder.h */,
08B91D881AC73B8000335131 /* FlacDecoder.h */,
08B91D891AC73B8000335131 /* VorbisDecoder.h */,
08B91D8A1AC73B8000335131 /* OpusDecoder.h */,
083DB3F41B091C1E00FB0661 /* WavEncoder.h */,
08B91D8E1AC73B8000335131 /* WavDecoder.h */,
08B91D8F1AC73B8000335131 /* WavPackDecoder.h */,
08C83B7C1C25D7780071EED6 /* IMA4Util.h */,
);
name = include;
sourceTree = "<group>";
};
08B91D821AC73B6900335131 /* src */ = {
isa = PBXGroup;
children = (
080A58551B083D5100302850 /* deps */,
08B91D901AC73B8A00335131 /* CafDecoder.cpp */,
083730B81BE52B9600216BDC /* MusepackDecoder.cpp */,
08B91D911AC73B8A00335131 /* AudioDecoder.cpp */,
08B91D931AC73B8A00335131 /* Common.cpp */,
080A58571B0866F600302850 /* RiffUtils.cpp */,
08FFC72E1CA7038D005812D6 /* ModplugDecoder.cpp */,
08B91D941AC73B8A00335131 /* FlacDecoder.cpp */,
08B91D961AC73B8A00335131 /* VorbisDecoder.cpp */,
08B91D971AC73B8A00335131 /* OpusDecoder.cpp */,
083DB3F21B091C1100FB0661 /* WavEncoder.cpp */,
08B91D981AC73B8A00335131 /* WavDecoder.cpp */,
08B91D991AC73B8A00335131 /* WavPackDecoder.cpp */,
);
name = src;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
08B91D251AC26FC100335131 /* libnyquist */ = {
isa = PBXNativeTarget;
buildConfigurationList = 08B91D2D1AC26FC100335131 /* Build configuration list for PBXNativeTarget "libnyquist" */;
buildPhases = (
08B91D221AC26FC100335131 /* Sources */,
08B91D231AC26FC100335131 /* Frameworks */,
08B91D241AC26FC100335131 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = libnyquist;
productName = libnyquist;
productReference = 08B91D261AC26FC100335131 /* libnyquist.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08B91D1E1AC26FC100335131 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0720;
ORGANIZATIONNAME = "Dimitri Diakopoulos";
TargetAttributes = {
08B91D251AC26FC100335131 = {
CreatedOnToolsVersion = 6.1.1;
};
};
};
buildConfigurationList = 08B91D211AC26FC100335131 /* Build configuration list for PBXProject "libnyquist" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 08B91D1D1AC26FC100335131;
productRefGroup = 08B91D271AC26FC100335131 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
08B91D251AC26FC100335131 /* libnyquist */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
08B91D221AC26FC100335131 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
083730B91BE52B9600216BDC /* MusepackDecoder.cpp in Sources */,
083730BC1BE5350C00216BDC /* MusepackDependencies.c in Sources */,
081FFB191ADF803800673073 /* FlacDependencies.c in Sources */,
0804D13F1AE69F0100F4B1FD /* OpusDependencies.c in Sources */,
083DB3F31B091C1100FB0661 /* WavEncoder.cpp in Sources */,
08B91D9B1AC73B8A00335131 /* AudioDecoder.cpp in Sources */,
08B91DA01AC73B8A00335131 /* VorbisDecoder.cpp in Sources */,
08B91DA21AC73B8A00335131 /* WavDecoder.cpp in Sources */,
08B91D9A1AC73B8A00335131 /* CafDecoder.cpp in Sources */,
080A58581B0866F600302850 /* RiffUtils.cpp in Sources */,
08B91DA11AC73B8A00335131 /* OpusDecoder.cpp in Sources */,
08FFC72D1CA702EC005812D6 /* ModplugDependencies.cpp in Sources */,
08B91D9E1AC73B8A00335131 /* FlacDecoder.cpp in Sources */,
08FFC72F1CA7038D005812D6 /* ModplugDecoder.cpp in Sources */,
08D0EC751C6DA41300FCDA23 /* WavPackDependencies.c in Sources */,
086DADAD1AE029860031F793 /* VorbisDependencies.c in Sources */,
08B91DA31AC73B8A00335131 /* WavPackDecoder.cpp in Sources */,
08B91D9D1AC73B8A00335131 /* Common.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
08B91D2B1AC26FC100335131 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
08B91D2C1AC26FC100335131 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
};
name = Release;
};
08B91D2E1AC26FC100335131 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
EXECUTABLE_EXTENSION = a;
EXECUTABLE_PREFIX = "";
GCC_CHAR_IS_UNSIGNED_CHAR = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_BUILTIN_FUNCTIONS = YES;
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_INPUT_FILETYPE = automatic;
GCC_LINK_WITH_DYNAMIC_LIBRARIES = YES;
GCC_NO_COMMON_BLOCKS = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
__MACOSX_CORE__,
USE_ALLOCA,
OPUS_BUILD,
);
GCC_STRICT_ALIASING = NO;
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/include/libnyquist",
"$(SRCROOT)/third_party",
"$(SRCROOT)/third_party/rtaudio",
"$(SRCROOT)/third_party/flac/src/include",
"$(SRCROOT)/third_party/libogg/include",
"$(SRCROOT)/third_party/libvorbis/src",
"$(SRCROOT)/third_party/libvorbis/include",
"$(SRCROOT)/third_party/opus/silk",
"$(SRCROOT)/third_party/opus/silk/float",
"$(SRCROOT)/third_party/opus/celt",
"$(SRCROOT)/third_party/opus/libopus/include",
"$(SRCROOT)/third_party/opus/opusfile/src/include",
"$(SRCROOT)/third_party/opus/opusfile/include",
"$(SRCROOT)/third_party/wavpack/include",
"$(SRCROOT)/third_party/wavpack/src",
"$(SRCROOT)/third_party/musepack/include",
"$(SRCROOT)/third_party/musepack/libmpcdec",
"$(SRCROOT)/third_party/libmodplug/src",
);
PRODUCT_NAME = "$(TARGET_NAME)";
SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES;
};
name = Debug;
};
08B91D2F1AC26FC100335131 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
EXECUTABLE_EXTENSION = a;
EXECUTABLE_PREFIX = "";
GCC_CHAR_IS_UNSIGNED_CHAR = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_BUILTIN_FUNCTIONS = YES;
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_INPUT_FILETYPE = automatic;
GCC_LINK_WITH_DYNAMIC_LIBRARIES = YES;
GCC_NO_COMMON_BLOCKS = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
__MACOSX_CORE__,
USE_ALLOCA,
OPUS_BUILD,
);
GCC_STRICT_ALIASING = NO;
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/include/libnyquist",
"$(SRCROOT)/third_party",
"$(SRCROOT)/third_party/rtaudio",
"$(SRCROOT)/third_party/flac/src/include",
"$(SRCROOT)/third_party/libogg/include",
"$(SRCROOT)/third_party/libvorbis/src",
"$(SRCROOT)/third_party/libvorbis/include",
"$(SRCROOT)/third_party/opus/silk",
"$(SRCROOT)/third_party/opus/silk/float",
"$(SRCROOT)/third_party/opus/celt",
"$(SRCROOT)/third_party/opus/libopus/include",
"$(SRCROOT)/third_party/opus/opusfile/src/include",
"$(SRCROOT)/third_party/opus/opusfile/include",
"$(SRCROOT)/third_party/wavpack/include",
"$(SRCROOT)/third_party/wavpack/src",
"$(SRCROOT)/third_party/musepack/include",
"$(SRCROOT)/third_party/musepack/libmpcdec",
"$(SRCROOT)/third_party/libmodplug/src",
);
PRODUCT_NAME = "$(TARGET_NAME)";
SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
08B91D211AC26FC100335131 /* Build configuration list for PBXProject "libnyquist" */ = {
isa = XCConfigurationList;
buildConfigurations = (
08B91D2B1AC26FC100335131 /* Debug */,
08B91D2C1AC26FC100335131 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
08B91D2D1AC26FC100335131 /* Build configuration list for PBXNativeTarget "libnyquist" */ = {
isa = XCConfigurationList;
buildConfigurations = (
08B91D2E1AC26FC100335131 /* Debug */,
08B91D2F1AC26FC100335131 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 08B91D1E1AC26FC100335131 /* Project object */;
}

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:libnyquist.xcodeproj">
</FileRef>
</Workspace>

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "08B91D251AC26FC100335131"
BuildableName = "libnyquist.a"
BlueprintName = "libnyquist"
ReferencedContainer = "container:libnyquist.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "08B91D251AC26FC100335131"
BuildableName = "libnyquist.a"
BlueprintName = "libnyquist"
ReferencedContainer = "container:libnyquist.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "YES"
customWorkingDirectory = "$(PROJECT_DIR)"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "08B91D251AC26FC100335131"
BuildableName = "libnyquist.a"
BlueprintName = "libnyquist"
ReferencedContainer = "container:libnyquist.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "08B91D251AC26FC100335131"
BuildableName = "libnyquist.a"
BlueprintName = "libnyquist"
ReferencedContainer = "container:libnyquist.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

@ -0,0 +1,8 @@
## MIDI Player Functionality
A SoundFont `.sf2` file is a file that contains many samples of different instruments playing different notes, enabling Libnyquist to render finally each instrument sound in the MIDI song. SoundFonts are available on the web, but the quality and size varies a lot, and they may have licensing issues (because of the copyright of the different samples), they may be designed for different styles of music (classical, jazz, pop...), and they may target different sets of instruments as well. As a general rule, most MIDI files are targeted to use the 128 sounds of [General MIDI standard (GM)](http://en.wikipedia.org/wiki/General_MIDI), so use a SoundFont that does conform to this standard. You probably want to try the [Fluid R3 GM (141 MB uncompressed)](http://google.com/search?q=Fluid+R3+GM+soundfont) as a starter pack, which is a very good general purpose SoundFont (and fully MIT licensed).
SoundFont files are large and often compressed in `.zip`, `.tar.gz` or `.sfArk` formats. `.sfArk` files can be unpacked with [sfark tool](http://www.melodymachine.com/sfark.htm). For now, libnyquist supports `.pat` (GUS) soundfonts only, which can be converted from `.sf2` files with the [unsf tool](http://alsa.opensrc.org/Unsf).
Back to the library, the compiler directive `PAT_CONFIG_FILE` tells libnyquist what soundfont file is hardcoded by default (defaults to `pat/timidity.cfg`, but might be `FluidR3_GM2/FluidR3_GM2-2.cfg`, or any other valid path during compilation). Additionally, there is a runtime check for the environment variable `MMPAT_PATH_TO_CFG`, which contains the path to the config file. For more info please check [this source file](third_party/libmodplug/src/load_pat.cpp)

@ -0,0 +1,177 @@
/*
Copyright (c) 2015, 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 "AudioDecoder.h"
#include "WavDecoder.h"
#include "WavPackDecoder.h"
#include "FlacDecoder.h"
#include "VorbisDecoder.h"
#include "OpusDecoder.h"
#include "MusepackDecoder.h"
#include "ModplugDecoder.h"
#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 << "Caught internal exception: " << e.what() << std::endl;
}
}
else throw std::runtime_error("No available decoders.");
}
else
{
throw UnsupportedExtensionEx();
}
}
void NyquistIO::Load(AudioData * data, const std::vector<uint8_t> & buffer)
{
const std::vector<int16_t> wv = { 'w', 'v', 'p', 'k' };
const std::vector<int16_t> wav = { 0x52, 0x49, 0x46, 0x46, -0x1, -0x1, -0x11, -0x1, 0x57, 0x41, 0x56, 0x45 };
const std::vector<int16_t> flac = { 0x66, 0x4C, 0x61, 0x43 };
const std::vector<int16_t> pat = { 0x47, 0x50, 0x41, 0x54 };
const std::vector<int16_t> opus = { 'O', 'p', 'u', 's', 'H', 'e', 'a', 'd' };
const std::vector<int16_t> ogg = { 0x4F, 0x67, 0x67, 0x53, 0x00, 0x02, 0x00, 0x00 };
const std::vector<int16_t> mid = { 0x4D, 0x54, 0x68, 0x64 };
auto match_magic = [](const uint8_t * data, const int16_t * magic)
{
for (int i = 0; magic[i] != -2; i++)
{
if (magic[i] >= 0 && data[i] != magic[i]) return false;
}
return true;
};
static const int16_t * numbers[] = { wv, wav, flac, pat, mid, opus, ogg, nullptr };
static const char* extensions[] = { "wv", "wav", "flac", "pat", "mid", "opus", "ogg" };
for (int i = 0; numbers[i] != nullptr; i++)
{
if (match_magic(data, numbers[i])) {
return extensions[i];
}
}
}
// With a known file extension
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 exception: " << e.what() << std::endl;
}
}
else
{
throw std::runtime_error("No available decoders.");
}
}
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<ModplugDecoder>());
}

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:
@ -24,165 +24,9 @@ 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;
@ -260,10 +104,9 @@ void nqr::ConvertToFloat32(float * dst, const uint8_t * src, const size_t N, PCM
else if (f == PCM_FLT)
{
std::memcpy(dst, src, N * sizeof(float));
/* const float * dataPtr = reinterpret_cast<const float *>(src);
const float * dataPtr = reinterpret_cast<const float *>(src);
for (size_t i = 0; i < N; ++i)
dst[i] = (float) Read32(dataPtr[i]); */
dst[i] = (float) Read32(dataPtr[i]);
}
else if (f == PCM_DBL)
{

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:
@ -23,26 +23,27 @@ 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 "FlacDecoder.h"
#include "flac/all.h"
#include "flac/stream_decoder.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>
#include "AudioDecoder.h"
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)
// FLAC is a big-endian format. All values are unsigned.
FlacDecoderInternal(AudioData * d, std::string filepath) : d(d)
{
/////////////////////////////
// Initialize FLAC library //
/////////////////////////////
decoderInternal = FLAC__stream_decoder_new();
FLAC__stream_decoder_set_metadata_respond(decoderInternal, FLAC__METADATA_TYPE_STREAMINFO);
@ -57,48 +58,9 @@ public:
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);
//////////////////////
// Read Stream Data //
/////////////////////
if (initialized)
{
@ -119,7 +81,12 @@ public:
// 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");
else
{
throw std::runtime_error("Unable to initialize FLAC decoder");
}
}
~FlacDecoderInternal()
@ -154,14 +121,16 @@ public:
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++)
for(int j = 0; j < decoder->d->channelCount; j++)
{
std::memcpy(dataPtr + decoder->bufferPosition, &buffer[j][i], bytesPerSample);
memcpy(dataPtr + decoder->bufferPosition, &buffer[j][i], bytesPerSample);
decoder->bufferPosition += bytesPerSample;
}
}
@ -176,51 +145,7 @@ public:
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();
std::cerr << "FLAC Decoder Error: " << FLAC__StreamDecoderErrorStatusString[status] << std::endl;
}
private:
@ -228,8 +153,7 @@ private:
NO_COPY(FlacDecoderInternal);
FLAC__StreamDecoder * decoderInternal;
std::vector<uint8_t> data;
size_t dataPos;
size_t bufferPosition = 0;
size_t numSamples = 0;
@ -249,7 +173,7 @@ void FlacDecoder::LoadFromPath(AudioData * data, const std::string & path)
void FlacDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
{
FlacDecoderInternal decoder(data, memory);
throw LoadBufferNotImplEx();
}
std::vector<std::string> FlacDecoder::GetSupportedFileExtensions()

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:
@ -77,25 +77,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define HAVE_LROUND 1
#include "FLAC/all.h"
#include "flac/all.h"
#if defined(_WIN32) || defined(_WIN64)
#include "FLAC/src/win_utf8_io.c"
#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"
#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

@ -0,0 +1,131 @@
/*
Copyright (c) 2016, 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 "ModplugDecoder.h"
using namespace nqr;
#ifndef MODPLUG_STATIC
#define MODPLUG_STATIC
#endif
#include "libmodplug/src/modplug.h"
class ModplugInternal
{
public:
ModplugInternal(AudioData * d, const std::vector<uint8_t> & fileData) : d(d)
{
ModPlug_Settings mps;
ModPlug_GetSettings(&mps);
mps.mChannels = 2;
mps.mBits = 32;
mps.mFrequency = 44100;
mps.mResamplingMode = MODPLUG_RESAMPLE_FIR; //_LINEAR, _SPLINE
mps.mStereoSeparation = 128;
mps.mMaxMixChannels = 64;
mps.mLoopCount = 0; // forever: -1;
mps.mFlags = MODPLUG_ENABLE_OVERSAMPLING; // _NOISE_REDUCTION, _REVERB, _MEGABASS, _SURROUND
ModPlug_SetSettings(&mps);
mpf = ModPlug_Load((const void*)fileData.data(), fileData.size());
if (!mpf)
{
throw std::runtime_error("could not load module");
}
d->sampleRate = 44100;
d->channelCount = 2;
d->sourceFormat = MakeFormatForBits(32, true, false);
auto len_ms = ModPlug_GetLength(mpf);
d->lengthSeconds = (double) len_ms / 1000.0;
auto totalSamples = (44100LL * len_ms) / 1000;
d->samples.resize(totalSamples * d->channelCount);
auto readInternal = [&]()
{
const float invf = 1 / (float)0x7fffffff;
float *ptr = d->samples.data();
float *end = d->samples.data() + d->samples.size();
while( ptr < end ) {
int res = ModPlug_Read( mpf, (void*)ptr, (end - ptr) * sizeof(float) );
int samples_read = res / (sizeof(float) * 2);
if( totalSamples < samples_read ) {
samples_read = totalSamples;
}
for( int i = 0; i < samples_read; ++i ) {
*ptr++ = *((int*)ptr) * invf;
*ptr++ = *((int*)ptr) * invf;
}
totalSamples -= samples_read;
}
return ptr >= end;
};
if (!readInternal())
throw std::runtime_error("could not read any data");
ModPlug_Unload(mpf);
}
private:
ModPlugFile* mpf;
NO_MOVE(ModplugInternal);
AudioData * d;
};
//////////////////////
// Public Interface //
//////////////////////
void ModplugDecoder::LoadFromPath(AudioData * data, const std::string & path)
{
auto fileBuffer = nqr::ReadFile(path);
ModplugInternal decoder(data, fileBuffer.buffer);
}
void ModplugDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
{
ModplugInternal decoder(data, memory);
}
std::vector<std::string> ModplugDecoder::GetSupportedFileExtensions()
{
return {"pat","mid", "mod","s3m","xm","it","669","amf","ams","dbm","dmf","dsm","far","mdl","med","mtm","okt","ptm","stm","ult","umx","mt2","psm"};
}

@ -0,0 +1,102 @@
/*
Copyright (c) 2016, 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"
#define HAVE_SETENV
#endif
#ifndef MODPLUG_STATIC
#define MODPLUG_STATIC
#endif
#define HAVE_SINF
#include "libmodplug/src/load_669.cpp"
#include "libmodplug/src/load_abc.cpp"
#include "libmodplug/src/load_amf.cpp"
#include "libmodplug/src/load_ams.cpp"
#include "libmodplug/src/load_dbm.cpp"
#include "libmodplug/src/load_dmf.cpp"
#include "libmodplug/src/load_dsm.cpp"
#include "libmodplug/src/load_far.cpp"
#include "libmodplug/src/load_it.cpp"
#include "libmodplug/src/load_j2b.cpp"
#include "libmodplug/src/load_mdl.cpp"
#include "libmodplug/src/load_med.cpp"
#define none none_alt
#define MMFILE MMFILE_alt
#define mmfseek mmfseek_alt
#define mmftell mmftell_alt
#define mmreadUBYTES mmreadUBYTES_alt
#include "libmodplug/src/load_mid.cpp"
#include "libmodplug/src/load_mod.cpp"
#include "libmodplug/src/load_mt2.cpp"
#include "libmodplug/src/load_mtm.cpp"
#include "libmodplug/src/load_okt.cpp"
#undef MMFILE
#undef mmfseek
#undef mmftell
#undef mmreadUBYTES
#define MMFILE MMFILE_alt2
#define mmfseek mmfseek_alt2
#define mmftell mmftell_alt2
#define mmreadUBYTES mmreadUBYTES_alt2
#include "libmodplug/src/load_pat.cpp"
#include "libmodplug/src/load_psm.cpp"
#include "libmodplug/src/load_ptm.cpp"
#include "libmodplug/src/load_s3m.cpp"
#include "libmodplug/src/load_stm.cpp"
#include "libmodplug/src/load_ult.cpp"
#include "libmodplug/src/load_umx.cpp"
#include "libmodplug/src/load_wav.cpp"
#include "libmodplug/src/load_xm.cpp"
#include "libmodplug/src/mmcmp.cpp"
#include "libmodplug/src/modplug.cpp"
#include "libmodplug/src/sndfile.cpp"
#include "libmodplug/src/sndmix.cpp"
#include "libmodplug/src/fastmix.cpp"
#include "libmodplug/src/snd_dsp.cpp"
#include "libmodplug/src/snd_flt.cpp"
#include "libmodplug/src/snd_fx.cpp"
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#if (_MSC_VER)
#pragma warning (pop)
#endif

@ -1,80 +0,0 @@
/*
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 <cstdlib>
#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);
std::free(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"};
}

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:
@ -23,7 +23,7 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Decoders.h"
#include "MusepackDecoder.h"
using namespace nqr;
@ -110,7 +110,9 @@ public:
reader.tell = tell_mem;
mpcDemux = mpc_demux_init(&reader);
if (!mpcDemux) throw std::runtime_error("could not initialize mpc demuxer");
if (!mpcDemux)
throw std::runtime_error("could not initialize mpc demuxer");
mpc_demux_get_info(mpcDemux, &streamInfo);

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:
@ -23,19 +23,13 @@ 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 "OpusDecoder.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
{

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:

@ -0,0 +1,66 @@
/*
Copyright (c) 2015, 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 "RiffUtils.h"
using namespace nqr;
ChunkHeaderInfo nqr::ScanForChunk(const std::vector<uint8_t> & fileData, uint32_t chunkMarker)
{
// D[n] aligned to 16 bytes now
const uint16_t * d = reinterpret_cast<const uint16_t *>(fileData.data());
for (size_t i = 0; i < fileData.size() / sizeof(uint16_t); i++)
{
// This will be in machine endianess
uint32_t m = Pack(Read16(d[i]), Read16(d[i+1]));
if (m == chunkMarker)
{
uint32_t cSz = Pack(Read16(d[i+2]), Read16(d[i+3]));
return {(uint32_t (i * sizeof(uint16_t))), cSz}; // return i in bytes to the start of the data
}
else continue;
}
return {0, 0};
};
WaveChunkHeader nqr::MakeWaveHeader(const EncoderParams param, const int sampleRate)
{
WaveChunkHeader header;
int bitdepth = GetFormatBitsPerSample(param.targetFormat);
header.fmt_id = GenerateChunkCode('f', 'm', 't', ' ');
header.chunk_size = 16;
header.format = (param.targetFormat <= PCMFormat::PCM_32) ? WaveFormatCode::FORMAT_PCM : WaveFormatCode::FORMAT_IEEE;
header.channel_count = param.channelCount;
header.sample_rate = sampleRate;
header.data_rate = sampleRate * param.channelCount * (bitdepth / 8);
header.frame_size = param.channelCount * (bitdepth / 8);
header.bit_depth = bitdepth;
return header;
}

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:
@ -23,11 +23,9 @@ 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 "VorbisDecoder.h"
#include "libvorbis/include/vorbis/vorbisfile.h"
#include <string.h>
using namespace nqr;
class VorbisDecoderInternal

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:
@ -23,116 +23,12 @@ 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>
#include "WavDecoder.h"
#include "RiffUtils.h"
#include "IMA4Util.h"
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 //
//////////////////////
@ -220,7 +116,10 @@ void WavDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & m
bool grabExtensibleData = false;
bool adpcmEncoded = false;
if (wavHeader.format == WaveFormatCode::FORMAT_IEEE)
if (wavHeader.format == WaveFormatCode::FORMAT_PCM)
{
}
else if (wavHeader.format == WaveFormatCode::FORMAT_IEEE)
{
scanForFact = true;
}
@ -231,7 +130,8 @@ void WavDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & m
}
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;
// Used when (1) PCM data has more than 16 bits; (2) channels > 2; (3) bits/sample !== container size; (4) channel/speaker mapping specified
//std::cout << "[format id] extended" << std::endl;
scanForFact = true;
grabExtensibleData = true;
}
@ -300,7 +200,7 @@ void WavDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & m
uint32_t frameOffset = 0;
uint32_t frameCount = DataChunkInfo.size / s.frame_size;
for (uint32_t i = 0; i < frameCount; ++i)
for (int i = 0; i < frameCount; ++i)
{
decode_ima_adpcm(s, adpcm_pcm16.data() + frameOffset, wavHeader.channel_count);
s.inBuffer += s.frame_size;

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:
@ -23,26 +23,26 @@ 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>
#include "WavEncoder.h"
using namespace nqr;
static inline void to_bytes(uint8_t value, char * arr)
{
arr[0] = (value) & 0xFF;
arr[0] = (value)& 0xFF;
}
static inline void to_bytes(uint16_t value, char * arr)
{
arr[0] = (value) & 0xFF;
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[0] = (value)& 0xFF;
arr[1] = (value >> 8) & 0xFF;
arr[2] = (value >> 16) & 0xFF;
arr[3] = (value >> 24) & 0xFF;
}
@ -51,10 +51,9 @@ static inline void to_bytes(uint32_t value, char * arr)
// Wave File Encoding //
////////////////////////////
int nqr::encode_wav_to_disk(const EncoderParams p, const AudioData * d, const std::string & path)
int WavEncoder::WriteFile(const EncoderParams p, const AudioData * d, const std::string & path)
{
if (!d->samples.size())
return EncoderError::InsufficientSampleData;
assert(d->samples.size() > 0);
// Cast away const because we know what we are doing (Hopefully?)
float * sampleData = const_cast<float *>(d->samples.data());
@ -80,23 +79,32 @@ int nqr::encode_wav_to_disk(const EncoderParams p, const AudioData * d, const st
sampleDataOptionalMix.resize(sampleDataSize * 2);
MonoToStereo(sampleData, sampleDataOptionalMix.data(), sampleDataSize); // Mix
// Re-point data
// 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
// Re-point data
sampleData = sampleDataOptionalMix.data();
sampleDataSize = sampleDataOptionalMix.size();
}
else if (d->channelCount == p.channelCount) { /* do nothing */ }
else return EncoderError::UnsupportedChannelMix;
}
else if (d->channelCount == p.channelCount)
{
// No op
}
else
{
return EncoderError::UnsupportedChannelMix;
}
// -- End Channel Mixing
auto maxFileSizeInBytes = std::numeric_limits<uint32_t>::max();
@ -139,7 +147,9 @@ int nqr::encode_wav_to_disk(const EncoderParams p, const AudioData * d, const st
auto sourceBits = GetFormatBitsPerSample(d->sourceFormat);
auto targetBits = GetFormatBitsPerSample(p.targetFormat);
//@todo - channel mixing!
////////////////////////////
//@todo - channel mixing! //
////////////////////////////
// Write out fact chunk
if (p.targetFormat == PCM_FLT)
@ -387,14 +397,15 @@ public:
return true;
}
};
#define OPUS_MAX_PACKET_SIZE (1024 * 8)
#define OPUS_FRAME_SIZE 960
// Opus only supports a 48k samplerate...
// Opus only supports a 48k samplerate... M
// 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)
int OggOpusEncoder::WriteFile(const EncoderParams p, const AudioData * d, const std::string & path)
{
assert(d->samples.size() > 0);
//assert(d->sampleRate == 48000);

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Copyright (c) 2015, 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:
@ -23,10 +23,8 @@ 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 "WavPackDecoder.h"
#include "wavpack.h"
#include <string.h>
#include <cstring>
using namespace nqr;
@ -35,36 +33,50 @@ class WavPackInternal
public:
WavPackInternal(AudioData * d, const std::string & path) : d(d)
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)
if (!context)
{
throw std::runtime_error("Not a WavPack file");
}
auto totalSamples = wph.total_samples;
auto bitdepth = WavpackGetBitsPerSample(context);
d->sampleRate = WavpackGetSampleRate(context);
d->channelCount = WavpackGetNumChannels(context);
d->lengthSeconds = double(getLengthInSeconds());
d->frameSize = d->channelCount * bitdepth;
//@todo support channel masks
// WavpackGetChannelMask
auto totalSamples = size_t(getTotalSamples());
int mode = WavpackGetMode(context);
bool isFloatingPoint = (MODE_FLOAT & mode);
d->sourceFormat = MakeFormatForBits(bitdepth, isFloatingPoint, false);
/* From the docs:
"... required memory at "buffer" is 4 * samples * num_channels bytes. The
audio data is returned right-justified in 32-bit longs in the endian
mode native to the executing processor."
*/
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);
decode(totalSamples);
}
~WavPackInternal()
@ -77,6 +89,8 @@ public:
size_t framesRemaining = requestedFrameCount;
size_t totalFramesRead = 0;
// int frameSize = d->channelCount * WavpackGetBitsPerSample(context);
// The samples returned are handled differently based on the file's mode
int mode = WavpackGetMode(context);
@ -97,7 +111,8 @@ public:
}
// EOF
//if (framesRead == 0) break;
//if (framesRead == 0)
// break;
totalFramesRead += framesRead;
framesRemaining -= framesRead;
@ -107,59 +122,6 @@ public:
}
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);
@ -187,7 +149,7 @@ void WavPackDecoder::LoadFromPath(AudioData * data, const std::string & path)
void WavPackDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
{
WavPackInternal decoder(data, memory);
throw LoadBufferNotImplEx();
}
std::vector<std::string> WavPackDecoder::GetSupportedFileExtensions()

@ -0,0 +1,68 @@
/*
Copyright (c) 2015, 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 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
#ifdef _WIN32
#ifndef WIN32
#define WIN32
#endif
#endif
#include "wavpack/src/bits.c"
#include "wavpack/src/extra1.c"
#define WavpackExtraInfo WavpackExtraInfo_alt
#define log2overhead log2overhead_alt
#define xtable xtable_alt
#include "wavpack/src/extra2.c"
#include "wavpack/src/float.c"
#include "wavpack/src/metadata.c"
#define decorr_stereo_pass decorr_stereo_pass_alt
#include "wavpack/src/pack.c"
#include "wavpack/src/tags.c"
#undef decorr_stereo_pass
#define decorr_stereo_pass decorr_stereo_pass_alt_2
#include "wavpack/src/unpack.c"
#include "wavpack/src/unpack3.c"
#include "wavpack/src/words.c"
#include "wavpack/src/wputils.c"
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#if (_MSC_VER)
#pragma warning (pop)
#endif

Binary file not shown.

File diff suppressed because it is too large Load Diff

@ -61,12 +61,12 @@
#define flac_min(a,b) __min(a,b)
#endif
#ifndef flac_min
#define flac_min(x,y) ((x) <= (y) ? (x) : (y))
#ifndef MIN
#define MIN(x,y) ((x) <= (y) ? (x) : (y))
#endif
#ifndef flac_max
#define flac_max(x,y) ((x) >= (y) ? (x) : (y))
#ifndef MAX
#define MAX(x,y) ((x) >= (y) ? (x) : (y))
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save