From 2260727a66d7b780ef570caf35b726e89a8e268f Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Sat, 19 Sep 2020 15:39:46 +0200 Subject: [PATCH 1/4] Aligned vector --- cmake/SfizzConfig.cmake | 4 + external/jsl/LICENSE.md | 23 ++++++ external/jsl/include/jsl/allocator | 73 +++++++++++++++++++ .../jsl/bits/allocator/aligned_allocator.tcc | 41 +++++++++++ .../jsl/bits/allocator/ordinary_allocator.tcc | 53 ++++++++++++++ .../jsl/bits/allocator/stdc_allocator.tcc | 16 ++++ src/CMakeLists.txt | 4 +- src/sfizz/Oversampler.cpp | 10 ++- 8 files changed, 219 insertions(+), 5 deletions(-) create mode 100644 external/jsl/LICENSE.md create mode 100644 external/jsl/include/jsl/allocator create mode 100644 external/jsl/include/jsl/bits/allocator/aligned_allocator.tcc create mode 100644 external/jsl/include/jsl/bits/allocator/ordinary_allocator.tcc create mode 100644 external/jsl/include/jsl/bits/allocator/stdc_allocator.tcc diff --git a/cmake/SfizzConfig.cmake b/cmake/SfizzConfig.cmake index 0e70d9e8..0d1c29b4 100644 --- a/cmake/SfizzConfig.cmake +++ b/cmake/SfizzConfig.cmake @@ -76,6 +76,10 @@ endfunction() # The sndfile library add_library(sfizz-sndfile INTERFACE) +# The jsl utility library for C++ +add_library(sfizz-jsl INTERFACE) +target_include_directories(sfizz-jsl INTERFACE "external/jsl/include") + if (SFIZZ_USE_VCPKG OR CMAKE_CXX_COMPILER_ID MATCHES "MSVC") find_package(SndFile CONFIG REQUIRED) find_path(SNDFILE_INCLUDE_DIR sndfile.hh) diff --git a/external/jsl/LICENSE.md b/external/jsl/LICENSE.md new file mode 100644 index 00000000..44da875b --- /dev/null +++ b/external/jsl/LICENSE.md @@ -0,0 +1,23 @@ +# 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. diff --git a/external/jsl/include/jsl/allocator b/external/jsl/include/jsl/allocator new file mode 100644 index 00000000..e97c25a3 --- /dev/null +++ b/external/jsl/include/jsl/allocator @@ -0,0 +1,73 @@ +// -*- C++ -*- +#pragma once +#include +#include + +namespace jsl { + +template +struct ordinary_allocator { + typedef T value_type; + typedef T *pointer; + typedef const T *const_pointer; + typedef T &reference; + typedef const T &const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef std::true_type propagate_on_container_move_assignment; + template struct rebind { typedef ordinary_allocator other; }; + typedef std::true_type is_always_equal; + + ordinary_allocator() noexcept {} + ordinary_allocator(const ordinary_allocator &) noexcept {} + template ordinary_allocator(const ordinary_allocator&) noexcept {} + + T *address(T &x) const noexcept; + const T *address(const T &x) const noexcept; + + T *allocate(std::size_t n, const void * = nullptr); + void deallocate(T *p, std::size_t n) noexcept; + std::size_t max_size() const noexcept; + + template void construct(U *p, Args &&...args); + template void destroy(U *p); +}; + +template +inline bool operator==(const ordinary_allocator &, const ordinary_allocator &) noexcept +{ + return true; +} + +template +inline bool operator!=(const ordinary_allocator &, const ordinary_allocator &) noexcept +{ + return false; +} + +//------------------------------------------------------------------------------ + +struct stdc_allocator_traits { + static void *allocate(std::size_t n); + static void deallocate(void *p, std::size_t = 0); +}; + +template +using stdc_allocator = ordinary_allocator; + +//------------------------------------------------------------------------------ + +template +struct aligned_allocator_traits { + static void *allocate(std::size_t n); + static void deallocate(void *p, std::size_t = 0); +}; + +template +using aligned_allocator = ordinary_allocator>; + +} // namespace jsl + +#include "bits/allocator/ordinary_allocator.tcc" +#include "bits/allocator/stdc_allocator.tcc" +#include "bits/allocator/aligned_allocator.tcc" diff --git a/external/jsl/include/jsl/bits/allocator/aligned_allocator.tcc b/external/jsl/include/jsl/bits/allocator/aligned_allocator.tcc new file mode 100644 index 00000000..d42e6585 --- /dev/null +++ b/external/jsl/include/jsl/bits/allocator/aligned_allocator.tcc @@ -0,0 +1,41 @@ +#include "../../allocator" +#include +#if defined(_WIN32) +# include +#else +# include +#endif + +namespace jsl { + +template +void *aligned_allocator_traits::allocate(std::size_t n) +{ + static_assert(Al % sizeof(void *) == 0, + "alignment must be a multiple of the pointer size"); + static_assert((Al & (~Al + 1)) == Al, + "alignment must be a power of two"); +#if defined(_WIN32) + void *p = ::_aligned_malloc(n, Al); + if (!p) + throw std::bad_alloc(); + return p; +#else + void *p; + if (::posix_memalign(&p, Al, n) != 0) + throw std::bad_alloc(); + return p; +#endif +} + +template +void aligned_allocator_traits::deallocate(void *p, std::size_t) +{ +#if defined(_WIN32) + ::_aligned_free(p); +#else + ::free(p); +#endif +} + +} // namespace jsl diff --git a/external/jsl/include/jsl/bits/allocator/ordinary_allocator.tcc b/external/jsl/include/jsl/bits/allocator/ordinary_allocator.tcc new file mode 100644 index 00000000..cfb54b03 --- /dev/null +++ b/external/jsl/include/jsl/bits/allocator/ordinary_allocator.tcc @@ -0,0 +1,53 @@ +#include "../../allocator" +#include + +namespace jsl { + +template +inline T *ordinary_allocator::address(T &x) const noexcept +{ + return &x; +} + +template +inline const T *ordinary_allocator::address(const T &x) const noexcept +{ + return &x; +} + +template +T *ordinary_allocator::allocate(std::size_t n, const void *) +{ + T *ptr = (T *)Traits::allocate(n * sizeof(T)); + if (!ptr) + throw std::bad_alloc(); + return ptr; +} + +template +void ordinary_allocator::deallocate(T *p, std::size_t n) noexcept +{ + Traits::deallocate(p, n * sizeof(T)); +} + +template +std::size_t ordinary_allocator::max_size() const noexcept +{ + return std::numeric_limits::max() / sizeof(T); +} + +template +template +void ordinary_allocator::construct(U *p, Args &&...args) +{ + ::new((void *)p) U(std::forward(args)...); +} + +template +template +void ordinary_allocator::destroy(U *p) +{ + p->~U(); +} + +} // namespace jsl diff --git a/external/jsl/include/jsl/bits/allocator/stdc_allocator.tcc b/external/jsl/include/jsl/bits/allocator/stdc_allocator.tcc new file mode 100644 index 00000000..960ea5ad --- /dev/null +++ b/external/jsl/include/jsl/bits/allocator/stdc_allocator.tcc @@ -0,0 +1,16 @@ +#include "../../allocator" +#include + +namespace jsl { + +inline void *stdc_allocator_traits::allocate(std::size_t n) +{ + return ::malloc(n); +} + +inline void stdc_allocator_traits::deallocate(void *p, std::size_t) +{ + ::free(p); +} + +} // namespace jsl diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7e04487e..2f65ea3c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -216,7 +216,7 @@ target_sources(sfizz_static PRIVATE target_include_directories (sfizz_static PUBLIC .) target_include_directories (sfizz_static PUBLIC external) target_link_libraries (sfizz_static PUBLIC absl::strings absl::span) -target_link_libraries (sfizz_static PRIVATE sfizz_parser absl::flat_hash_map Threads::Threads sfizz-sndfile sfizz-pugixml sfizz-spline sfizz-tunings sfizz-kissfft sfizz-cpuid sfizz-atomic) +target_link_libraries (sfizz_static PRIVATE sfizz_parser absl::flat_hash_map Threads::Threads sfizz-sndfile sfizz-pugixml sfizz-spline sfizz-tunings sfizz-kissfft sfizz-cpuid sfizz-jsl sfizz-atomic) set_target_properties (sfizz_static PROPERTIES OUTPUT_NAME sfizz PUBLIC_HEADER "sfizz.h;sfizz.hpp") if (WIN32) target_compile_definitions (sfizz_static PRIVATE _USE_MATH_DEFINES) @@ -255,7 +255,7 @@ if (SFIZZ_SHARED) ${SFIZZ_HEADERS} ${SFIZZ_SOURCES} ${FAUST_FILES} sfizz/sfizz_wrapper.cpp sfizz/sfizz.cpp) target_include_directories (sfizz_shared PRIVATE .) target_include_directories (sfizz_shared PRIVATE external) - target_link_libraries (sfizz_shared PRIVATE absl::strings absl::span sfizz_parser absl::flat_hash_map Threads::Threads sfizz-sndfile sfizz-pugixml sfizz-spline sfizz-tunings sfizz-kissfft sfizz-cpuid sfizz-atomic) + target_link_libraries (sfizz_shared PRIVATE absl::strings absl::span sfizz_parser absl::flat_hash_map Threads::Threads sfizz-sndfile sfizz-pugixml sfizz-spline sfizz-tunings sfizz-kissfft sfizz-cpuid sfizz-jsl sfizz-atomic) if (WIN32) target_compile_definitions (sfizz_shared PRIVATE _USE_MATH_DEFINES) endif() diff --git a/src/sfizz/Oversampler.cpp b/src/sfizz/Oversampler.cpp index 8476ff34..4bb1dd4a 100644 --- a/src/sfizz/Oversampler.cpp +++ b/src/sfizz/Oversampler.cpp @@ -9,6 +9,10 @@ #include "AudioSpan.h" #include "AudioReader.h" #include "SIMDConfig.h" +#include + +template +using aligned_vector = std::vector>; constexpr std::array coeffsStage2x { 0.036681502163648017, @@ -70,9 +74,9 @@ void sfz::Oversampler::stream(AudioSpan input, AudioSpan output, s const auto numFrames = input.getNumFrames(); const auto numChannels = input.getNumChannels(); - std::vector upsampler2x; - std::vector upsampler4x; - std::vector upsampler8x; + aligned_vector upsampler2x; + aligned_vector upsampler4x; + aligned_vector upsampler8x; switch(factor) { From d9ba9c879e29778d563ebd91421ba4a2cda57a7a Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Sun, 20 Sep 2020 15:05:43 +0100 Subject: [PATCH 2/4] Align also in the overload --- src/sfizz/Oversampler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sfizz/Oversampler.cpp b/src/sfizz/Oversampler.cpp index 4bb1dd4a..b4f21621 100644 --- a/src/sfizz/Oversampler.cpp +++ b/src/sfizz/Oversampler.cpp @@ -149,9 +149,9 @@ void sfz::Oversampler::stream(AudioReader& input, AudioSpan output, std:: const auto numFrames = static_cast(input.frames()); const auto numChannels = input.channels(); - std::vector upsampler2x; - std::vector upsampler4x; - std::vector upsampler8x; + aligned_vector upsampler2x; + aligned_vector upsampler4x; + aligned_vector upsampler8x; switch(factor) { From d783ba6c8715ebb19124d713bf3223c9f4946691 Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Sun, 20 Sep 2020 15:06:01 +0100 Subject: [PATCH 3/4] Make neon required on ARM platforms --- cmake/SfizzConfig.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/SfizzConfig.cmake b/cmake/SfizzConfig.cmake index 0d1c29b4..15376c7d 100644 --- a/cmake/SfizzConfig.cmake +++ b/cmake/SfizzConfig.cmake @@ -60,6 +60,9 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") add_compile_options(-Werror=return-type) if (SFIZZ_SYSTEM_PROCESSOR MATCHES "^(i.86|x86_64)$") add_compile_options(-msse2) + elseif (SFIZZ_SYSTEM_PROCESSOR MATCHES "^(armv.*)$") + add_compile_options(-mfloat-abi=hard) + add_compile_options(-mfpu=neon) endif() elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") set(CMAKE_CXX_STANDARD 17) From 9415ffe09284dd4b2520614d63cc7dbe966489bb Mon Sep 17 00:00:00 2001 From: Paul Ferrand Date: Sun, 20 Sep 2020 15:19:14 +0100 Subject: [PATCH 4/4] Add clang tidy include flag --- scripts/run_clang_tidy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run_clang_tidy.sh b/scripts/run_clang_tidy.sh index 0f3ff24b..08ceb36c 100755 --- a/scripts/run_clang_tidy.sh +++ b/scripts/run_clang_tidy.sh @@ -30,7 +30,7 @@ clang-tidy \ vst/SfizzVstProcessor.cpp \ vst/SfizzVstEditor.cpp \ vst/SfizzVstState.cpp \ - -- -Iexternal/abseil-cpp -Isrc/external -Isrc/external/pugixml/src \ + -- -Iexternal/abseil-cpp -Iexternal/jsl/include -Isrc/external -Isrc/external/pugixml/src \ -Isrc/sfizz -Isrc -Isrc/external/spline -Isrc/external/cpuid/src \ -Ivst -Ivst/external/VST_SDK/VST3_SDK -Ivst/external/VST_SDK/VST3_SDK/vstgui4 -Ivst/external/ring_buffer \ -Ieditor/src \