Compare commits

...

147 Commits

Author SHA1 Message Date
Dimitri Diakopoulos 59a51e440c
Merge pull request #51 from 4321ba/master
fix compilation with mingw
5 years ago
Dimitri Diakopoulos 3d700fa04c
Merge pull request #55 from phniix/fix_memory_leak_with_free
Fixes #54
5 years ago
pheonix xx 54893b008c The memory allocated for info.buffer has been done with malloc(). 5 years ago
1234ab ae7c538ed4 Merge remote-tracking branch 'upstream/master' 5 years ago
Nick Porcino 244afdd52e Bump cmake version to 3.13 to get modern behavior for policy 0077 for inclusion as a subproject 5 years ago
1234ab f8774aba54 fix compilation with mingw 5 years ago
Nick Porcino b05d6931ae Make libopus build optional, as libopus is built statically into libnyquist already 5 years ago
Dimitri Diakopoulos 8ab792f803
Merge pull request #48 from mallgrab/fixmemoryleak
Fix memory leak when decoding mp3 file.
5 years ago
Dimitri Diakopoulos 0ea4f700ba
Merge pull request #47 from mallgrab/updatemp3headers
Update minimp3 headers.
5 years ago
mallgrab addc37778e Fix memory leak when decoding mp3 file. 5 years ago
mallgrab 86780f2998 Update minimp3 headers. 5 years ago
Dimitri Diakopoulos fa4e1e37c3
Merge pull request #45 from mikeperri/fix-in-memory-wavpack
Fix in-memory WavPack decoding
6 years ago
Mike 73951ef531 Add example for in-memory WavPack decoding 6 years ago
Mike d22c529fd2 Load in-memory WavPack files using WavpackOpenRawDecoder function 6 years ago
Dimitri Diakopoulos 8bb474473f
Merge pull request #43 from phniix/Issue42-LoadFromBuffer_avert_silently_handled_exception
Fixes ddiakopoulos/libnyquist#42
6 years ago
pheonix 55404f6ef6 Fixes ddiakopoulos/libnyquist#42
This aids in rethrowing exceptions from callers wanting to:
- void NyquistIO::Load(AudioData * data, const std::vector<uint8_t> & buffer)
- void NyquistIO::Load(AudioData * data, const std::string & extension, const std::vector<uint8_t> & buffer)

where std::exceptions are not raised by the catch on:
97d71768ef/src/Common.cpp (L135)
6 years ago
Nick Porcino 97d71768ef encode_wave_to_disk should report an empty data buffer instead of asserting 6 years ago
Nick Porcino f94005c398 Make error reporting a bit more informative, rethrow a caught exception 6 years ago
Nick Porcino 726cdf26df Don't add libopus demo programs to the libopus library 6 years ago
Nick Porcino 95c3e7f7db Fix source_group typo 7 years ago
Dimitri Diakopoulos c8db659724
Merge pull request #38 from ArthurSonzogni/master
Populate the PUBLIC and PRIVATE interface of libnyquist
7 years ago
Nick Porcino 6a88f291ea Update for building on iOS 7 years ago
ArthurSonzogni 12f60ab575 Fix flac_min/flac_max not defined with Emscripten.
When the compiler doesn't match the ones expected, flac_min/flac_max
aren't defined. There is a fallback to always define them, but MIN/MAX
were defined instead of flac_min/flac_max

This commit is the same as the one is the original FLAC project:
https://github.com/xiph/flac/blob/master/src/libFLAC/include/private/macros.h
7 years ago
ArthurSonzogni 7d2044f645 Populate the PUBLIC and PRIVATE interface of libnyquist
When linking against libnyquist:
 + include its public headers in the PUBLIC interface.
 + include its libraries dependencies in the PRIVATE interface.

Along the way, update the linkage of the examples, it was made PUBLIC
unnecessarily, it is an executable, it won't be linked against another
target.
7 years ago
Nick Porcino ae0f455615 Port examples to Mac 7 years ago
dimitri d372227a91 fix accidental last-minute keyboard macro that changed the file to lowercase 7 years ago
dimitri 49ab009115 tab->space file normalization 7 years ago
dimitri dafe5969ae public api addition: implement magic number detection so file extension strings do not need to be passed alongside in-memory audio files 7 years ago
Nick Porcino f760776a79 Allow libnyquist install location to be set from command line 7 years ago
Nick Porcino 73bf914788 port libnyquist samples to linux- cmake fix 7 years ago
Nick Porcino 9eef7cf964 Port libnyquist to ubuntu by tweaking the cmake files 7 years ago
Dimitri Diakopoulos 850cc66d9d
added travis build badge to readme 7 years ago
dimitri 782d5455d2 Minor changes across codebase for TravisCI integration to build on
OSX/Clang and Linux/GCC.
7 years ago
Nick Porcino 7aa6d409e0 Fix gcc build 7 years ago
dimitri ba979acdab minimal travis 7 years ago
dimitri e046ec27f1 further simplify 7 years ago
dimitri 56e6b387c1 reduce the number of public header files 7 years ago
dimitri 09c15110dc minor example updates 7 years ago
dimitri b00efee0eb merge 7 years ago
dimitri ae019f1943 readme updates 7 years ago
dimitri acaf19d97e implement basic mp3 decoding using public-domain minimp3 library 7 years ago
dimitri a909deff2f added stub file for mp3 decoding 7 years ago
dimitri 1fa96191ab remove modplug support (not a regularly tested decoder, hard to maintain) 7 years ago
dimitri 84a48bb861 update appveyor for cmake build; minor cmake adjustments 7 years ago
dimitri d3a523b262 minor 7 years ago
dimitri 15fce17ef6 update copyright notices 7 years ago
Dimitri Diakopoulos 5d761413b2
Merge pull request #35 from meshula/why-no-link
fix link via cmake
7 years ago
Nick Porcino 9f63cc9bfd fix link via cmake 7 years ago
dimitri 28695aa4eb cmake issues 7 years ago
Nick Porcino b6b71dd349 Fix debug iterator issue 8 years ago
dimitri 3857ab49e9 merge with modulesio/master 8 years ago
dimitri af0720ba97 update appveyor to point to VS2017 project 8 years ago
dimitri c8e8eda859 test in-memory decoding of ogg 8 years ago
dimitri 6640c054cf cleanup remnants of cafdecoder; additional final/default qualifiers on derived BaseDevocer classes; coding style 8 years ago
dimitri 99250daf6c core audio format will likely never be implemented/supported in libnyquist; remove stub files 8 years ago
dimitri c1881be5c7 virtual destructor on BaseDecoder 8 years ago
dimitri c1a0f1c44a vorbis decoder style/formatting 8 years ago
dimitri 4bd46b2458 update example project to VS2017 8 years ago
Dimitri Diakopoulos 207f451664
Merge pull request #33 from raub/oggmem
implemented OGG decoding from memory
8 years ago
Luis Blanco baf7ef85a3 implemented OGG decoding from memory 8 years ago
Avaer Kazmer b6ad5b49c0 Bugfix vorbis decoder seeking 8 years ago
Avaer Kazmer 2ce6909240 Add move semantics to memory buffer decoders 8 years ago
Avaer Kazmer 9ce7f0cf34 Wavpack library dead files cleanup 8 years ago
Avaer Kazmer e0d696e5df Add missing wavpack dependencies to windows VS solution 8 years ago
Avaer Kazmer 773b4a2ed7 Remove dead WavPackDependencies.c from windows VS solution 8 years ago
Avaer Kazmer c30da7146d Remove dead WavPackDependenies binding file 8 years ago
Avaer Kazmer b7affaf20e Bugfix vorbis decoder missing return value 8 years ago
Avaer Kazmer bcbcecf039 Add buffer wabpack decoder 8 years ago
Avaer Kazmer f9dfa28dab Add flac buffer decoder 8 years ago
Avaer Kazmer 978f702927 Small vorbis decoder cleanup 8 years ago
Avaer Kazmer 168fc5be6d Update wavpack library source 8 years ago
Avaer Kazmer e0f36dac15 Add vorbis decoder callbacks support 8 years ago
Adrian Biedrzycki a303147a07 Bugfix floating point sample load 8 years ago
Adrian Biedrzycki 8a141449ab Bugfix extern MixSoundBuffer size subscript 8 years ago
Adrian Biedrzycki d8853d2ebb Bugfix missing extern declarations in libmodplug 8 years ago
Adrian Biedrzycki 40db0e641c Bugfix missing libogg ogg/config_types.h include 8 years ago
Adrian Biedrzycki e27f888021 Move flac to FLAC 8 years ago
Avaer Kazmer 83ac466283 Update VS project 8 years ago
dimitri 258f5ad21f vs2017 project 8 years ago
Nick Porcino 6e39d17b01 Fix xcodeproj 8 years ago
dimitri 77938cd0be remove RtAudio & AudioDevice dependency from core library; move into sample project 9 years ago
dimitri e3f4a9e61c nuke visual studio 2013 projects 9 years ago
Dimitri Diakopoulos 82939a2228 hermite resampling just for fun 10 years ago
Dimitri Diakopoulos dcd2d1200f comment about the linear resample function 10 years ago
Dimitri Diakopoulos a7d9fbfbd7 optimize the linear resampler 10 years ago
Dimitri Diakopoulos 55db08501b cleanup broken commit and enable testing with microphone to opus path 10 years ago
Dimitri Diakopoulos 97c2b2cd56 space normalization 10 years ago
Dimitri Diakopoulos ce56c943b9 the most basic, generally not-correct linear interpolating resampling filter 10 years ago
Dimitri Diakopoulos 892c798f9f various ogg encoder cleanups 10 years ago
Dimitri Diakopoulos 2ca4e517dd working opus encoder 10 years ago
Dimitri Diakopoulos 2cc87ce652 setup for testing; fix misnamed fields in opus encoder header generation 10 years ago
Dimitri Diakopoulos 75ca01d34f initial inner loop of opus encode 10 years ago
Dimitri Diakopoulos f273e7d98c ogg stream write function 10 years ago
Dimitri Diakopoulos e898e362f6 fixes 10 years ago
Dimitri Diakopoulos aa297174ec oggwriter (header + tags) for opus 10 years ago
Dimitri Diakopoulos 4da74edd43 disambiguate OpusEncoder and begin implementing encoding functionality 10 years ago
Dimitri Diakopoulos 4019cdee22 appropriate the wave encoding files for opus encoding prototype (stub functionality for now) 10 years ago
Dimitri Diakopoulos 494c0ab9ec debug cleanup 10 years ago
Dimitri Diakopoulos 20d12d7f97 simple recording functionality for later encoding tests 10 years ago
Dimitri Diakopoulos 26713c3fd8 add rtaudio params for audio device input 10 years ago
Dimitri 30456b1515 libmodplug fixes for windows; added to vs2015 solution 10 years ago
Dimitri Diakopoulos 3a043a977d Update README.md 10 years ago
Dimitri Diakopoulos d5193f8491 readme 10 years ago
Dimitri Diakopoulos 9d0ecda104 order 10 years ago
Dimitri Diakopoulos 3f3a1ee208 link fix 10 years ago
Dimitri Diakopoulos da21ce45d6 readme 10 years ago
Dimitri Diakopoulos 26cbf1c671 remove libmodplug extra detritus 10 years ago
Dimitri Diakopoulos add218eeaa update xcode project for libmodplug support 10 years ago
Dimitri Diakopoulos cfadf538fc update for osx/clang compile 10 years ago
Dimitri Diakopoulos 0c5e915ed5 update COPYING file for libmodplug 10 years ago
Dimitri Diakopoulos 0ecaa2e918 Merge pull request #16 from r-lyeh/master
modplug decoder: multichannel + midi support
10 years ago
r-lyeh f0bab5eee0 Update README.md 10 years ago
r-lyeh 868ec9f2d6 add support for non-timidity soundfonts (like Fluid R3) 10 years ago
r-lyeh fbd87c0752 modplug decoder: multichannel + midi support 10 years ago
Dimitri Diakopoulos e90db5b8cd update vs2013 10 years ago
Dimitri 5c2ef85aae fix 2015 solution file 10 years ago
Dimitri cc5b3aceb6 update appveyor 10 years ago
Dimitri c04a830943 real appveyor config this time 10 years ago
Dimitri 91193d076e appveyor badge 10 years ago
Dimitri f87ab8b34a appveyor config 10 years ago
Dimitri c1a40f3d71 wavepack inline compile - vs2015 solution 10 years ago
Dimitri Diakopoulos 51ab7c598b untangle opus for inline compile 10 years ago
Dimitri 29b7b203f9 introduce vs 2015 example solution/proj file and fix paths. vs 2013 needs to be fixed 10 years ago
Dimitri 5648d7a014 simplify mpc decoder 10 years ago
Dimitri 031d94497b fix heap corruption for musepack decoder 10 years ago
Dimitri 97245f61ab fileData as a shared ptr 10 years ago
Dimitri 02982aa426 assert on empty file samples data; correct use of static WavEncoder::WriteFile method 10 years ago
Dimitri 68fd66a1fc cleanup example main file a bit 10 years ago
Dimitri Diakopoulos dd9b4f9075 Merge pull request #14 from r-lyeh/master
Improved example; amalgamated libraries
10 years ago
r-lyeh e215d95f52 Amalgamate missing dependencies: musepack, opus, wavpack 10 years ago
r-lyeh e6f07b7587 Catch failed initializations. Add extra argument 10 years ago
Dimitri Diakopoulos 4bdf06ef13 further remove debug output 10 years ago
Dimitri Diakopoulos 00363a3721 disable debug output 10 years ago
Dimitri Diakopoulos ab33491168 Merge branch 'master' of https://github.com/ddiakopoulos/libnyquist 10 years ago
Dimitri Diakopoulos 1de76c80a2 move impl and fix todo 10 years ago
Dimitri Diakopoulos 0415228c34 remove wip streaming (will resume in different branch) and remove unnecessary template 10 years ago
Dimitri Diakopoulos 859e58052c noticed need for additional exception 10 years ago
Dimitri Diakopoulos 0e78a2ed80 fix 10 years ago
Dimitri Diakopoulos 9130de77b7 thinking about streaming implementation 10 years ago
Dimitri Diakopoulos fe34756ac5 remove other error codes from public decoding API 10 years ago
Dimitri Diakopoulos 25e43204d0 Handle unsupported file extension exception 10 years ago
Dimitri Diakopoulos 3622b0ea08 begin to deprecate error codes in favor of exceptions 10 years ago
Dimitri Diakopoulos 5aba7f90aa consistency 10 years ago
Dimitri Diakopoulos f1e3de7a12 add note about platform APIs 10 years ago
Dimitri Diakopoulos 24f68a7eb0 add ima4util header to visual studio projects 10 years ago
Dimitri Diakopoulos dcef49b47f Add note about ima adpcm 10 years ago
Dimitri Diakopoulos 4961219cf3 finish up ima adpcm implementation 10 years ago

2
.gitignore vendored

@ -42,4 +42,6 @@ DerivedData
*.reapeaks
*.opendb
encoded.wav

@ -0,0 +1,34 @@
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 .

@ -0,0 +1,296 @@
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()

@ -234,28 +234,6 @@ 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.
Catch (Boost)
libmodplug (Public Domain)
===============================================================================
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.
ModPlug-XMMS and libmodplug are now in the public domain.

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

@ -1,34 +1,33 @@
# 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.
The library steers away from patent-encumbered formats and those with non-BSD licensed codec implementations (such as MP3 and AAC, respectively).
Libnyquist is meant to be statically linked, which is not the case with other popular libraries like libsndfile (LGPL). Furthermore, the library is not concerned with legacy format support (for instance, A-law PCM encoding or SND files).
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 is intended to be used an audio loading frontend for games, audio sequencers, music players, and more.
The library does not include patent or license encumbered formats (such as AAC). For portability, libnyquist does not link against platform-specific APIs like Windows Media Foundation or CoreAudio, and instead bundles the source code of reference decoders as an implementation detail.
Libnyquist is meant to be statically linked, which is not the case with other popular libraries like libsndfile (which is licensed under the LGPL). Furthermore, the library is not concerned with supporting very rare encodings (for instance, A-law PCM or the SND format).
While untested, there are no technical conditions that preclude compilation on other platforms with C++11 support (Android NDK r10e+, Linux, iOS, etc).
## Format Support
Regardless of input bit depth, the library hands over an interleaved float array, normalized between [-1.0,+1.0]. At present, the library does not provide resampling functionality.
Regardless of input bit depth, the library produces a channel-interleaved float vector, normalized between [-1.0,+1.0]. At present, the library does not provide comprehensive resampling functionality.
* Wave
* Wave (+ IMA-ADPCM encoding)
* MP3
* Ogg Vorbis
* Ogg Opus
* FLAC
* WavPack
* Musepack
* Core Audio Format (Apple Lossless / AIFF) (WIP)
## 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.
## License
Libyquist is released under the 2-Clause BSD license. All dependencies and codecs are under similar open licenses.
This library is released under the simplied 2 clause BSD license. All included dependencies have been released under identical or similarly permissive licenses.

@ -0,0 +1,13 @@
# appveyor file
# http://www.appveyor.com/docs/appveyor-yml
os: Visual Studio 2017
platform:
- x64
build_script:
- mkdir build
- cd build
- cmake -G "Visual Studio 15 2017 Win64" ..
- cmake --build . --config Release

@ -0,0 +1,24 @@
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()

@ -1,347 +0,0 @@
// !$*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 */;
}

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

@ -1,89 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0610"
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
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "08B91D251AC26FC100335131"
BuildableName = "nyquist-example"
BlueprintName = "nyquist-example"
ReferencedContainer = "container:libnyquist-example.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "YES"
customWorkingDirectory = "$(PROJECT_DIR)/../"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
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
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
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>

@ -1,28 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.30723.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\v120\libnyquist.vcxproj", "{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
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}.Release|Win32.ActiveCfg = Release|Win32
{C0C0C270-FB9E-4EEB-8F22-180BB2FA800B}.Release|Win32.Build.0 = Release|Win32
{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}.Release|Win32.ActiveCfg = Release|Win32
{0EEC3739-F60A-4B90-8B75-9E1AFF28106A}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.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="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C0C0C270-FB9E-4EEB-8F22-180BB2FA800B}</ProjectGuid>
<RootNamespace>libnyquistexamples</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</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 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>
<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)'=='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>
<ItemGroup>
<ClCompile Include="..\..\third_party\rtaudio\RtAudio.cpp" />
<ClCompile Include="..\src\Main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\third_party\rtaudio\RtAudio.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\libnyquist.vcxproj\v120\libnyquist.vcxproj">
<Project>{0eec3739-f60a-4b90-8b75-9e1aff28106a}</Project>
<Private>false</Private>
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -1,26 +0,0 @@
<?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>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\third_party\rtaudio\RtAudio.h">
<Filter>third_party</Filter>
</ClInclude>
</ItemGroup>
</Project>

@ -1,10 +0,0 @@
<?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) 2015, Dimitri Diakopoulos All rights reserved.
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:
@ -28,37 +28,61 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <algorithm>
#include <thread>
#include <chrono>
using namespace nqr;
#include <iostream>
static RingBufferT<float> buffer(BUFFER_LENGTH);
static RingBufferT<float> record_buffer(BUFFER_LENGTH / 2);
static int rt_callback(void * output_buffer, void * input_buffer, unsigned int num_bufferframes, double stream_time, RtAudioStreamStatus status, void * user_data)
static int rt_callback(void * output_buffer, void * input_buffer, uint32_t num_bufferframes, double stream_time, RtAudioStreamStatus status, void * user_data)
{
if (status) std::cerr << "[rtaudio] Buffer over or underflow" << std::endl;
if (status) std::cerr << "[rtaudio] buffer over or underflow" << std::endl;
if (buffer.getAvailableRead())
{
buffer.read((float*) output_buffer, BUFFER_LENGTH);
}
else
{
memset(output_buffer, 0, BUFFER_LENGTH * sizeof(float));
}
// 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);
return 0;
}
AudioDevice::AudioDevice(int numChannels, int sampleRate, int deviceId)
{
rtaudio = std::unique_ptr<RtAudio>(new RtAudio);
info.id = (deviceId != -1) ? deviceId : rtaudio->getDefaultOutputDevice();
info.numChannels = numChannels;
info.sampleRate = sampleRate;
info.frameSize = FRAME_SIZE;
}
AudioDevice::~AudioDevice()
{
if (rtaudio)
{
rtaudio->stopStream();
if (rtaudio->isStreamOpen())
{
rtaudio->closeStream();
}
}
}
bool AudioDevice::Open(const int deviceId)
{
if (!rtaudio) throw std::runtime_error("rtaudio not created yet");
RtAudio::StreamParameters parameters;
parameters.deviceId = info.id;
parameters.nChannels = info.numChannels;
parameters.firstChannel = 0;
RtAudio::StreamParameters outputParams;
outputParams.deviceId = info.id;
outputParams.nChannels = info.numChannels;
outputParams.firstChannel = 0;
rtaudio->openStream(&parameters, NULL, RTAUDIO_FLOAT32, info.sampleRate, &info.frameSize, &rt_callback, (void*) & buffer);
RtAudio::StreamParameters inputParams;
inputParams.deviceId = rtaudio->getDefaultInputDevice();
inputParams.nChannels = 1;
inputParams.firstChannel = 0;
rtaudio->openStream(&outputParams, &inputParams, RTAUDIO_FLOAT32, info.sampleRate, &info.frameSize, &rt_callback, (void*) & buffer);
if (rtaudio->isStreamOpen())
{
@ -73,11 +97,11 @@ void AudioDevice::ListAudioDevices()
std::unique_ptr<RtAudio> tempDevice(new RtAudio);
RtAudio::DeviceInfo info;
unsigned int devices = tempDevice->getDeviceCount();
uint32_t devices = tempDevice->getDeviceCount();
std::cout << "[rtaudio] Found: " << devices << " device(s)\n";
for (unsigned int i = 0; i < devices; ++i)
for (uint32_t i = 0; i < devices; ++i)
{
info = tempDevice->getDeviceInfo(i);
std::cout << "\tDevice: " << i << " - " << info.name << std::endl;
@ -94,11 +118,32 @@ bool AudioDevice::Play(const std::vector<float> & data)
int writeCount = 0;
while(writeCount < sizeInFrames)
while (writeCount < sizeInFrames)
{
bool status = buffer.write((data.data() + (writeCount * BUFFER_LENGTH)), BUFFER_LENGTH);
if (status) writeCount++;
}
return true;
}
}
bool AudioDevice::Record(const uint32_t lengthInSamples, std::vector<float> & recordingBuffer)
{
uint64_t recordedSamples = 0;
// 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);
}
}
}
return true;
}

@ -1,5 +1,5 @@
/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.
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:
@ -23,73 +23,43 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// This file implements a simple sound file player based on RtAudio for testing / example purposes.
#ifndef AUDIO_DEVICE_H
#define AUDIO_DEVICE_H
// This file implements a simple sound file player based on RtAudio for testing / example purposes.
#include "Common.h"
#include "RingBuffer.h"
#include "rtaudio/RtAudio.h"
#include <iostream>
#include <vector>
#include <memory>
namespace nqr
{
const unsigned int FRAME_SIZE = 512;
const int CHANNELS = 2;
const int BUFFER_LENGTH = FRAME_SIZE * CHANNELS;
static const uint32_t FRAME_SIZE = 512;
static const int32_t CHANNELS = 2;
static const int32_t BUFFER_LENGTH = FRAME_SIZE * CHANNELS;
struct DeviceInfo
struct AudioDeviceInfo
{
int id;
int numChannels;
int sampleRate;
unsigned int frameSize;
uint32_t id;
uint32_t numChannels;
uint32_t sampleRate;
uint32_t frameSize;
bool isPlaying = false;
};
class AudioDevice
{
NO_MOVE(AudioDevice);
std::unique_ptr<RtAudio> rtaudio;
protected:
AudioDevice(const AudioDevice& r) = delete;
AudioDevice & operator = (const AudioDevice& r) = delete;
public:
DeviceInfo info;
AudioDeviceInfo info;
AudioDevice(int numChannels, int sampleRate, int deviceId = -1);
~AudioDevice();
static void ListAudioDevices();
AudioDevice(int numChannels, int sampleRate, int deviceId = -1)
{
rtaudio = std::unique_ptr<RtAudio>(new RtAudio);
info.id = deviceId != -1 ? deviceId : rtaudio->getDefaultOutputDevice();
info.numChannels = numChannels;
info.sampleRate = sampleRate;
info.frameSize = FRAME_SIZE;
}
~AudioDevice()
{
if (rtaudio)
{
rtaudio->stopStream();
if (rtaudio->isStreamOpen())
rtaudio->closeStream();
}
}
bool Open(const int deviceId);
bool Play(const std::vector<float> & data);
bool Record(const uint32_t lengthInSamples, std::vector<float> & recordingBuffer);
};
} // end namespace nqr
#endif

@ -1,104 +1,167 @@
// 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
// will be unable to find the example assets unless the proper working directory is set.
#if defined(_MSC_VER)
#pragma comment(lib, "dsound.lib")
#endif
#include "libnyquist/AudioDevice.h"
#include "libnyquist/AudioDecoder.h"
#include "libnyquist/WavEncoder.h"
#include "libnyquist/PostProcess.h"
#include "AudioDevice.h"
#include "libnyquist/Decoders.h"
#include "libnyquist/Encoders.h"
#include <thread>
using namespace nqr;
int main()
int main(int argc, const char **argv) try
{
AudioDevice::ListAudioDevices();
AudioDevice::ListAudioDevices();
int desiredSampleRate = 44100;
AudioDevice myDevice(2, desiredSampleRate);
myDevice.Open(myDevice.info.id);
AudioData * fileData = new AudioData();
NyquistIO loader;
WavEncoder encoder;
try
{
// Circular libnyquist testing!
//auto result = loader.Load(fileData, "encoded.wav");
//auto result = loader.Load(fileData, "test_data/1ch/44100/8/test.wav");
//auto result = loader.Load(fileData, "test_data/1ch/44100/16/test.wav");
//auto result = loader.Load(fileData, "test_data/1ch/44100/24/test.wav");
//auto result = loader.Load(fileData, "test_data/1ch/44100/32/test.wav");
//auto result = loader.Load(fileData, "test_data/1ch/44100/64/test.wav");
//auto result = loader.Load(fileData, "test_data/2ch/44100/8/test.wav");
//auto result = loader.Load(fileData, "test_data/2ch/44100/16/test.wav");
//auto result = loader.Load(fileData, "test_data/2ch/44100/24/test.wav");
//auto result = loader.Load(fileData, "test_data/2ch/44100/32/test.wav");
//auto result = loader.Load(fileData, "test_data/2ch/44100/64/test.wav");
//auto result = loader.Load(fileData, "test_data/ad_hoc/6_channel_44k_16b.wav");
//auto result = loader.Load(fileData, "test_data/ad_hoc/LR_Stereo.ogg");
//auto result = loader.Load(fileData, "test_data/ad_hoc/TestLaugh_44k.ogg");
//auto result = loader.Load(fileData, "test_data/ad_hoc/TestBeat.ogg");
//auto result = loader.Load(fileData, "test_data/ad_hoc/TestBeatMono.ogg");
//auto result = loader.Load(fileData, "test_data/ad_hoc/BlockWoosh_Stereo.ogg");
//auto result = loader.Load(fileData, "test_data/ad_hoc/KittyPurr8_Stereo_Dithered.flac");
//auto result = loader.Load(fileData, "test_data/ad_hoc/KittyPurr16_Stereo.flac");
//auto result = loader.Load(fileData, "test_data/ad_hoc/KittyPurr16_Mono.flac");
//auto result = loader.Load(fileData, "test_data/ad_hoc/KittyPurr24_Stereo.flac");
//auto result = loader.Load(fileData, "test_data/ad_hoc/detodos.opus"); // "Firefox: From All, To All"
//auto result = loader.Load(fileData, "test_data/ad_hoc/TestBeat_Float32.wv");
//auto result = loader.Load(fileData, "test_data/ad_hoc/TestBeat_Float32_Mono.wv");
//auto result = loader.Load(fileData, "test_data/ad_hoc/TestBeat_Int16.wv");
//auto result = loader.Load(fileData, "test_data/ad_hoc/TestBeat_Int24.wv");
//auto result = loader.Load(fileData, "test_data/ad_hoc/TestBeat_Int32.wv");
//auto result = loader.Load(fileData, "test_data/ad_hoc/TestBeat_Int24_Mono.wv");
//auto result = loader.Load(fileData, "test_data/ad_hoc/44_16_stereo.mpc");
//auto result = loader.Load(fileData, "test_data/ad_hoc/44_16_mono.mpc");
auto result = loader.Load(fileData, "test_data/ad_hoc/TestBeat_44_16_stereo-ima4.wav");
std::cout << "[Debug] Loader Status: " << result << std::endl;
}
catch (std::exception e)
{
std::cerr << "Caught: " << e.what() << std::endl;
std::exit(1);
}
const int desiredSampleRate = 44100;
const int desiredChannelCount = 2;
AudioDevice myDevice(desiredChannelCount, desiredSampleRate);
myDevice.Open(myDevice.info.id);
// Libnyquist does not do sample rate conversion
if (fileData->sampleRate != desiredSampleRate)
{
std::cout << "[Warning - Sample Rate Mismatch] - file is sampled at " << fileData->sampleRate << " and output is " << desiredSampleRate << std::endl;
}
// Convert mono to stereo for testing playback
if (fileData->channelCount == 1)
{
std::vector<float> stereoCopy(fileData->samples.size() * 2);
std::shared_ptr<AudioData> fileData = std::make_shared<AudioData>();
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");
// 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");
//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");
// 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");
//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"
// 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");
// In-memory ogg
//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);
*/
if (fileData->sampleRate != desiredSampleRate)
{
std::cout << "[Warning - Sample Rate Mismatch] - file is sampled at " << fileData->sampleRate << " and output is " << desiredSampleRate << std::endl;
}
std::cout << "Input Samples: " << fileData->samples.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 for: " << fileData->lengthSeconds << " seconds..." << std::endl;
myDevice.Play(fileData->samples);
}
// Test wav file encoder
int encoderStatus = encoder.WriteFile({2, PCM_16, DITHER_NONE}, fileData, "encoded.wav");
std::cout << "Encoder Status: " << encoderStatus << std::endl;
return 0;
myDevice.Play(stereoCopy);
}
else
{
std::cout << "Playing STEREO 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;
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;
}
catch (const UnsupportedExtensionEx & e)
{
std::cerr << "Caught: " << e.what() << std::endl;
}
catch (const LoadPathNotImplEx & e)
{
std::cerr << "Caught: " << e.what() << std::endl;
}
catch (const LoadBufferNotImplEx & e)
{
std::cerr << "Caught: " << e.what() << std::endl;
}
catch (const std::exception & e)
{
std::cerr << "Caught: " << e.what() << std::endl;
}

@ -36,6 +36,8 @@
#include <atomic>
#include <assert.h>
#include <cstring>
#include <cstdlib>
template <typename T>
class RingBufferT
@ -43,18 +45,12 @@ 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);
}
RingBufferT(size_t count) : mAllocatedSize(0) { resize(count); }
RingBufferT(RingBufferT &&other)
: mData(other.mData), mAllocatedSize(other.mAllocatedSize), mWriteIndex(0), mReadIndex(0)
RingBufferT(RingBufferT &&other) : mData(other.mData), mAllocatedSize(other.mAllocatedSize), mWriteIndex(0), mReadIndex(0)
{
other.mData = nullptr;
other.mAllocatedSize = 0;
@ -71,9 +67,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 *)::realloc(mData, allocatedSize * sizeof(T));
mData = (T *) std::realloc(mData, allocatedSize * sizeof(T));
else
mData = (T *)::calloc(allocatedSize, sizeof(T));
mData = (T *) std::calloc(allocatedSize, sizeof(T));
assert(mData);
@ -81,7 +77,7 @@ class RingBufferT
clear();
}
// Invalidates the internal buffer and resets read / write indices to 0. \note Must be synchronized with both read and write threads.
// Invalidates the internal buffer and resets read / write indices to 0. Must be synchronized with both read and write threads.
void clear()
{
mWriteIndex = 0;
@ -91,16 +87,16 @@ class RingBufferT
// Returns the maximum number of elements.
size_t getSize() const
{
return mAllocatedSize - 1;
}
// Returns the number of elements available for wrtiing. \note Only safe to call from the write thread.
// Returns the number of elements available for writing. Only safe to call from the write thread.
size_t getAvailableWrite() const
{
return getAvailableWrite(mWriteIndex, mReadIndex);
}
// Returns the number of elements available for wrtiing. \note Only safe to call from the read thread.
// Returns the number of elements available for reading. Only safe to call from the read thread.
size_t getAvailableRead() const
{
return getAvailableRead(mWriteIndex, mReadIndex);
@ -188,7 +184,7 @@ class RingBufferT
return writeIndex + mAllocatedSize - readIndex;
}
T *mData;
T * mData;
size_t mAllocatedSize;
std::atomic<size_t> mWriteIndex, mReadIndex;
};
@ -196,4 +192,3 @@ class RingBufferT
typedef RingBufferT<float> RingBuffer;
#endif

@ -1,98 +0,0 @@
/*
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>
namespace nqr
{
// Individual decoder classes will throw std::exceptions for bad things,
// but NyquistIO implements this enum for high-level error notifications.
enum IOError
{
NoError,
NoDecodersLoaded,
ExtensionNotSupported,
LoadPathNotImplemented,
LoadBufferNotImplemented,
UnknownError
};
struct BaseDecoder
{
virtual int LoadFromPath(nqr::AudioData * data, const std::string & path) = 0;
virtual int LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) = 0;
virtual std::vector<std::string> GetSupportedFileExtensions() = 0;
//@todo implement streaming helper methods here
};
typedef std::pair<std::string, std::shared_ptr<nqr::BaseDecoder>> DecoderPair;
class NyquistIO
{
public:
NyquistIO();
~NyquistIO();
int Load(AudioData * data, const std::string & path);
int Load(AudioData *data, std::string extension, const std::vector<uint8_t> & buffer);
bool IsFileSupported(const std::string path) const;
private:
std::string ParsePathForExtension(const std::string & path) const;
std::shared_ptr<nqr::BaseDecoder> GetDecoderForExtension(const std::string ext);
void BuildDecoderTable();
template<typename T>
void AddDecoderToTable(std::shared_ptr<T> decoder)
{
auto supportedExtensions = decoder->GetSupportedFileExtensions();
//@todo: basic sanity checking that the extension isn't already supported
for (const auto ext : supportedExtensions)
{
decoderTable.insert(DecoderPair(ext, decoder));
}
}
std::map<std::string, std::shared_ptr<BaseDecoder>> decoderTable;
NO_MOVE(NyquistIO);
};
} // end namespace nqr
#endif

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

@ -1,5 +1,5 @@
/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.
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:
@ -26,6 +26,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef LIBNYQUIST_COMMON_H
#define LIBNYQUIST_COMMON_H
#include <memory>
#include <vector>
#include <algorithm>
#include <cmath>
@ -36,12 +37,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <type_traits>
#include <numeric>
#include <array>
#include "PostProcess.h"
#include "Dither.h"
#include <map>
#include <random>
namespace nqr
{
/////////////////
// Util Macros //
/////////////////
@ -199,10 +200,90 @@ 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
@ -250,6 +331,9 @@ 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 //
//////////////////////////
@ -282,10 +366,328 @@ struct NyquistFileBuffer
size_t size;
};
NyquistFileBuffer ReadFile(std::string pathToFile);
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:
int GetFormatBitsPerSample(PCMFormat f);
PCMFormat MakeFormatForBits(int bits, bool floatingPt, bool isSigned);
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!
}
} // end namespace nqr

@ -0,0 +1,136 @@
/*
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,69 +0,0 @@
/*
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 DITHER_OPERATIONS_H
#define DITHER_OPERATIONS_H
#include <random>
namespace nqr
{
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

@ -1,5 +1,5 @@
/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.
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:
@ -23,23 +23,22 @@ 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
#ifndef NYQUIST_ENCODERS_H
#define NYQUIST_ENCODERS_H
#include "AudioDecoder.h"
#include "Common.h"
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);
struct WavPackDecoder : public nqr::BaseDecoder
{
WavPackDecoder() {};
virtual ~WavPackDecoder() {};
virtual int LoadFromPath(nqr::AudioData * data, const std::string & path) override;
virtual int LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override;
virtual std::vector<std::string> GetSupportedFileExtensions() override;
};
// 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);
} // end namespace nqr
#endif
#endif // end NYQUIST_ENCODERS_H

@ -1,65 +0,0 @@
/*
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 : public nqr::BaseDecoder
{
FlacDecoder() {}
virtual ~FlacDecoder() {}
virtual int LoadFromPath(nqr::AudioData * data, const std::string & path) override;
virtual int LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override;
virtual std::vector<std::string> GetSupportedFileExtensions() override;
};
} // end namespace nqr
#endif

@ -1,140 +0,0 @@
/*
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, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8
};
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 = 0;
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;
diff += ima_step_table[s] >> 3;
// Sign
if (nibble & 8) diff = -diff;
// Add delta
p += diff;
p = ima_clamp_predict(p);
s += ima_index_table[nibble];
s = ima_clamp_index(s);
return p;
}
void decode_ima_adpcm(ADPCMState & state, int16_t * outBuffer, uint32_t num_channels)
{
const uint8_t * data = state.inBuffer;
// Loop over the interleaved words
for (int32_t ch = 0; ch < num_channels; ch++)
{
const int byteOffset = ch * 4;
// Get step table index and predicted value from the header word for the current channel
int16_t predictedSample = (data[byteOffset] | (data[byteOffset + 1] << 8));
int stepIndex = data[byteOffset + 2];
// Reserved byte of the header word should be 0.
uint8_t reserved = data[byteOffset + 3];
if (reserved != 0) std::cout << "Fuck" << std::endl;
int byteIdx = num_channels * 4 + byteOffset; //the byte index of the first data word for this channel
int idx = ch;
// Decode each nibble of the current data word, containing 8 encoded samples, for the current channel
while (byteIdx < state.frame_size)
{
for (int j = 0; j < 4; j++)
{
outBuffer[idx] = decode_nibble(data[byteIdx] & 0xf, predictedSample, stepIndex); // low nibble
idx += num_channels;
outBuffer[idx] = decode_nibble(data[byteIdx] >> 4, predictedSample, 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

@ -1,45 +0,0 @@
/*
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 : public nqr::BaseDecoder
{
MusepackDecoder() {};
virtual ~MusepackDecoder() {};
virtual int LoadFromPath(nqr::AudioData * data, const std::string & path) override;
virtual int LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override;
virtual std::vector<std::string> GetSupportedFileExtensions() override;
};
} // end namespace nqr
#endif

@ -1,50 +0,0 @@
/*
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 : public nqr::BaseDecoder
{
OpusDecoder() {}
virtual ~OpusDecoder() {}
virtual int LoadFromPath(nqr::AudioData * data, const std::string & path) override;
virtual int LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override;
virtual std::vector<std::string> GetSupportedFileExtensions() override;
};
} // end namespace nqr
#endif

@ -1,104 +0,0 @@
/*
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

@ -1,84 +0,0 @@
/*
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

@ -1,44 +0,0 @@
/*
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 : public nqr::BaseDecoder
{
VorbisDecoder() {}
virtual ~VorbisDecoder() {}
virtual int LoadFromPath(nqr::AudioData * data, const std::string & path) override;
virtual int LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override;
virtual std::vector<std::string> GetSupportedFileExtensions() override;
};
} // end namespace nqr
#endif

@ -1,182 +0,0 @@
/*
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 : public nqr::BaseDecoder
{
WavDecoder() {}
virtual ~WavDecoder() {}
virtual int LoadFromPath(nqr::AudioData * data, const std::string & path) override;
virtual int LoadFromBuffer(nqr::AudioData * data, const std::vector<uint8_t> & memory) override;
virtual std::vector<std::string> GetSupportedFileExtensions() override;
};
} // end namespace nqr
#endif

@ -1,62 +0,0 @@
/*
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
{
// 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.
class WavEncoder
{
enum EncoderError
{
NoError,
InsufficientSampleData,
FileIOError,
UnsupportedSamplerate,
UnsupportedChannelConfiguration,
UnsupportedBitdepth,
UnsupportedChannelMix,
BufferTooBig,
};
public:
// Assume data adheres to EncoderParams, except for bit depth and fmt
static int WriteFile(const EncoderParams p, const AudioData * d, const std::string & path);
};
} // end namespace nqr
#endif

@ -1,28 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.30723.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

@ -1,180 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.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\AudioDevice.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="$(ProjectDir)..\..\third_party\opus\celt\celt_decoder.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\opus\celt\celt_encoder.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\bits.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\extra1.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\extra2.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\float.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\metadata.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\pack.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\tags.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\unpack.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\unpack3.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\words.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\wputils.c" />
<ClCompile Include="..\..\src\MusepackDecoder.cpp" />
<ClCompile Include="..\..\src\MusepackDependencies.c" />
<ClCompile Include="..\..\third_party\musepack\libmpcdec\mpc_bits_reader.c" />
<ClCompile Include="..\..\third_party\musepack\libmpcdec\mpc_decoder.c" />
<ClCompile Include="..\..\third_party\musepack\libmpcdec\mpc_demux.c" />
<ClCompile Include="..\..\third_party\musepack\libmpcdec\mpc_reader.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\AudioDevice.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\Common.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\Dither.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\RingBuffer.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\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>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</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\libmpcdec;$(ProjectDir)..\..\third_party\musepack\libmpcenc;%(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\libmpcdec;$(ProjectDir)..\..\third_party\musepack\libmpcenc;%(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\libmpcdec;$(ProjectDir)..\..\third_party\musepack\libmpcenc;%(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\libmpcdec;$(ProjectDir)..\..\third_party\musepack\libmpcenc;%(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>

@ -1,177 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="$(ProjectDir)..\..\third_party\opus\celt\celt_encoder.c">
<Filter>third_party\celt</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\opus\celt\celt_decoder.c">
<Filter>third_party\celt</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\bits.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\extra1.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\extra2.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\float.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\pack.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\tags.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\unpack.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\unpack3.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\words.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\wputils.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\metadata.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<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\AudioDevice.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="..\..\third_party\musepack\libmpcdec\mpc_reader.c">
<Filter>third_party\mpc</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\musepack\libmpcdec\mpc_bits_reader.c">
<Filter>third_party\mpc</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\musepack\libmpcdec\mpc_decoder.c">
<Filter>third_party\mpc</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\musepack\libmpcdec\mpc_demux.c">
<Filter>third_party\mpc</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\AudioDevice.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\RingBuffer.h">
<Filter>include\util</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>
</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="third_party">
<UniqueIdentifier>{33572766-230e-4a7f-8c06-885c4780c1d1}</UniqueIdentifier>
</Filter>
<Filter Include="third_party\wavpack">
<UniqueIdentifier>{d40a1038-d11f-45dc-820b-e32743336269}</UniqueIdentifier>
</Filter>
<Filter Include="third_party\celt">
<UniqueIdentifier>{d38860a7-b4e5-4a1e-99a5-c4eac7e1c013}</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>
<Filter Include="third_party\mpc">
<UniqueIdentifier>{cc5d22ad-1a3e-46cf-8f65-7d33f02629fb}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

@ -1,28 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.30723.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

@ -1,180 +0,0 @@
<?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\AudioDevice.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="$(ProjectDir)..\..\third_party\opus\celt\celt_decoder.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\opus\celt\celt_encoder.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\bits.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\extra1.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\extra2.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\float.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\metadata.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\pack.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\tags.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\unpack.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\unpack3.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\words.c" />
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\wputils.c" />
<ClCompile Include="..\..\src\MusepackDecoder.cpp" />
<ClCompile Include="..\..\src\MusepackDependencies.c" />
<ClCompile Include="..\..\third_party\musepack\libmpcdec\mpc_bits_reader.c" />
<ClCompile Include="..\..\third_party\musepack\libmpcdec\mpc_decoder.c" />
<ClCompile Include="..\..\third_party\musepack\libmpcdec\mpc_demux.c" />
<ClCompile Include="..\..\third_party\musepack\libmpcdec\mpc_reader.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\AudioDevice.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\Common.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\Dither.h" />
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\RingBuffer.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\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>

@ -1,177 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="$(ProjectDir)..\..\third_party\opus\celt\celt_encoder.c">
<Filter>third_party\celt</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\opus\celt\celt_decoder.c">
<Filter>third_party\celt</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\bits.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\extra1.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\extra2.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\float.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\pack.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\tags.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\unpack.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\unpack3.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\words.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\wputils.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<ClCompile Include="$(ProjectDir)..\..\third_party\wavpack\src\metadata.c">
<Filter>third_party\wavpack</Filter>
</ClCompile>
<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\AudioDevice.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="..\..\third_party\musepack\libmpcdec\mpc_bits_reader.c">
<Filter>third_party\mpc</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\musepack\libmpcdec\mpc_decoder.c">
<Filter>third_party\mpc</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\musepack\libmpcdec\mpc_demux.c">
<Filter>third_party\mpc</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\musepack\libmpcdec\mpc_reader.c">
<Filter>third_party\mpc</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\AudioDevice.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\RingBuffer.h">
<Filter>include\util</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>
</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="third_party">
<UniqueIdentifier>{33572766-230e-4a7f-8c06-885c4780c1d1}</UniqueIdentifier>
</Filter>
<Filter Include="third_party\wavpack">
<UniqueIdentifier>{d40a1038-d11f-45dc-820b-e32743336269}</UniqueIdentifier>
</Filter>
<Filter Include="third_party\celt">
<UniqueIdentifier>{d38860a7-b4e5-4a1e-99a5-c4eac7e1c013}</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>
<Filter Include="third_party\mpc">
<UniqueIdentifier>{5e7b9ab1-a3bf-4934-96d8-38ad1c4b08d7}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

@ -1,553 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
0804D13F1AE69F0100F4B1FD /* OpusDependencies.c in Sources */ = {isa = PBXBuildFile; fileRef = 0804D13E1AE69F0100F4B1FD /* OpusDependencies.c */; };
0804D1451AE6BA5100F4B1FD /* celt_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 0804D1431AE6BA5100F4B1FD /* celt_decoder.c */; settings = {COMPILER_FLAGS = "-w"; }; };
0804D1461AE6BA5100F4B1FD /* celt_encoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 0804D1441AE6BA5100F4B1FD /* celt_encoder.c */; settings = {COMPILER_FLAGS = "-w"; }; };
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 */; };
083730C21BE5372300216BDC /* mpc_bits_reader.c in Sources */ = {isa = PBXBuildFile; fileRef = 083730BE1BE5372300216BDC /* mpc_bits_reader.c */; settings = {COMPILER_FLAGS = "-w"; }; };
083730C31BE5372300216BDC /* mpc_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 083730BF1BE5372300216BDC /* mpc_decoder.c */; settings = {COMPILER_FLAGS = "-w"; }; };
083730C41BE5372300216BDC /* mpc_demux.c in Sources */ = {isa = PBXBuildFile; fileRef = 083730C01BE5372300216BDC /* mpc_demux.c */; settings = {COMPILER_FLAGS = "-w"; }; };
083730C51BE5372300216BDC /* mpc_reader.c in Sources */ = {isa = PBXBuildFile; fileRef = 083730C11BE5372300216BDC /* mpc_reader.c */; settings = {COMPILER_FLAGS = "-w"; }; };
083DB3F31B091C1100FB0661 /* WavEncoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 083DB3F21B091C1100FB0661 /* WavEncoder.cpp */; };
086DADAD1AE029860031F793 /* VorbisDependencies.c in Sources */ = {isa = PBXBuildFile; fileRef = 086DADAB1ADF9DF30031F793 /* VorbisDependencies.c */; };
08894F291AEAA5D7007AAF90 /* bits.c in Sources */ = {isa = PBXBuildFile; fileRef = 08894F1E1AEAA5D7007AAF90 /* bits.c */; settings = {COMPILER_FLAGS = "-w"; }; };
08894F2A1AEAA5D7007AAF90 /* extra1.c in Sources */ = {isa = PBXBuildFile; fileRef = 08894F1F1AEAA5D7007AAF90 /* extra1.c */; settings = {COMPILER_FLAGS = "-w"; }; };
08894F2B1AEAA5D7007AAF90 /* extra2.c in Sources */ = {isa = PBXBuildFile; fileRef = 08894F201AEAA5D7007AAF90 /* extra2.c */; settings = {COMPILER_FLAGS = "-w"; }; };
08894F2C1AEAA5D7007AAF90 /* float.c in Sources */ = {isa = PBXBuildFile; fileRef = 08894F211AEAA5D7007AAF90 /* float.c */; settings = {COMPILER_FLAGS = "-w"; }; };
08894F2D1AEAA5D7007AAF90 /* metadata.c in Sources */ = {isa = PBXBuildFile; fileRef = 08894F221AEAA5D7007AAF90 /* metadata.c */; settings = {COMPILER_FLAGS = "-w"; }; };
08894F2E1AEAA5D7007AAF90 /* pack.c in Sources */ = {isa = PBXBuildFile; fileRef = 08894F231AEAA5D7007AAF90 /* pack.c */; settings = {COMPILER_FLAGS = "-w"; }; };
08894F2F1AEAA5D7007AAF90 /* tags.c in Sources */ = {isa = PBXBuildFile; fileRef = 08894F241AEAA5D7007AAF90 /* tags.c */; settings = {COMPILER_FLAGS = "-w"; }; };
08894F301AEAA5D7007AAF90 /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = 08894F251AEAA5D7007AAF90 /* unpack.c */; settings = {COMPILER_FLAGS = "-w"; }; };
08894F311AEAA5D7007AAF90 /* unpack3.c in Sources */ = {isa = PBXBuildFile; fileRef = 08894F261AEAA5D7007AAF90 /* unpack3.c */; settings = {COMPILER_FLAGS = "-w"; }; };
08894F321AEAA5D7007AAF90 /* words.c in Sources */ = {isa = PBXBuildFile; fileRef = 08894F271AEAA5D7007AAF90 /* words.c */; settings = {COMPILER_FLAGS = "-w"; }; };
08894F331AEAA5D7007AAF90 /* wputils.c in Sources */ = {isa = PBXBuildFile; fileRef = 08894F281AEAA5D7007AAF90 /* wputils.c */; settings = {COMPILER_FLAGS = "-w"; }; };
08B91D9A1AC73B8A00335131 /* CafDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D901AC73B8A00335131 /* CafDecoder.cpp */; };
08B91D9B1AC73B8A00335131 /* AudioDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D911AC73B8A00335131 /* AudioDecoder.cpp */; };
08B91D9C1AC73B8A00335131 /* AudioDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D921AC73B8A00335131 /* AudioDevice.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 */; };
/* 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; };
0804D1431AE6BA5100F4B1FD /* celt_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = celt_decoder.c; path = third_party/opus/celt/celt_decoder.c; sourceTree = SOURCE_ROOT; };
0804D1441AE6BA5100F4B1FD /* celt_encoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = celt_encoder.c; path = third_party/opus/celt/celt_encoder.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; };
083730BE1BE5372300216BDC /* mpc_bits_reader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mpc_bits_reader.c; path = third_party/musepack/libmpcdec/mpc_bits_reader.c; sourceTree = SOURCE_ROOT; };
083730BF1BE5372300216BDC /* mpc_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mpc_decoder.c; path = third_party/musepack/libmpcdec/mpc_decoder.c; sourceTree = SOURCE_ROOT; };
083730C01BE5372300216BDC /* mpc_demux.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mpc_demux.c; path = third_party/musepack/libmpcdec/mpc_demux.c; sourceTree = SOURCE_ROOT; };
083730C11BE5372300216BDC /* mpc_reader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mpc_reader.c; path = third_party/musepack/libmpcdec/mpc_reader.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; };
08894F1E1AEAA5D7007AAF90 /* bits.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bits.c; path = third_party/wavpack/src/bits.c; sourceTree = SOURCE_ROOT; };
08894F1F1AEAA5D7007AAF90 /* extra1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = extra1.c; path = third_party/wavpack/src/extra1.c; sourceTree = SOURCE_ROOT; };
08894F201AEAA5D7007AAF90 /* extra2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = extra2.c; path = third_party/wavpack/src/extra2.c; sourceTree = SOURCE_ROOT; };
08894F211AEAA5D7007AAF90 /* float.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = float.c; path = third_party/wavpack/src/float.c; sourceTree = SOURCE_ROOT; };
08894F221AEAA5D7007AAF90 /* metadata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = metadata.c; path = third_party/wavpack/src/metadata.c; sourceTree = SOURCE_ROOT; };
08894F231AEAA5D7007AAF90 /* pack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pack.c; path = third_party/wavpack/src/pack.c; sourceTree = SOURCE_ROOT; };
08894F241AEAA5D7007AAF90 /* tags.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tags.c; path = third_party/wavpack/src/tags.c; sourceTree = SOURCE_ROOT; };
08894F251AEAA5D7007AAF90 /* unpack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unpack.c; path = third_party/wavpack/src/unpack.c; sourceTree = SOURCE_ROOT; };
08894F261AEAA5D7007AAF90 /* unpack3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unpack3.c; path = third_party/wavpack/src/unpack3.c; sourceTree = SOURCE_ROOT; };
08894F271AEAA5D7007AAF90 /* words.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = words.c; path = third_party/wavpack/src/words.c; sourceTree = SOURCE_ROOT; };
08894F281AEAA5D7007AAF90 /* wputils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wputils.c; path = third_party/wavpack/src/wputils.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; };
08B91D921AC73B8A00335131 /* AudioDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioDevice.cpp; path = src/AudioDevice.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; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
08B91D231AC26FC100335131 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
0804D1421AE6BA2F00F4B1FD /* celt */ = {
isa = PBXGroup;
children = (
0804D1431AE6BA5100F4B1FD /* celt_decoder.c */,
0804D1441AE6BA5100F4B1FD /* celt_encoder.c */,
);
name = celt;
sourceTree = "<group>";
};
080A58551B083D5100302850 /* deps */ = {
isa = PBXGroup;
children = (
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>";
};
083730BD1BE5370400216BDC /* musepack */ = {
isa = PBXGroup;
children = (
083730BE1BE5372300216BDC /* mpc_bits_reader.c */,
083730BF1BE5372300216BDC /* mpc_decoder.c */,
083730C01BE5372300216BDC /* mpc_demux.c */,
083730C11BE5372300216BDC /* mpc_reader.c */,
);
name = musepack;
sourceTree = "<group>";
};
08894F1D1AEAA5B7007AAF90 /* wavpack */ = {
isa = PBXGroup;
children = (
08894F1E1AEAA5D7007AAF90 /* bits.c */,
08894F1F1AEAA5D7007AAF90 /* extra1.c */,
08894F201AEAA5D7007AAF90 /* extra2.c */,
08894F211AEAA5D7007AAF90 /* float.c */,
08894F221AEAA5D7007AAF90 /* metadata.c */,
08894F231AEAA5D7007AAF90 /* pack.c */,
08894F241AEAA5D7007AAF90 /* tags.c */,
08894F251AEAA5D7007AAF90 /* unpack.c */,
08894F261AEAA5D7007AAF90 /* unpack3.c */,
08894F271AEAA5D7007AAF90 /* words.c */,
08894F281AEAA5D7007AAF90 /* wputils.c */,
);
name = wavpack;
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 = (
083730BD1BE5370400216BDC /* musepack */,
08894F1D1AEAA5B7007AAF90 /* wavpack */,
0804D1421AE6BA2F00F4B1FD /* celt */,
);
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 */,
08B91D921AC73B8A00335131 /* AudioDevice.cpp */,
08B91D931AC73B8A00335131 /* Common.cpp */,
080A58571B0866F600302850 /* RiffUtils.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 = 0610;
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 = (
08894F2C1AEAA5D7007AAF90 /* float.c in Sources */,
083730C51BE5372300216BDC /* mpc_reader.c in Sources */,
08894F2E1AEAA5D7007AAF90 /* pack.c in Sources */,
08894F2A1AEAA5D7007AAF90 /* extra1.c in Sources */,
08894F321AEAA5D7007AAF90 /* words.c in Sources */,
08894F291AEAA5D7007AAF90 /* bits.c in Sources */,
08894F2B1AEAA5D7007AAF90 /* extra2.c in Sources */,
08894F301AEAA5D7007AAF90 /* unpack.c in Sources */,
083730B91BE52B9600216BDC /* MusepackDecoder.cpp in Sources */,
0804D1451AE6BA5100F4B1FD /* celt_decoder.c in Sources */,
0804D1461AE6BA5100F4B1FD /* celt_encoder.c in Sources */,
08894F331AEAA5D7007AAF90 /* wputils.c in Sources */,
08894F2F1AEAA5D7007AAF90 /* tags.c in Sources */,
08894F2D1AEAA5D7007AAF90 /* metadata.c in Sources */,
08894F311AEAA5D7007AAF90 /* unpack3.c in Sources */,
083730C21BE5372300216BDC /* mpc_bits_reader.c in Sources */,
083730C41BE5372300216BDC /* mpc_demux.c in Sources */,
083730C31BE5372300216BDC /* mpc_decoder.c 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 */,
08B91D9E1AC73B8A00335131 /* FlacDecoder.cpp in Sources */,
08B91D9C1AC73B8A00335131 /* AudioDevice.cpp 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;
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;
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)/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",
);
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;
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)/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",
);
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 */;
}

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

@ -1,88 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0610"
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
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "08B91D251AC26FC100335131"
BuildableName = "libnyquist.a"
BlueprintName = "libnyquist"
ReferencedContainer = "container:libnyquist.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "YES"
customWorkingDirectory = "$(PROJECT_DIR)"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "08B91D251AC26FC100335131"
BuildableName = "libnyquist.a"
BlueprintName = "libnyquist"
ReferencedContainer = "container:libnyquist.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
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>

@ -1,138 +0,0 @@
/*
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 "CafDecoder.h"
#include "MusepackDecoder.h"
using namespace nqr;
NyquistIO::NyquistIO()
{
BuildDecoderTable();
}
NyquistIO::~NyquistIO() { }
int NyquistIO::Load(AudioData * data, const std::string & path)
{
if (IsFileSupported(path))
{
if (decoderTable.size())
{
auto fileExtension = ParsePathForExtension(path);
auto decoder = GetDecoderForExtension(fileExtension);
try
{
return decoder->LoadFromPath(data, path);
}
catch (std::exception e)
{
std::cerr << "Caught fatal exception: " << e.what() << std::endl;
}
}
return IOError::NoDecodersLoaded;
}
else
{
return IOError::ExtensionNotSupported;
}
// Should never be reached
return IOError::UnknownError;
}
int NyquistIO::Load(AudioData * data, std::string extension, const std::vector<uint8_t> & buffer)
{
if (decoderTable.find(extension) == decoderTable.end())
{
return IOError::ExtensionNotSupported;
}
if (decoderTable.size())
{
auto decoder = GetDecoderForExtension(extension);
try
{
return decoder->LoadFromBuffer(data, buffer);
}
catch (std::exception e)
{
std::cerr << "Caught fatal exception: " << e.what() << std::endl;
}
}
else
{
return IOError::NoDecodersLoaded;
}
// Should never be reached
return IOError::UnknownError;
}
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)
{
return decoderTable[ext];
}
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<CAFDecoder>());
AddDecoderToTable(std::make_shared<MusepackDecoder>());
}

@ -1,47 +0,0 @@
/*
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 "CafDecoder.h"
using namespace nqr;
//////////////////////
// Public Interface //
//////////////////////
int CAFDecoder::LoadFromPath(AudioData * data, const std::string & path)
{
return IOError::LoadPathNotImplemented;
}
int CAFDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
{
return IOError::LoadBufferNotImplemented;
}
std::vector<std::string> CAFDecoder::GetSupportedFileExtensions()
{
return {};
}

@ -1,5 +1,5 @@
/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.
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:
@ -24,38 +24,193 @@ 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;
NyquistFileBuffer nqr::ReadFile(std::string pathToFile)
NyquistIO::NyquistIO() { BuildDecoderTable(); }
NyquistIO::~NyquistIO() { }
void NyquistIO::Load(AudioData * data, const std::string & path)
{
std::cout << "[Debug] Open: " << pathToFile << std::endl;
if (IsFileSupported(path))
{
if (decoderTable.size())
{
auto fileExtension = ParsePathForExtension(path);
auto decoder = GetDecoderForExtension(fileExtension);
try
{
decoder->LoadFromPath(data, path);
}
catch (const std::exception & e)
{
std::cerr << "NyquistIO::Load(" << path << ") caught internal exception: " << e.what() << std::endl;
throw;
}
}
else throw std::runtime_error("No available decoders.");
}
else
{
throw UnsupportedExtensionEx();
}
}
void NyquistIO::Load(AudioData * data, const std::vector<uint8_t> & buffer)
{
const std::map<std::vector<int16_t>, std::string> magic_map{
{{ 'w', 'v', 'p', 'k' }, "wv" },
{{ 'M', 'P', 'C', 'K' }, "mpc" },
{{ 0xFF, 0xFB }, "mp3" }, // ÿû, mp3 without ID3 header
{{ 'I', 'D', '3' }, "mp3" }, // mp3 with ID3 header
{{ 'O', 'g', 'g', 'S' }, "ogg_or_vorbis" }, // see `match_ogg_subtype`
{{ 'f', 'L', 'a', 'C' }, "flac" },
{{ 0x52, 0x49, 0x46, 0x46, -0x1, -0x1, -0x1, -0x1, 0x57, 0x41, 0x56, 0x45 }, "wav" } // RIFF....WAVE
};
auto match_magic = [](const uint8_t * data, const std::vector<int16_t> & magic)
{
for (int i = 0; i < magic.size(); ++i)
{
if (magic[i] != data[i] && magic[i] != -0x1) // -0x1 skips things that don't contribute to the magic number
{
return false;
}
}
return true;
};
auto match_ogg_subtype = [](const uint8_t * data)
{
std::string header; // arbitrarily read the first 64 bytes as ascii characters
for (int i = 0; i < 64; ++i) header += data[i];
std::size_t found_opus = header.find("OpusHead");
if (found_opus != std::string::npos) return "opus";
std::size_t found_vorbis = header.find("vorbis");
if (found_vorbis != std::string::npos) return "ogg";
return "none";
};
std::string ext = "none";
for (auto & filetype : magic_map)
{
if (match_magic(buffer.data(), filetype.first))
{
ext = filetype.second;
}
if (ext == "ogg_or_vorbis")
{
ext = match_ogg_subtype(buffer.data());
}
}
NyquistIO::Load(data, ext, buffer);
}
void NyquistIO::Load(AudioData * data, const std::string & extension, const std::vector<uint8_t> & buffer)
{
if (decoderTable.find(extension) == decoderTable.end())
{
throw UnsupportedExtensionEx();
}
if (decoderTable.size())
{
auto decoder = GetDecoderForExtension(extension);
try
{
decoder->LoadFromBuffer(data, buffer);
}
catch (const std::exception & e)
{
std::cerr << "caught internal loading exception: " << e.what() << std::endl;
throw;
}
}
else throw std::runtime_error("fatal: no decoders available");
}
bool NyquistIO::IsFileSupported(const std::string & path) const
{
auto fileExtension = ParsePathForExtension(path);
if (decoderTable.find(fileExtension) == decoderTable.end()) return false;
else return true;
}
std::string NyquistIO::ParsePathForExtension(const std::string & path) const
{
if (path.find_last_of(".") != std::string::npos) return path.substr(path.find_last_of(".") + 1);
return std::string("");
}
std::shared_ptr<BaseDecoder> NyquistIO::GetDecoderForExtension(const std::string & ext)
{
if (decoderTable.size()) return decoderTable[ext];
else throw std::runtime_error("No available decoders.");
return nullptr;
}
void NyquistIO::AddDecoderToTable(std::shared_ptr<nqr::BaseDecoder> decoder)
{
auto supportedExtensions = decoder->GetSupportedFileExtensions();
for (const auto ext : supportedExtensions)
{
if (decoderTable.count(ext) >= 1) throw std::runtime_error("decoder already exists for extension");
decoderTable.insert(DecoderPair(ext, decoder));
}
}
void NyquistIO::BuildDecoderTable()
{
AddDecoderToTable(std::make_shared<WavDecoder>());
AddDecoderToTable(std::make_shared<WavPackDecoder>());
AddDecoderToTable(std::make_shared<FlacDecoder>());
AddDecoderToTable(std::make_shared<VorbisDecoder>());
AddDecoderToTable(std::make_shared<OpusDecoder>());
AddDecoderToTable(std::make_shared<MusepackDecoder>());
AddDecoderToTable(std::make_shared<Mp3Decoder>());
}
NyquistFileBuffer nqr::ReadFile(const std::string & pathToFile)
{
//std::cout << "[Debug] Open: " << pathToFile << std::endl;
FILE * audioFile = fopen(pathToFile.c_str(), "rb");
if (!audioFile)
{
throw std::runtime_error("file not found");
}
fseek(audioFile, 0, SEEK_END);
size_t lengthInBytes = ftell(audioFile);
fseek(audioFile, 0, SEEK_SET);
// Allocate temporary buffer
std::vector<uint8_t> fileBuffer(lengthInBytes);
size_t elementsRead = fread(fileBuffer.data(), 1, lengthInBytes, audioFile);
if (elementsRead == 0 || fileBuffer.size() < 64)
{
throw std::runtime_error("error reading file or file too small");
}
NyquistFileBuffer data = {std::move(fileBuffer), elementsRead};
fclose(audioFile);
// Copy out to user
return data;
}
@ -64,7 +219,7 @@ NyquistFileBuffer nqr::ReadFile(std::string pathToFile)
void nqr::ConvertToFloat32(float * dst, const uint8_t * src, const size_t N, PCMFormat f)
{
assert(f != PCM_END);
if (f == PCM_U8)
{
const uint8_t * dataPtr = reinterpret_cast<const uint8_t *>(src);
@ -100,14 +255,15 @@ void nqr::ConvertToFloat32(float * dst, const uint8_t * src, const size_t N, PCM
for (size_t i = 0; i < N; ++i)
dst[i] = int32_to_float32(Read32(dataPtr[i]));
}
//@todo add int64 format
else if (f == PCM_FLT)
{
const float * dataPtr = reinterpret_cast<const float *>(src);
std::memcpy(dst, src, N * sizeof(float));
/* const float * dataPtr = reinterpret_cast<const float *>(src);
for (size_t i = 0; i < N; ++i)
dst[i] = (float) Read32(dataPtr[i]);
dst[i] = (float) Read32(dataPtr[i]); */
}
else if (f == PCM_DBL)
{
@ -121,7 +277,7 @@ void nqr::ConvertToFloat32(float * dst, const uint8_t * src, const size_t N, PCM
void nqr::ConvertToFloat32(float * dst, const int32_t * src, const size_t N, PCMFormat f)
{
assert(f != PCM_END);
if (f == PCM_16)
{
for (size_t i = 0; i < N; ++i)
@ -160,7 +316,7 @@ void nqr::ConvertFromFloat32(uint8_t * dst, const float * src, const size_t N, P
assert(f != PCM_END);
Dither dither(t);
if (f == PCM_U8)
{
uint8_t * destPtr = reinterpret_cast<uint8_t *>(dst);

@ -0,0 +1,442 @@
/*
Copyright (c) 2019, Dimitri Diakopoulos All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Encoders.h"
#include <fstream>
using namespace nqr;
static inline void to_bytes(uint8_t value, char * arr)
{
arr[0] = (value) & 0xFF;
}
static inline void to_bytes(uint16_t value, char * arr)
{
arr[0] = (value) & 0xFF;
arr[1] = (value >> 8) & 0xFF;
}
static inline void to_bytes(uint32_t value, char * arr)
{
arr[0] = (value) & 0xFF;
arr[1] = (value >> 8) & 0xFF;
arr[2] = (value >> 16) & 0xFF;
arr[3] = (value >> 24) & 0xFF;
}
////////////////////////////
// Wave File Encoding //
////////////////////////////
int nqr::encode_wav_to_disk(const EncoderParams p, const AudioData * d, const std::string & path)
{
if (!d->samples.size())
return EncoderError::InsufficientSampleData;
// Cast away const because we know what we are doing (Hopefully?)
float * sampleData = const_cast<float *>(d->samples.data());
size_t sampleDataSize = d->samples.size();
std::vector<float> sampleDataOptionalMix;
if (sampleDataSize <= 32)
{
return EncoderError::InsufficientSampleData;
}
if (d->channelCount < 1 || d->channelCount > 8)
{
return EncoderError::UnsupportedChannelConfiguration;
}
// Handle Channel Mixing --
// Mono => Stereo
if (d->channelCount == 1 && p.channelCount == 2)
{
sampleDataOptionalMix.resize(sampleDataSize * 2);
MonoToStereo(sampleData, sampleDataOptionalMix.data(), sampleDataSize); // Mix
// Re-point data
sampleData = sampleDataOptionalMix.data();
sampleDataSize = sampleDataOptionalMix.size();
}
// Stereo => Mono
else if (d->channelCount == 2 && p.channelCount == 1)
{
sampleDataOptionalMix.resize(sampleDataSize / 2);
StereoToMono(sampleData, sampleDataOptionalMix.data(), sampleDataSize); // Mix
// Re-point data
sampleData = sampleDataOptionalMix.data();
sampleDataSize = sampleDataOptionalMix.size();
}
else if (d->channelCount == p.channelCount) { /* do nothing */ }
else return EncoderError::UnsupportedChannelMix;
// -- End Channel Mixing
auto maxFileSizeInBytes = std::numeric_limits<uint32_t>::max();
auto samplesSizeInBytes = (sampleDataSize * GetFormatBitsPerSample(p.targetFormat)) / 8;
// 64 arbitrary
if ((samplesSizeInBytes - 64) >= maxFileSizeInBytes)
{
return EncoderError::BufferTooBig;
}
// Don't support PC64 or PCDBL
if (GetFormatBitsPerSample(p.targetFormat) > 32)
{
return EncoderError::UnsupportedBitdepth;
}
std::ofstream fout(path.c_str(), std::ios::out | std::ios::binary);
if (!fout.is_open())
{
return EncoderError::FileIOError;
}
char * chunkSizeBuff = new char[4];
// Initial size (this is changed after we're done writing the file)
to_bytes(uint32_t(36), chunkSizeBuff);
// RIFF file header
fout.write(GenerateChunkCodeChar('R', 'I', 'F', 'F'), 4);
fout.write(chunkSizeBuff, 4);
fout.write(GenerateChunkCodeChar('W', 'A', 'V', 'E'), 4);
// Fmt header
auto header = MakeWaveHeader(p, d->sampleRate);
fout.write(reinterpret_cast<char*>(&header), sizeof(WaveChunkHeader));
auto sourceBits = GetFormatBitsPerSample(d->sourceFormat);
auto targetBits = GetFormatBitsPerSample(p.targetFormat);
//@todo - channel mixing!
// Write out fact chunk
if (p.targetFormat == PCM_FLT)
{
uint32_t four = 4;
uint32_t dataSz = int(sampleDataSize / p.channelCount);
fout.write(GenerateChunkCodeChar('f', 'a', 'c', 't'), 4);
fout.write(reinterpret_cast<const char *>(&four), 4);
fout.write(reinterpret_cast<const char *>(&dataSz), 4); // Number of samples (per channel)
}
// Data header
fout.write(GenerateChunkCodeChar('d', 'a', 't', 'a'), 4);
// + data chunk size
to_bytes(uint32_t(samplesSizeInBytes), chunkSizeBuff);
fout.write(chunkSizeBuff, 4);
if (targetBits <= sourceBits && p.targetFormat != PCM_FLT)
{
// At most need this number of bytes in our copy
std::vector<uint8_t> samplesCopy(samplesSizeInBytes);
ConvertFromFloat32(samplesCopy.data(), sampleData, sampleDataSize, p.targetFormat, p.dither);
fout.write(reinterpret_cast<const char*>(samplesCopy.data()), samplesSizeInBytes);
}
else
{
// Handle PCFLT. Coming in from AudioData ensures we start with 32 bits, so we're fine
// since we've also rejected formats with more than 32 bits above.
fout.write(reinterpret_cast<const char*>(sampleData), samplesSizeInBytes);
}
// Padding byte
if (isOdd(samplesSizeInBytes))
{
const char * zero = "";
fout.write(zero, 1);
}
// Find size
long totalSize = fout.tellp();
// Modify RIFF header
fout.seekp(4);
// Total size of the file, less 8 bytes for the RIFF header
to_bytes(uint32_t(totalSize - 8), chunkSizeBuff);
fout.write(chunkSizeBuff, 4);
delete[] chunkSizeBuff;
return EncoderError::NoError;
}
////////////////////////////
// Opus File Encoding //
////////////////////////////
#include "opus/opusfile/include/opusfile.h"
#include "ogg/ogg.h"
typedef std::pair<std::string, std::string> metadata_t;
class OggWriter
{
void write_to_ostream(bool flush)
{
while (ogg_stream_pageout(&oss, &page))
{
ostream->write(reinterpret_cast<char*>(page.header), static_cast<std::streamsize>(page.header_len));
ostream->write(reinterpret_cast<char*>(page.body), static_cast<std::streamsize>(page.body_len));
}
if (flush && ogg_stream_flush(&oss, &page))
{
ostream->write(reinterpret_cast<char*>(page.header), static_cast<std::streamsize>(page.header_len));
ostream->write(reinterpret_cast<char*>(page.body), static_cast<std::streamsize>(page.body_len));
}
}
std::vector<char> make_header(int channel_count, int preskip, long sample_rate, int gain)
{
std::vector<char> header;
std::array<char, 9> steam_count = { { 0x0, 0x1, 0x1, 0x2, 0x2, 0x3, 0x4, 0x5, 0x5 } };
std::array<char, 9> coupled_streacount = { { 0x0, 0x0, 0x1, 0x1, 0x2, 0x2, 0x2, 0x2, 0x3 } };
std::array<char, 1> chan_map_1 = { { 0x0 } };
std::array<char, 2> chan_map_2 = { { 0x0, 0x1 } };
std::array<char, 9> _preamble = { { 'O', 'p', 'u', 's', 'H', 'e', 'a', 'd', 0x1 } };
std::array<char, 1> _channel_count;
std::array<char, 2> _preskip;
std::array<char, 4> _sample_rate;
std::array<char, 2> _gain;
std::array<char, 1> _channel_family = { { 0x1 } };
to_bytes(uint8_t(channel_count), _channel_count.data());
to_bytes(uint16_t(preskip), _preskip.data());
to_bytes(uint32_t(sample_rate), _sample_rate.data());
to_bytes(uint16_t(gain), _gain.data());
header.insert(header.end(), _preamble.cbegin(), _preamble.cend());
header.insert(header.end(), _channel_count.cbegin(), _channel_count.cend());
header.insert(header.end(), _preskip.cbegin(), _preskip.cend());
header.insert(header.end(), _sample_rate.cbegin(), _sample_rate.cend());
header.insert(header.end(), _gain.cbegin(), _gain.cend());
header.insert(header.end(), _channel_family.cbegin(), _channel_family.cend());
header.push_back(steam_count[channel_count]);
header.push_back(coupled_streacount[channel_count]);
switch (channel_count)
{
case 1: header.insert(header.end(), chan_map_1.cbegin(), chan_map_1.cend()); break;
case 2: header.insert(header.end(), chan_map_2.cbegin(), chan_map_2.cend()); break;
default: throw std::runtime_error("couldn't map channel data");
}
return header;
}
std::vector<char> make_tags(const std::string & vendor, const std::vector<metadata_t> & metadata)
{
std::vector<char> tags;
std::array<char, 8> _preamble = { { 'O', 'p', 'u', 's', 'T', 'a', 'g', 's' } };
std::array<char, 4> _vendor_length;
std::array<char, 4> _metadata_count;
to_bytes(uint32_t(vendor.size()), _vendor_length.data());
to_bytes(uint32_t(metadata.size()), _metadata_count.data());
tags.insert(tags.end(), _preamble.cbegin(), _preamble.cend());
tags.insert(tags.end(), _vendor_length.cbegin(), _vendor_length.cend());
tags.insert(tags.end(), vendor.cbegin(), vendor.cend());
tags.insert(tags.end(), _metadata_count.cbegin(), _metadata_count.cend());
// Process metadata.
for (const auto & metadata_entry : metadata)
{
std::array<char, 4> _metadata_entry_length;
std::string entry = metadata_entry.first + "=" + metadata_entry.second;
to_bytes(uint32_t(entry.size()), _metadata_entry_length.data());
tags.insert(tags.end(), _metadata_entry_length.cbegin(), _metadata_entry_length.cend());
tags.insert(tags.end(), entry.cbegin(), entry.cend());
}
return tags;
}
ogg_int64_t packet_number;
ogg_int64_t granule;
ogg_page page;
ogg_stream_state oss;
int channel_count;
long sample_rate;
int bits_per_sample;
std::ofstream * ostream;
std::string description;
std::vector<metadata_t> metadata;
public:
OggWriter(int channel_count, long sample_rate, int bits_per_sample, std::ofstream & stream, const std::vector<metadata_t> & md)
{
this->channel_count = channel_count;
this->sample_rate = sample_rate;
this->bits_per_sample = bits_per_sample;
this->ostream = &stream;
this->metadata = md;
int oggInitErr, packetErr;
ogg_packet header_packet;
ogg_packet tags_packet;
std::vector<char> header_vector;
std::vector<char> tags_vector;
description = "Ogg";
packet_number = 0;
granule = 0;
// Validate parameters
if (channel_count < 1 && channel_count > 255) throw std::runtime_error("Channel count must be between 1 and 255.");
// Initialize the Ogg stream.
oggInitErr = ogg_stream_init(&oss, 12345);
if (oggInitErr) throw std::runtime_error("Could not initialize the Ogg stream state.");
// Initialize the header packet.
header_vector = make_header(channel_count, 3840, sample_rate, 0);
header_packet.packet = reinterpret_cast<unsigned char*>(header_vector.data());
header_packet.bytes = header_vector.size();
header_packet.b_o_s = 1;
header_packet.e_o_s = 0;
header_packet.granulepos = 0;
header_packet.packetno = packet_number++;
// Initialize tags
tags_vector = make_tags("libnyquist", metadata);
tags_packet.packet = reinterpret_cast<unsigned char*>(tags_vector.data());
tags_packet.bytes = tags_vector.size();
tags_packet.b_o_s = 0;
tags_packet.e_o_s = 0;
tags_packet.granulepos = 0;
tags_packet.packetno = packet_number++;
// Write header page
packetErr = ogg_stream_packetin(&oss, &header_packet);
if (packetErr) throw std::runtime_error("Could not write header packet to the Ogg stream.");
write_to_ostream(true);
// Write tags page
packetErr = ogg_stream_packetin(&oss, &tags_packet);
if (packetErr) throw std::runtime_error("Could not write tags packet to the Ogg stream.");
write_to_ostream(true);
}
~OggWriter()
{
write_to_ostream(true);
ogg_stream_clear(&oss);
}
bool write(char * data, std::streamsize length, size_t sampleCount, bool end)
{
int err;
ogg_packet packet;
granule += sampleCount;
packet.packet = reinterpret_cast<unsigned char*>(data);
packet.bytes = static_cast<long>(length);
packet.b_o_s = 0;
packet.e_o_s = end ? 1 : 0;
packet.granulepos = granule;
packet.packetno = packet_number++;
err = ogg_stream_packetin(&oss, &packet);
if (err) throw std::runtime_error("could not write packet to stream");
write_to_ostream(false);
return true;
}
};
#define OPUS_MAX_PACKET_SIZE (1024 * 8)
#define OPUS_FRAME_SIZE 960
// Opus only supports a 48k samplerate...
// This encoder only supports mono for the time being
int nqr::encode_opus_to_disk(const EncoderParams p, const AudioData * d, const std::string & path)
{
assert(d->samples.size() > 0);
//assert(d->sampleRate == 48000);
float * sampleData = const_cast<float *>(d->samples.data());
const size_t sampleDataSize = d->samples.size();
int opus_error;
OpusEncoder * enc;
enc = opus_encoder_create(48000, 1, OPUS_APPLICATION_AUDIO, &opus_error);
if (!enc) throw std::runtime_error("opus_encoder_create caused an error!");
std::ofstream fout(path.c_str(), std::ios::out | std::ios::binary);
std::vector<metadata_t> oggMetadata = { { "artist", "dimitri" } };
OggWriter writer(d->channelCount, d->sampleRate, GetFormatBitsPerSample(d->sourceFormat), fout, oggMetadata);
std::vector<uint8_t> outBuffer(OPUS_MAX_PACKET_SIZE);
int framesToEncode = (sampleDataSize / OPUS_FRAME_SIZE) - 1; // fixme
while (framesToEncode >= 0)
{
auto encoded_size = opus_encode_float(enc, sampleData, OPUS_FRAME_SIZE, outBuffer.data(), OPUS_MAX_PACKET_SIZE);
if (encoded_size < 0)
{
std::cerr << "Bad Opus Status: " << encoded_size << std::endl;
return EncoderError::FileIOError;
}
writer.write((char*)outBuffer.data(), encoded_size, OPUS_FRAME_SIZE, (framesToEncode == 0) ? true : false);
framesToEncode--;
sampleData += OPUS_FRAME_SIZE;
}
fout.close();
opus_encoder_destroy(enc);
return EncoderError::NoError;
}
#undef OPUS_MAX_PACKET_SIZE

@ -1,5 +1,5 @@
/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.
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:
@ -23,27 +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 "FlacDecoder.h"
#include "flac/all.h"
#include "flac/stream_decoder.h"
#include "Decoders.h"
#include "AudioDecoder.h"
// http://lists.xiph.org/pipermail/flac-dev/2012-March/003276.html
#define FLAC__NO_DLL
#include "FLAC/all.h"
#include "FLAC/stream_decoder.h"
#include <cstring>
using namespace nqr;
// FLAC is a big-endian format. All values are unsigned.
class FlacDecoderInternal
{
public:
// N.B.: FLAC is a big-endian format. All values are unsigned.
FlacDecoderInternal(AudioData * d, std::string filepath) : d(d)
FlacDecoderInternal(AudioData * d, const 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,10 +56,49 @@ public:
this) == FLAC__STREAM_DECODER_INIT_STATUS_OK;
FLAC__stream_decoder_set_md5_checking(decoderInternal, true);
if (initialized)
{
// Find the size and allocate memory
FLAC__stream_decoder_process_until_end_of_metadata(decoderInternal);
// Read memory out into our temporary internalBuffer
FLAC__stream_decoder_process_until_end_of_stream(decoderInternal);
// Presently unneeded, but useful for reference
// FLAC__ChannelAssignment channelAssignment = FLAC__stream_decoder_get_channel_assignment(decoderInternal);
// Fill out remaining user data
d->lengthSeconds = (float) numSamples / (float) d->sampleRate;
auto totalSamples = numSamples * d->channelCount;
// Next, process internal buffer into the user-visible samples array
ConvertToFloat32(d->samples.data(), internalBuffer.data(), totalSamples, d->sourceFormat);
}
else throw std::runtime_error("Unable to initialize FLAC decoder");
}
FlacDecoderInternal(AudioData * d, const std::vector<uint8_t> & memory) : d(d), data(std::move(memory)), dataPos(0)
{
decoderInternal = FLAC__stream_decoder_new();
//////////////////////
// Read Stream Data //
/////////////////////
FLAC__stream_decoder_set_metadata_respond(decoderInternal, FLAC__METADATA_TYPE_STREAMINFO);
bool initialized = FLAC__stream_decoder_init_stream(
decoderInternal,
read_callback,
seek_callback,
tell_callback,
length_callback,
eof_callback,
s_writeCallback,
s_metadataCallback,
s_errorCallback,
this
) == FLAC__STREAM_DECODER_INIT_STATUS_OK;
FLAC__stream_decoder_set_md5_checking(decoderInternal, true);
if (initialized)
{
@ -81,12 +119,7 @@ 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()
@ -100,7 +133,7 @@ public:
void processMetadata(const FLAC__StreamMetadata_StreamInfo & info)
{
// N.B.: "Currently the reference encoder and decoders only support up to 24 bits per sample."
// Currently the reference encoder and decoders only support up to 24 bits per sample.
d->sampleRate = info.sample_rate;
d->channelCount = info.channels; // Assert 1 to 8
d->sourceFormat = MakeFormatForBits(info.bits_per_sample, false, true);
@ -115,22 +148,20 @@ public:
}
///////////////////////
// libflab callbacks //
// libflac callbacks //
///////////////////////
static FLAC__StreamDecoderWriteStatus s_writeCallback(const FLAC__StreamDecoder*, const FLAC__Frame* frame, const FLAC__int32* const buffer[], void* userPtr)
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(unsigned int i = 0; i < frame->header.blocksize; i++)
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++)
{
memcpy(dataPtr + decoder->bufferPosition, &buffer[j][i], bytesPerSample);
std::memcpy(dataPtr + decoder->bufferPosition, &buffer[j][i], bytesPerSample);
decoder->bufferPosition += bytesPerSample;
}
}
@ -138,14 +169,58 @@ public:
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
static void s_metadataCallback (const FLAC__StreamDecoder*, const FLAC__StreamMetadata* metadata, void* userPtr)
static void s_metadataCallback (const FLAC__StreamDecoder *, const FLAC__StreamMetadata * metadata, void * userPtr)
{
static_cast<FlacDecoderInternal*>(userPtr)->processMetadata(metadata->data.stream_info);
}
static void s_errorCallback (const FLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus status, void*)
static void s_errorCallback (const FLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus status, void *)
{
std::cerr << "FLAC Decoder Error: " << FLAC__StreamDecoderErrorStatusString[status] << std::endl;
throw std::runtime_error("FLAC decode exception " + std::string(FLAC__StreamDecoderErrorStatusString[status]));
}
static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
{
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
size_t readLength = std::min<size_t>(*bytes, decoderInternal->data.size() - decoderInternal->dataPos);
if (readLength > 0)
{
std::memcpy(buffer, decoderInternal->data.data(), readLength);
decoderInternal->dataPos += readLength;
*bytes = readLength;
if (decoderInternal->dataPos < decoderInternal->data.size()) return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
else return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
}
else return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
}
static FLAC__StreamDecoderSeekStatus seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
{
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
size_t newPos = std::min<size_t>(absolute_byte_offset, decoderInternal->data.size() - decoderInternal->dataPos);
decoderInternal->dataPos = newPos;
return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
}
static FLAC__StreamDecoderTellStatus tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
{
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
*absolute_byte_offset = decoderInternal->dataPos;
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
}
static FLAC__StreamDecoderLengthStatus length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
{
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
*stream_length = decoderInternal->data.size();
return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
}
static FLAC__bool eof_callback(const FLAC__StreamDecoder *decoder, void *client_data)
{
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
return decoderInternal->dataPos == decoderInternal->data.size();
}
private:
@ -153,7 +228,8 @@ private:
NO_COPY(FlacDecoderInternal);
FLAC__StreamDecoder * decoderInternal;
std::vector<uint8_t> data;
size_t dataPos;
size_t bufferPosition = 0;
size_t numSamples = 0;
@ -166,18 +242,17 @@ private:
// Public Interface //
//////////////////////
int FlacDecoder::LoadFromPath(AudioData * data, const std::string & path)
void FlacDecoder::LoadFromPath(AudioData * data, const std::string & path)
{
FlacDecoderInternal decoder(data, path);
return IOError::NoError;
}
int FlacDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
void FlacDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
{
return IOError::LoadBufferNotImplemented;
FlacDecoderInternal decoder(data, memory);
}
std::vector<std::string> FlacDecoder::GetSupportedFileExtensions()
{
return {"flac"};
}
}

@ -1,5 +1,5 @@
/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.
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:
@ -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(_MSC_VER)
#include "flac/src/win_utf8_io.c"
#if defined(_WIN32) || defined(_WIN64)
#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
@ -105,4 +105,4 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if (_MSC_VER)
#pragma warning (pop)
#endif
#endif

@ -0,0 +1,80 @@
/*
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) 2015, Dimitri Diakopoulos All rights reserved.
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:
@ -23,7 +23,7 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "MusepackDecoder.h"
#include "Decoders.h"
using namespace nqr;
@ -50,7 +50,7 @@ class MusepackInternal
{
mpc_reader_state *p_mem = (mpc_reader_state*) p_reader->data;
if (p_mem->magic != STDIO_MAGIC) return MPC_STATUS_FAIL;
mpc_int32_t max = (p_mem->p_end - p_mem->p_file);
mpc_int32_t max = mpc_int32_t(p_mem->p_end - p_mem->p_file);
if (size >= max) size = max;
memcpy((unsigned char *)ptr, p_mem->p_file, size);
p_mem->p_file += size;
@ -72,14 +72,14 @@ class MusepackInternal
{
mpc_reader_state *p_mem = (mpc_reader_state*) p_reader->data;
if(p_mem->magic != STDIO_MAGIC) return MPC_STATUS_FAIL;
return p_mem->p_file - p_mem->p_begin;
return mpc_int32_t(p_mem->p_file - p_mem->p_begin);
}
static mpc_int32_t get_size_mem(mpc_reader *p_reader)
{
mpc_reader_state *p_mem = (mpc_reader_state*) p_reader->data;
if (p_mem->magic != STDIO_MAGIC) return MPC_STATUS_FAIL;
return p_mem->p_end - p_mem->p_begin;
return mpc_int32_t(p_mem->p_end - p_mem->p_begin);
}
static mpc_bool_t canseek_mem(mpc_reader *p_reader)
@ -94,7 +94,7 @@ public:
// Musepack is a purely variable bitrate format and does not work at a constant bitrate.
MusepackInternal(AudioData * d, const std::vector<uint8_t> & fileData) : d(d)
{
decoderMemory.reset(new mpc_reader_state());
decoderMemory = std::make_shared<mpc_reader_state>();
decoderMemory->magic = STDIO_MAGIC;
decoderMemory->p_file = (unsigned char *) fileData.data();
@ -110,18 +110,17 @@ 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);
d->sampleRate = (float) streamInfo.sample_freq;
d->sampleRate = (int) streamInfo.sample_freq;
d->channelCount = streamInfo.channels;
d->sourceFormat = MakeFormatForBits(32, true, false);
d->lengthSeconds = (double) mpc_streaminfo_get_length(&streamInfo);
auto totalSamples = size_t(mpc_streaminfo_get_length_samples(&streamInfo));
d->samples.reserve(totalSamples * d->channelCount + (MPC_DECODER_BUFFER_LENGTH / sizeof(MPC_SAMPLE_FORMAT))); // demux writes in chunks
d->samples.resize(totalSamples * d->channelCount);
if (!readInternal())
@ -130,32 +129,29 @@ public:
size_t readInternal()
{
mpc_status err;
mpc_status err = MPC_STATUS_OK;
size_t totalSamplesRead = 0;
while(MPC_TRUE)
while (true)
{
mpc_frame_info frame;
frame.buffer = d->samples.data() + totalSamplesRead;
err = mpc_demux_decode(mpcDemux, &frame);
if (frame.bits == -1) break;
if (frame.bits == -1 || err != MPC_STATUS_OK) break;
totalSamplesRead += (frame.samples * streamInfo.channels);
}
if (err != MPC_STATUS_OK)
std::cerr << "Something went wrong... " << err << std::endl;
std::cerr << "An internal error occured in mpc_demux_decode" << std::endl;
return totalSamplesRead;
}
~MusepackInternal()
{
mpc_demux_exit(mpcDemux);
if (mpcDemux) mpc_demux_exit(mpcDemux);
}
@ -166,7 +162,7 @@ private:
mpc_decoder decoder;
mpc_demux * mpcDemux;
std::unique_ptr<mpc_reader_state> decoderMemory;
std::shared_ptr<mpc_reader_state> decoderMemory;
NO_MOVE(MusepackInternal);
@ -178,20 +174,18 @@ private:
// Public Interface //
//////////////////////
int MusepackDecoder::LoadFromPath(AudioData * data, const std::string & path)
void MusepackDecoder::LoadFromPath(AudioData * data, const std::string & path)
{
auto fileBuffer = nqr::ReadFile(path);
MusepackInternal decoder(data, fileBuffer.buffer);
return IOError::NoError;
}
int MusepackDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
void MusepackDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
{
MusepackInternal decoder(data, memory);
return IOError::NoError;
}
std::vector<std::string> MusepackDecoder::GetSupportedFileExtensions()
{
return {"mpc", "mpp"};
}
}

@ -1,5 +1,5 @@
/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.
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:
@ -36,16 +36,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#include "musepack/libmpcdec/huffman.c"
//#include "musepack/libmpcdec/mpc_decoder.c"
//#include "musepack/libmpcdec/mpc_reader.c"
//#include "musepack/libmpcdec/mpc_bits_reader.c"
//#include "musepack/libmpcdec/mpc_demux.c"
#include "musepack/libmpcdec/requant.c"
#include "musepack/libmpcdec/streaminfo.c"
#include "musepack/libmpcdec/synth_filter.c"
#include "musepack/libmpcdec/crc32.c"
#include "musepack/libmpcdec/mpc_reader.c"
#include "musepack/libmpcdec/mpc_decoder.c"
#include "musepack/libmpcdec/mpc_demux.c"
#include "musepack/libmpcdec/mpc_bits_reader.c"
#ifdef __clang__
#pragma clang diagnostic pop

@ -1,5 +1,5 @@
/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.
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:
@ -23,13 +23,19 @@ 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 "OpusDecoder.h"
#include "Decoders.h"
#include "opus/opusfile/include/opusfile.h"
using namespace nqr;
static const int OPUS_SAMPLE_RATE = 48000;
// Opus is a general-purpose codec designed to replace Vorbis at some point. Primarily, it's a low
// delay format making it suitable for high-quality, real time streaming. It's not really
// an archival format or something designed for heavy DSP post-processing since
// it's fundamentally limited to encode/decode at 48khz.
// https://mf4.xiph.org/jenkins/view/opus/job/opusfile-unix/ws/doc/html/index.html
class OpusDecoderInternal
{
@ -160,20 +166,18 @@ private:
// Public Interface //
//////////////////////
int nqr::OpusDecoder::LoadFromPath(AudioData * data, const std::string & path)
void nqr::OpusDecoder::LoadFromPath(AudioData * data, const std::string & path)
{
auto fileBuffer = nqr::ReadFile(path);
OpusDecoderInternal decoder(data, fileBuffer.buffer);
return IOError::NoError;
}
int nqr::OpusDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
void nqr::OpusDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
{
OpusDecoderInternal decoder(data, memory);
return IOError::NoError;
}
std::vector<std::string> nqr::OpusDecoder::GetSupportedFileExtensions()
{
return {"opus"};
}
}

@ -1,5 +1,5 @@
/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.
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:
@ -39,12 +39,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#undef HAVE_CONFIG_H
#define USE_ALLOCA 1
#define OPUS_BUILD 1
#define USE_ALLOCA 1
#define OPUS_BUILD 1
/* Enable SSE functions, if compiled with SSE/SSE2 (note that AMD64 implies SSE2) */
#if defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1))
#define __SSE__ 1
#define __SSE__ 1
#endif
//////////
@ -92,15 +92,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "opus/celt/rate.c"
#include "opus/celt/vq.c"
// Disabled inline because of name clash of opus_custom_encoder_get_size.
//#include "opus/celt/celt_decoder.c"
//#include "opus/celt/celt_encoder.c"
/*
See celt/celt_decoder.c + celt/celt_encoder.c in the project browser.
These files need to be in separate translation units due to name clashes,
unfortunately.
*/
//#define opus_custom_encoder_get_size opus_custom_encoder_get_size_alt
#include "opus/celt/celt_decoder.c"
#include "opus/celt/celt_encoder.c"
/////////////////
// SILK Common //

@ -1,66 +0,0 @@
/*
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) 2015, Dimitri Diakopoulos All rights reserved.
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:
@ -23,75 +23,44 @@ 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 "VorbisDecoder.h"
#include "Decoders.h"
#include "libvorbis/include/vorbis/vorbisfile.h"
#include <string.h>
using namespace nqr;
//@todo: implement decoding from memory (c.f. http://stackoverflow.com/questions/13437422/libvorbis-audio-decode-from-memory-in-c)
class VorbisDecoderInternal
{
public:
VorbisDecoderInternal(AudioData * d, const std::vector<uint8_t> & memory) : d(d)
{
void * data = const_cast<uint8_t*>(memory.data());
ogg_file t;
t.curPtr = t.filePtr = static_cast<char*>(data);
t.fileSize = memory.size();
fileHandle = new OggVorbis_File;
memset(fileHandle, 0, sizeof(OggVorbis_File));
ov_callbacks callbacks;
callbacks.read_func = AR_readOgg;
callbacks.seek_func = AR_seekOgg;
callbacks.close_func = AR_closeOgg;
callbacks.tell_func = AR_tellOgg;
loadAudioData(&t, callbacks);
}
VorbisDecoderInternal(AudioData * d, std::string filepath) : d(d)
{
fileHandle = new OggVorbis_File();
/* @todo proper steaming support + classes
const ov_callbacks callbacks =
{
.read_func = s_readCallback,
.seek_func = s_seekCallback,
.tell_func = s_tellCallback,
.close_func = nullptr
};
*/
FILE * f = fopen(filepath.c_str(), "rb");
if (!f)
throw std::runtime_error("Can't open file");
if (auto r = ov_test_callbacks(f, fileHandle, nullptr, 0, OV_CALLBACKS_DEFAULT) != 0)
{
std::cerr << errorAsString(r) << std::endl;
throw std::runtime_error("File is not a valid ogg vorbis file");
}
if (auto r = ov_test_open(fileHandle) != 0)
{
std::cerr << errorAsString(r) << std::endl;
throw std::runtime_error("ov_test_open failed");
}
// N.B.: Don't need to fclose() after an open -- vorbis does this internally
vorbis_info *ovInfo = ov_info(fileHandle, -1);
if (ovInfo == nullptr)
{
throw std::runtime_error("Reading metadata failed");
}
if (auto r = ov_streams(fileHandle) != 1)
{
std::cerr << errorAsString(r) << std::endl;
throw std::runtime_error( "Unsupported: file contains multiple bitstreams");
}
d->sampleRate = int(ovInfo->rate);
d->channelCount = ovInfo->channels;
d->sourceFormat = MakeFormatForBits(32, true, false);
d->lengthSeconds = double(getLengthInSeconds());
d->frameSize = ovInfo->channels * GetFormatBitsPerSample(d->sourceFormat);
// Samples in a single channel
auto totalSamples = size_t(getTotalSamples());
d->samples.resize(totalSamples * d->channelCount);
if (!readInternal(totalSamples))
throw std::runtime_error("could not read any data");
if (!f) throw std::runtime_error("Can't open file");
loadAudioData(f, OV_CALLBACKS_DEFAULT);
}
~VorbisDecoderInternal()
@ -101,7 +70,6 @@ public:
size_t readInternal(size_t requestedFrameCount, size_t frameOffset = 0)
{
//@todo support offset
float **buffer = nullptr;
@ -113,13 +81,12 @@ public:
{
int64_t framesRead = ov_read_float(fileHandle, &buffer, std::min(2048, (int) framesRemaining), &bitstream);
// EOF
if(!framesRead)
break;
// end of file
if(!framesRead) break;
// Probably OV_HOLE, OV_EBADLINK, OV_EINVAL. @todo - log warning here.
if (framesRead < 0)
{
// Probably OV_HOLE, OV_EBADLINK, OV_EINVAL. Log warning here.
continue;
}
@ -131,7 +98,6 @@ public:
totalFramesRead++;
}
}
}
return totalFramesRead;
@ -167,6 +133,13 @@ public:
private:
struct ogg_file
{
char* curPtr;
char* filePtr;
size_t fileSize;
};
NO_COPY(VorbisDecoderInternal);
OggVorbis_File * fileHandle;
@ -176,21 +149,111 @@ private:
inline int64_t getLengthInSeconds() const { return int64_t(ov_time_total(const_cast<OggVorbis_File *>(fileHandle), -1)); }
inline int64_t getCurrentSample() const { return int64_t(ov_pcm_tell(const_cast<OggVorbis_File *>(fileHandle))); }
static size_t AR_readOgg(void* dst, size_t size1, size_t size2, void* fh)
{
ogg_file* of = reinterpret_cast<ogg_file*>(fh);
size_t len = size1 * size2;
if ( of->curPtr + len > of->filePtr + of->fileSize )
{
len = of->filePtr + of->fileSize - of->curPtr;
}
memcpy( dst, of->curPtr, len );
of->curPtr += len;
return len;
}
static int AR_seekOgg(void * fh, ogg_int64_t to, int type)
{
ogg_file * of = reinterpret_cast<ogg_file*>(fh);
switch (type)
{
case SEEK_CUR: of->curPtr += to; break;
case SEEK_END: of->curPtr = of->filePtr + of->fileSize - to; break;
case SEEK_SET: of->curPtr = of->filePtr + to; break;
default: return -1;
}
if (of->curPtr < of->filePtr)
{
of->curPtr = of->filePtr;
return -1;
}
if (of->curPtr > of->filePtr + of->fileSize)
{
of->curPtr = of->filePtr + of->fileSize;
return -1;
}
return 0;
}
static int AR_closeOgg(void * fh)
{
return 0;
}
static long AR_tellOgg(void * fh)
{
ogg_file * of = reinterpret_cast<ogg_file*>(fh);
return (of->curPtr - of->filePtr);
}
void loadAudioData(void *source, ov_callbacks callbacks)
{
if (auto r = ov_test_callbacks(source, fileHandle, nullptr, 0, callbacks) != 0)
{
std::cerr << errorAsString(r) << std::endl;
throw std::runtime_error("File is not a valid ogg vorbis file");
}
if (auto r = ov_test_open(fileHandle) != 0)
{
std::cerr << errorAsString(r) << std::endl;
throw std::runtime_error("ov_test_open failed");
}
// Don't need to fclose() after an open -- vorbis does this internally
vorbis_info * ovInfo = ov_info(fileHandle, -1);
if (ovInfo == nullptr) throw std::runtime_error("Reading metadata failed");
if (auto r = ov_streams(fileHandle) != 1)
{
std::cerr << errorAsString(r) << std::endl;
throw std::runtime_error( "Unsupported: file contains multiple bitstreams");
}
d->sampleRate = int(ovInfo->rate);
d->channelCount = ovInfo->channels;
d->sourceFormat = MakeFormatForBits(32, true, false);
d->lengthSeconds = double(getLengthInSeconds());
d->frameSize = ovInfo->channels * GetFormatBitsPerSample(d->sourceFormat);
// Samples in a single channel
auto totalSamples = size_t(getTotalSamples());
d->samples.resize(totalSamples * d->channelCount);
if (!readInternal(totalSamples)) throw std::runtime_error("could not read any data");
}
};
//////////////////////
// Public Interface //
//////////////////////
int VorbisDecoder::LoadFromPath(AudioData * data, const std::string & path)
void VorbisDecoder::LoadFromPath(AudioData * data, const std::string & path)
{
VorbisDecoderInternal decoder(data, path);
return IOError::NoError;
}
int VorbisDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
void VorbisDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
{
return IOError::LoadBufferNotImplemented;
VorbisDecoderInternal decoder(data, memory);
}
std::vector<std::string> VorbisDecoder::GetSupportedFileExtensions()

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

@ -1,5 +1,5 @@
/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.
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:
@ -23,23 +23,127 @@ 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 "WavDecoder.h"
#include "RiffUtils.h"
#include "IMA4Util.h"
#include "Decoders.h"
#include <cstring>
using namespace nqr;
struct ADPCMState
{
int frame_size;
int firstDataBlockByte;
int dataSize;
int currentByte;
const uint8_t * inBuffer;
};
static const int ima_index_table[16] =
{
-1, -1, -1, -1, // +0 / +3 : - the step
2, 4, 6, 8, // +4 / +7 : + the step
-1, -1, -1, -1, // -0 / -3 : - the step
2, 4, 6, 8, // -4 / -7 : + the step
};
static inline int ima_clamp_index(int index)
{
if (index < 0) return 0;
else if (index > 88) return 88;
return index;
}
static inline int16_t ima_clamp_predict(int16_t predict)
{
if (predict < -32768) return -32768;
else if (predict > 32767) return 32767;
return predict;
}
static const int ima_step_table[89] =
{
7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34,
37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494,
544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552,
1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026,
4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623,
27086, 29794, 32767
};
// Decodes an IMA ADPCM nibble to a 16 bit pcm sample
static inline int16_t decode_nibble(uint8_t nibble, int16_t & p, int & s)
{
// Compute a delta to add to the predictor value
int diff = ima_step_table[s] >> 3;
if (nibble & 4) diff += ima_step_table[s];
if (nibble & 2) diff += ima_step_table[s] >> 1;
if (nibble & 1) diff += ima_step_table[s] >> 2;
// Sign
if (nibble & 8) diff = -diff;
// Add delta
p += diff;
s += ima_index_table[nibble];
s = ima_clamp_index(s);
return ima_clamp_predict(p);
}
void decode_ima_adpcm(ADPCMState & state, int16_t * outBuffer, uint32_t num_channels)
{
const uint8_t * data = state.inBuffer;
// Loop over the interleaved channels
for (uint32_t ch = 0; ch < num_channels; ch++)
{
const int byteOffset = ch * 4;
// Header Structure:
// Byte0: packed low byte of the initial predictor
// Byte1: packed high byte of the initial predictor
// Byte2: initial step index
// Byte3: Reserved empty value
int16_t predictor = ((int16_t)data[byteOffset + 1] << 8) | data[byteOffset];
int stepIndex = data[byteOffset + 2];
uint8_t reserved = data[byteOffset + 3];
if (reserved != 0) throw std::runtime_error("adpcm decode error");
int byteIdx = num_channels * 4 + byteOffset; //the byte index of the first data word for this channel
int idx = ch;
// Decode nibbles of the remaining data
while (byteIdx < state.frame_size)
{
for (int j = 0; j < 4; j++)
{
outBuffer[idx] = decode_nibble(data[byteIdx] & 0xf, predictor, stepIndex); // low nibble
idx += num_channels;
outBuffer[idx] = decode_nibble(data[byteIdx] >> 4, predictor, stepIndex); // high nibble
idx += num_channels;
byteIdx++;
}
byteIdx += (num_channels - 1) << 2; // Jump to the next data word for the current channel
}
}
}
//////////////////////
// Public Interface //
//////////////////////
int WavDecoder::LoadFromPath(AudioData * data, const std::string & path)
void WavDecoder::LoadFromPath(AudioData * data, const std::string & path)
{
auto fileBuffer = nqr::ReadFile(path);
return LoadFromBuffer(data, fileBuffer.buffer);
}
int WavDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
void WavDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
{
//////////////////////
// Read RIFF Header //
@ -110,16 +214,13 @@ int WavDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & me
case 64: data->sourceFormat = (wavHeader.format == WaveFormatCode::FORMAT_IEEE) ? PCMFormat::PCM_DBL : PCMFormat::PCM_64; break;
}
std::cout << wavHeader << std::endl;
//std::cout << wavHeader << std::endl;
bool scanForFact = false;
bool grabExtensibleData = false;
bool adpcmEncoded = false;
if (wavHeader.format == WaveFormatCode::FORMAT_PCM)
{
}
else if (wavHeader.format == WaveFormatCode::FORMAT_IEEE)
if (wavHeader.format == WaveFormatCode::FORMAT_IEEE)
{
scanForFact = true;
}
@ -130,8 +231,7 @@ int WavDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & me
}
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
//std::cout << "[format id] extended" << std::endl;
// Used when (1) PCM data has more than 16 bits; (2) channels > 2; (3) bits/sample !== container size; (4) channel/speaker mapping specified;
scanForFact = true;
grabExtensibleData = true;
}
@ -194,19 +294,17 @@ int WavDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & me
s.currentByte = 0;
s.inBuffer = const_cast<uint8_t*>(memory.data() + DataChunkInfo.offset);
// An encoded sample is 4 bits that expands to 16
size_t totalSamples = factChunk.sample_length * 4;
std::vector<int16_t> adpcm_pcm16(totalSamples, 0);
size_t totalSamples = (factChunk.sample_length * wavHeader.channel_count); // Samples per channel times channel count
std::vector<int16_t> adpcm_pcm16(totalSamples * 2, 0); // Each frame decodes into twice as many pcm samples
uint32_t frameOffset = 0;
unsigned numFrames = DataChunkInfo.size / s.frame_size;
for (int i = 0; i < numFrames; ++i)
uint32_t frameCount = DataChunkInfo.size / s.frame_size;
for (uint32_t i = 0; i < frameCount; ++i)
{
decode_ima_adpcm(s, adpcm_pcm16.data() + frameOffset, wavHeader.channel_count);
s.inBuffer += s.frame_size;
frameOffset += (wavHeader.channel_count * s.frame_size);
frameOffset += (s.frame_size * 2) - (8 * wavHeader.channel_count);
}
data->lengthSeconds = ((float) totalSamples / (float) wavHeader.sample_rate) / wavHeader.channel_count;
@ -220,8 +318,6 @@ int WavDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & me
data->samples.resize(totalSamples);
ConvertToFloat32(data->samples.data(), memory.data() + DataChunkInfo.offset, totalSamples, data->sourceFormat);
}
return IOError::NoError;
}
std::vector<std::string> WavDecoder::GetSupportedFileExtensions()

@ -1,189 +0,0 @@
/*
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 "WavEncoder.h"
#include <fstream>
using namespace nqr;
inline void toBytes(int value, char * arr)
{
arr[0] = (value) & 0xFF;
arr[1] = (value >> 8) & 0xFF;
arr[2] = (value >> 16) & 0xFF;
arr[3] = (value >> 24) & 0xFF;
}
int WavEncoder::WriteFile(const EncoderParams p, const AudioData * d, const std::string & path)
{
// Cast away const because we know what we are doing (Hopefully?)
float * sampleData = const_cast<float *>(d->samples.data());
size_t sampleDataSize = d->samples.size();
std::vector<float> sampleDataOptionalMix;
if (sampleDataSize <= 32)
{
return EncoderError::InsufficientSampleData;
}
if (d->channelCount < 1 || d->channelCount > 8)
{
return EncoderError::UnsupportedChannelConfiguration;
}
// Handle Channel Mixing --
// Mono => Stereo
if (d->channelCount == 1 && p.channelCount == 2)
{
sampleDataOptionalMix.resize(sampleDataSize * 2);
MonoToStereo(sampleData, sampleDataOptionalMix.data(), sampleDataSize); // Mix
// Re-point data
sampleData = sampleDataOptionalMix.data();
sampleDataSize = sampleDataOptionalMix.size();
}
// Stereo => Mono
else if (d->channelCount == 2 && p.channelCount == 1)
{
sampleDataOptionalMix.resize(sampleDataSize / 2);
StereoToMono(sampleData, sampleDataOptionalMix.data(), sampleDataSize); // Mix
// Re-point data
sampleData = sampleDataOptionalMix.data();
sampleDataSize = sampleDataOptionalMix.size();
}
else if (d->channelCount == p.channelCount)
{
// No op
}
else
{
return EncoderError::UnsupportedChannelMix;
}
// -- End Channel Mixing
auto maxFileSizeInBytes = std::numeric_limits<uint32_t>::max();
auto samplesSizeInBytes = (sampleDataSize * GetFormatBitsPerSample(p.targetFormat)) / 8;
// 64 arbitrary
if ((samplesSizeInBytes - 64) >= maxFileSizeInBytes)
{
return EncoderError::BufferTooBig;
}
// Don't support PCM_64 or PCM_DBL
if (GetFormatBitsPerSample(p.targetFormat) > 32)
{
return EncoderError::UnsupportedBitdepth;
}
std::ofstream fout(path.c_str(), std::ios::out | std::ios::binary);
if (!fout.is_open())
{
return EncoderError::FileIOError;
}
char * chunkSizeBuff = new char[4];
// Initial size (this is changed after we're done writing the file)
toBytes(36, chunkSizeBuff);
// RIFF file header
fout.write(GenerateChunkCodeChar('R', 'I', 'F', 'F'), 4);
fout.write(chunkSizeBuff, 4);
fout.write(GenerateChunkCodeChar('W', 'A', 'V', 'E'), 4);
// Fmt header
auto header = MakeWaveHeader(p, d->sampleRate);
fout.write(reinterpret_cast<char*>(&header), sizeof(WaveChunkHeader));
auto sourceBits = GetFormatBitsPerSample(d->sourceFormat);
auto targetBits = GetFormatBitsPerSample(p.targetFormat);
////////////////////////////
//@todo - channel mixing! //
////////////////////////////
// Write out fact chunk
if (p.targetFormat == PCM_FLT)
{
uint32_t four = 4;
uint32_t dataSz = int(sampleDataSize / p.channelCount);
fout.write(GenerateChunkCodeChar('f', 'a', 'c', 't'), 4);
fout.write(reinterpret_cast<const char *>(&four), 4);
fout.write(reinterpret_cast<const char *>(&dataSz), 4); // Number of samples (per channel)
}
// Data header
fout.write(GenerateChunkCodeChar('d', 'a', 't', 'a'), 4);
// + data chunk size
toBytes(int(samplesSizeInBytes), chunkSizeBuff);
fout.write(chunkSizeBuff, 4);
if (targetBits <= sourceBits && p.targetFormat != PCM_FLT)
{
// At most need this number of bytes in our copy
std::vector<uint8_t> samplesCopy(samplesSizeInBytes);
ConvertFromFloat32(samplesCopy.data(), sampleData, sampleDataSize, p.targetFormat, p.dither);
fout.write(reinterpret_cast<const char*>(samplesCopy.data()), samplesSizeInBytes);
}
else
{
// Handle PCM_FLT. Coming in from AudioData ensures we start with 32 bits, so we're fine
// since we've also rejected formats with more than 32 bits above.
fout.write(reinterpret_cast<const char*>(sampleData), samplesSizeInBytes);
}
// Padding byte
if (isOdd(samplesSizeInBytes))
{
const char * zero = "";
fout.write(zero, 1);
}
// Find size
long totalSize = fout.tellp();
// Modify RIFF header
fout.seekp(4);
// Total size of the file, less 8 bytes for the RIFF header
toBytes(int(totalSize - 8), chunkSizeBuff);
fout.write(chunkSizeBuff, 4);
delete[] chunkSizeBuff;
return EncoderError::NoError;
}

@ -1,5 +1,5 @@
/*
Copyright (c) 2015, Dimitri Diakopoulos All rights reserved.
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:
@ -23,8 +23,10 @@ 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 "WavPackDecoder.h"
#include "Decoders.h"
#include "wavpack.h"
#include <string.h>
#include <cstring>
using namespace nqr;
@ -33,50 +35,36 @@ 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)
if (!context) throw std::runtime_error("Not a WavPack file");
auto totalSamples = size_t(WavpackGetNumSamples(context));
decode(totalSamples);
}
WavPackInternal(AudioData * d, const std::vector<uint8_t> & memory) : d(d)
{
char errorStr[128];
context = WavpackOpenRawDecoder((void *) memory.data(), memory.size(), nullptr, 0, 0, errorStr, OPEN_WVC | OPEN_NORMALIZE, 0);
// Since we are using OpenRawDecoder, WavpackGetNumSamples won't work.
// Instead, find the first block and get totalSamples from its header.
WavpackHeader wph;
auto headerOffset = readNextHeader(memory, &wph, 0);
if (!context || headerOffset == -1)
{
throw std::runtime_error("Not a WavPack file");
}
auto 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);
auto totalSamples = wph.total_samples;
decode(totalSamples);
}
~WavPackInternal()
@ -89,8 +77,6 @@ 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);
@ -111,17 +97,69 @@ public:
}
// EOF
//if (framesRead == 0)
// break;
//if (framesRead == 0) break;
totalFramesRead += framesRead;
framesRemaining -= framesRead;
}
return totalFramesRead;
}
private:
void decode(size_t totalSamples) {
auto bitdepth = WavpackGetBitsPerSample(context);
d->sampleRate = WavpackGetSampleRate(context);
d->channelCount = WavpackGetNumChannels(context);
d->lengthSeconds = double(totalSamples / WavpackGetSampleRate(context));
d->frameSize = d->channelCount * bitdepth;
//@todo support channel masks
// WavpackGetChannelMask
int mode = WavpackGetMode(context);
bool isFloatingPoint = (MODE_FLOAT & mode);
d->sourceFormat = MakeFormatForBits(bitdepth, isFloatingPoint, false);
d->samples.resize(totalSamples * d->channelCount);
if (!isFloatingPoint)
internalBuffer.resize(totalSamples * d->channelCount);
if (!readInternal(totalSamples))
throw std::runtime_error("could not read any data");
// Next, process internal buffer into the user-visible samples array
if (!isFloatingPoint)
ConvertToFloat32(d->samples.data(), internalBuffer.data(), totalSamples * d->channelCount, d->sourceFormat);
}
int64_t readNextHeader(const std::vector<uint8_t> & memory, WavpackHeader *wphdr, size_t startOffset) {
/// Based on read_next_header function in wavpack's openutils.c.
/// This will find the position of the next WavPack header in the given vector, at or after startOffset.
/// If a header is found, it will write the header to *wphdr and return the position of its first byte in the vector.
/// Otherwise, it will return -1.
unsigned char* sp;
for (size_t i = startOffset; i < memory.size(); i++) {
sp = const_cast<unsigned char *>(memory.data() + i);
auto headerStartPoint = sp;
if (*sp++ == 'w' && *sp == 'v' && *++sp == 'p' && *++sp == 'k' &&
!(*++sp & 1) && sp [2] < 16 && !sp [3] && (sp [2] || sp [1] || *sp >= 24) && sp [5] == 4 &&
sp [4] >= (MIN_STREAM_VERS & 0xff) && sp [4] <= (MAX_STREAM_VERS & 0xff) && sp [18] < 3 && !sp [19]) {
memcpy (wphdr, headerStartPoint, sizeof (*wphdr));
WavpackLittleEndianToNative (wphdr, (char*)WavpackHeaderFormat);
return i;
}
}
return -1;
}
NO_MOVE(WavPackInternal);
@ -130,7 +168,7 @@ private:
WavpackContext * context; //@todo unique_ptr
AudioData * d;
std::vector<int32_t> internalBuffer;
inline int64_t getTotalSamples() const { return WavpackGetNumSamples(context); }
@ -142,15 +180,14 @@ private:
// Public Interface //
//////////////////////
int WavPackDecoder::LoadFromPath(AudioData * data, const std::string & path)
void WavPackDecoder::LoadFromPath(AudioData * data, const std::string & path)
{
WavPackInternal decoder(data, path);
return IOError::NoError;
}
int WavPackDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
void WavPackDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
{
return IOError::LoadBufferNotImplemented;
WavPackInternal decoder(data, memory);
}
std::vector<std::string> WavPackDecoder::GetSupportedFileExtensions()

Binary file not shown.

Binary file not shown.

@ -0,0 +1,43 @@
QUEST STUDIOS
SOFTWARE SOUNDTRACK SERIES
====================================================
THE SECRET OF MONKEY ISLAND
"INTRODUCTION/OPENING THEMES"
Michael Z. Land
====================================================
Copyright (c)1989 LucasArts Entertainment Co.
====================================================
G E N E R A L M I D I V E R S I O N
System Requirements:
- MIDI Playback Software capable of reading Type 1 Standard
MIDI File format
- General MIDI sound device (Wave Table recommended.)
This Standard MIDI File was recorded directly from LucasFilm Game's
"The Secret of Monkey Island" adventure game. It has been converted
from the MT-32 version for playback on General MIDI sound cards. A
Wave Table sound card is highly recommended for optimal playback.
Recorded/Converted to Standard MIDI File format by Tom Lewandowski.
Address questions or comments to:
QUEST STUDIOS
Tom Lewandowski
tom+di@netnet.net
THE ROLAND MT-32 SOUND MODULE RESOURCE CENTER
THE SIERRA SOUNDTRACK SERIES/SOFTWARE SOUNDTRACK SERIES
http://bayland.net/~tom+di/sierra/roland.html

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

Loading…
Cancel
Save